Ejemplo n.º 1
0
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.");
        }
    }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
void abrt_xmlrpc_conn::new_xmlrpc_client(const char* url, bool ssl_verify)
{
    m_pClient = NULL;
    m_pServer_info = NULL;

    xmlrpc_env env;
    xmlrpc_env_init(&env);

    /* This should be done at program startup, once. We do it in main */
    /* xmlrpc_client_setup_global_const(&env); */

    /* URL - bugzilla.redhat.com/show_bug.cgi?id=666893 Unable to make sense of
     * XML-RPC response from server
     *
     * By default, XML data from the network may be no larger than 512K.
     * XMLRPC_XML_SIZE_LIMIT_DEFAULT is #defined to (512*1024) in xmlrpc-c/base.h
     *
     * Users reported trouble with 733402 byte long responses, hope raising the
     * limit to 2*512k is enough
     */
    xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 2 * XMLRPC_XML_SIZE_LIMIT_DEFAULT);

    struct xmlrpc_curl_xportparms curlParms;
    memset(&curlParms, 0, sizeof(curlParms));
    /* curlParms.network_interface = NULL; - done by memset */
    curlParms.no_ssl_verifypeer = !ssl_verify;
    curlParms.no_ssl_verifyhost = !ssl_verify;
#ifdef VERSION
    curlParms.user_agent        = PACKAGE_NAME"/"VERSION;
#else
    curlParms.user_agent        = "abrt";
#endif

    struct xmlrpc_clientparms clientParms;
    memset(&clientParms, 0, sizeof(clientParms));
    clientParms.transport          = "curl";
    clientParms.transportparmsP    = &curlParms;
    clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent);

    xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS,
                        PACKAGE_NAME, VERSION,
                        &clientParms, XMLRPC_CPSIZE(transportparm_size),
                        &m_pClient);
    if (env.fault_occurred)
        throw_xml_fault(&env);

    m_pServer_info = xmlrpc_server_info_new(&env, url);
    if (env.fault_occurred)
    {
        xmlrpc_client_destroy(m_pClient);
        m_pClient = NULL;
        throw_xml_fault(&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;
}
Ejemplo n.º 5
0
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);
            }
        }
    }
}
Ejemplo n.º 6
0
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;
    }
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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();
    }
}
Ejemplo n.º 9
0
/*
 *	Do any per-module initialization that is separate to each
 *	configured instance of the module.  e.g. set up connections
 *	to external databases, read configuration files, set up
 *	dictionary entries, etc.
 *
 *	If configuration information is given in the config section
 *	that must be referenced in later calls, store a handle to it
 *	in *instance otherwise put a null pointer there.
 */
static int xmlrpc_instantiate(CONF_SECTION * conf, void **instance)
{
	rlm_xmlrpc_t *data;
	rlm_xmlrpc_client_t *first_client;
	rlm_xmlrpc_client_t *client;

	xmlrpc_env env;

	struct xmlrpc_clientparms clientParms;
	struct xmlrpc_curl_xportparms curlParms;

	int i, error;
	void (*do_auth) ();

	/*
	 *      Set up a storage area for instance data
	 */
	data = rad_malloc(sizeof(*data));
	if (!data) {
		return -1;
	}
	memset(data, 0, sizeof(*data));

	/*
	 *      If the configuration parameters can't be parsed, then
	 *      fail.
	 */
	if (cf_section_parse(conf, data, module_config) < 0) {
		free(data);
		return -1;
	}

	*instance = data;

#ifdef HAVE_PTHREAD_H
	pthread_mutex_init(&data->client_mutex, NULL);
#endif

	/*
	 * network_interface parameter cannot be omitted because the
	 * XMLRPC_CXPSIZE macro calcs the size from the first parameter
	 * to the last modified.
	 * Unfortunately is this the order. 
	 */
	curlParms.network_interface = data->interface;
	curlParms.no_ssl_verifypeer = data->no_ssl_verify_peer;
	curlParms.no_ssl_verifyhost = data->no_ssl_verify_host;

	clientParms.transport = "curl";
	clientParms.transportparmsP = &curlParms;
	clientParms.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost);

	/*
	 * Choosing method authentication
	 */
	if (strcmp(data->auth_type, "auth_basic") == 0) {
		do_auth = xmlrpc_server_info_allow_auth_basic;
	} else if (strcmp(data->auth_type, "auth_digest") == 0) {
		do_auth = xmlrpc_server_info_allow_auth_digest;
	} else if (strcmp(data->auth_type, "auth_negotiate") == 0) {
		do_auth = xmlrpc_server_info_allow_auth_negotiate;
	} else if (strcmp(data->auth_type, "auth_ntlm") == 0) {
		do_auth = xmlrpc_server_info_allow_auth_ntlm;
	}

	/*
	 * Clients are created into a circular linked list.
	 * Into this cycle we setup clients and server information objects.
	 * Server information contains a method to do html authentication. 
	 */
	for (i = 0; i < data->xmlrpc_num_socks; i++) {
		client = rad_malloc(sizeof(*client));
		if (!client) {
			return -1;
		}
		memset(client, 0, sizeof(*client));

		env = client->env;
		xmlrpc_env_init(&env);

		if (i == 0) {
			data->client = client;
			first_client = client;

			xmlrpc_client_setup_global_const(&env);
		} else {
			data->client->next = client;
			data->client = data->client->next;
		}

		xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, NAME,
				     VERSION, &clientParms,
				     XMLRPC_CPSIZE(transportparm_size), &client->clientP);

		error = check_error_and_free(data);
		if (error != RLM_MODULE_OK)
			return error;

		client->serverInfoP = xmlrpc_server_info_new(&env, data->url);
		error = check_error_and_free(data);
		if (error != RLM_MODULE_OK)
			return error;

		if (strcmp(data->auth_type, "none") != 0) {
			xmlrpc_server_info_set_user(&env, client->serverInfoP,
						    data->user, data->password);
			error = check_error_and_free(data);
			if (error != RLM_MODULE_OK)
				return error;

			do_auth(&env, client->serverInfoP);
			error = check_error_and_free(data);
			if (error != RLM_MODULE_OK)
				return error;

			radlog(L_INFO, "\trlm_xmlrpc: client #%d logged in as %s", i, data->user);
		}

		radlog(L_INFO, "\trlm_xmlrpc: client #%d initialized", i);

	}

	/*
	 * closing the circular linked list. data->client helds a pointer
	 * to the last client used by a thread.
	 */

	data->client->next = first_client;
	data->client = data->client->next;

	return 0;
}
Ejemplo n.º 10
0
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";

    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 */
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
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 */
}