コード例 #1
0
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;
}
コード例 #2
0
ファイル: method.c プロジェクト: jasonbourneh0810/FreeSWITCH
void
xmlrpc_methodCreate(xmlrpc_env *           const envP,
                    xmlrpc_method1               methodFnType1,
                    xmlrpc_method2               methodFnType2,
                    void *                 const userData,
                    const char *           const signatureString,
                    const char *           const helpText,
                    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       = strdup(helpText);

        makeSignatureList(envP, signatureString, &methodP->signatureListP);

        if (envP->fault_occurred)
            free(methodP);

        *methodPP = methodP;
    }
}
コード例 #3
0
static void
parseBase64(xmlrpc_env *    const envP,
            const char *    const str,
            size_t          const strLength,
            xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Parse the content of a <base64> 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);
    }
コード例 #4
0
ファイル: xmlrpc_authcookie.c プロジェクト: arssivka/naomech
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);
    }
コード例 #5
0
ファイル: xmlrpc_client.c プロジェクト: hoyin29/XML_RPC
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);
}
コード例 #6
0
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->_block);

        assert((size_t)(int)size == size);
            /* Because structs are defined to have few enough members */

        retval = (int)size;
    }
    return retval;
}
コード例 #7
0
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;
}
コード例 #8
0
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);
    }
}
コード例 #9
0
void 
xmlrpc_registry_add_method_w_doc(xmlrpc_env *env,
                                 xmlrpc_registry *registry,
                                 const char *host,
                                 const char *method_name,
                                 xmlrpc_method method,
                                 void *user_data,
                                 const char *signature,
                                 const char *help) {
    xmlrpc_value *method_info;

    XMLRPC_ASSERT_ENV_OK(env);
    XMLRPC_ASSERT_PTR_OK(registry);
    XMLRPC_ASSERT(host == NULL);
    XMLRPC_ASSERT_PTR_OK(method_name);
    XMLRPC_ASSERT_PTR_OK(method);

    /* Error-handling preconditions. */
    method_info = NULL;

    /* Store our method and user data into our hash table. */
    method_info = xmlrpc_build_value(env, "(ppss)", (void*) method, user_data,
                                     signature, help);
    XMLRPC_FAIL_IF_FAULT(env);
    xmlrpc_struct_set_value(env, registry->_methods, method_name, method_info);
    XMLRPC_FAIL_IF_FAULT(env);

 cleanup:
    if (method_info)
    xmlrpc_DECREF(method_info);

}
コード例 #10
0
void 
xmlrpc_registry_set_preinvoke_method(xmlrpc_env *env,
                                     xmlrpc_registry *registry,
                                     xmlrpc_preinvoke_method handler,
                                     void *user_data) {
    xmlrpc_value *method_info;

    XMLRPC_ASSERT_ENV_OK(env);
    XMLRPC_ASSERT_PTR_OK(registry);
    XMLRPC_ASSERT_PTR_OK(handler);

    /* Error-handling preconditions. */
    method_info = NULL;

    /* Store our method and user data into our hash table. */
    method_info = xmlrpc_build_value(env, "(pp)", (void*) handler, user_data);
    XMLRPC_FAIL_IF_FAULT(env);

    /* Dispose of any pre-existing preinvoke method and install ours. */
    if (registry->_preinvoke_method)
        xmlrpc_DECREF(registry->_preinvoke_method);
    registry->_preinvoke_method = method_info;

 cleanup:
    if (env->fault_occurred) {
        if (method_info)
            xmlrpc_DECREF(method_info);
    }
}
コード例 #11
0
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) {
/*----------------------------------------------------------------------------
  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.
-----------------------------------------------------------------------------*/
    xml_element * response;

    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",
            xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), xmlDataLen);
    else {
        xmlrpc_env env;
        xmlrpc_env_init(&env);

        xml_parse(&env, xmlData, xmlDataLen, &response);

        if (env.fault_occurred)
            setParseFault(envP, "Not valid XML.  %s", env.fault_string);
        else {
            /* Pick apart and verify our structure. */
            if (xmlrpc_streq(xml_element_name(response), "methodResponse")) {
                parseMethodResponseElt(envP, response,
                                       resultPP, faultCodeP, faultStringP);
            } else
                setParseFault(envP, "XML-RPC response must consist of a "
                              "<methodResponse> element.  "
                              "This has a <%s> instead.",
                              xml_element_name(response));
            
            xml_element_free(response);
        }
        xmlrpc_env_clean(&env);
    }
}
コード例 #12
0
ファイル: xmlrpc_authcookie.c プロジェクト: AlexeyS/cmake
/* set cookie function */
void xmlrpc_authcookie_set ( xmlrpc_env *env, 
                        const char *username, 
                        const char *password ) {
    char *unencoded;
    xmlrpc_mem_block *token;
    static char env_buffer[1024];
    const char* block;

    /* Check asserts. */
    XMLRPC_ASSERT_ENV_OK(env);
    XMLRPC_ASSERT_PTR_OK(username);
    XMLRPC_ASSERT_PTR_OK(password);

    /* Clear out memory. */
    unencoded = (char *) malloc ( sizeof ( char * ) );

    /* Create unencoded string/hash. */
    sprintf(unencoded, "%s:%s", username, password);

    /* Create encoded string. */
    token = xmlrpc_base64_encode_without_newlines(env, (unsigned char*)unencoded,
                                strlen(unencoded));
    XMLRPC_FAIL_IF_FAULT(env);

    /* Set HTTP_COOKIE_AUTH to the character representation of the
    ** encoded string. */
    block = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, token);
    sprintf(env_buffer, "HTTP_COOKIE_AUTH=%s", block);
    putenv(env_buffer);

 cleanup:
    if (token) xmlrpc_mem_block_free(token);
}
コード例 #13
0
static void 
format_out(xmlrpc_env *env,
           xmlrpc_mem_block *output,
           char *format_string,
           ...) {

    va_list args;
    char buffer[SMALL_BUFFER_SZ];
    int count;

    XMLRPC_ASSERT_ENV_OK(env);

    va_start(args, format_string);

    /* We assume that this function is present and works correctly. Right. */
    count = vsnprintf(buffer, SMALL_BUFFER_SZ, format_string, args);

    /* Old C libraries return -1 if vsnprintf overflows its buffer.
    ** New C libraries return the number of characters which *would* have
    ** been printed if the error did not occur. This is impressively vile.
    ** Thank the C99 committee for this bright idea. But wait! We also
    ** need to keep track of the trailing NULL. */
    if (count < 0 || count >= (SMALL_BUFFER_SZ - 1))
    XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
                "format_out overflowed internal buffer");

    /* Append our new data to our output. */
    XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, buffer, count);
    XMLRPC_FAIL_IF_FAULT(env);

cleanup:
    va_end(args);
}
コード例 #14
0
static xmlrpc_value *
convert_params(xmlrpc_env *        const envP,
               const xml_element * const elemP) {
/*----------------------------------------------------------------------------
   Convert an XML element representing a list of parameters (i.e.  a
   <params> element) to an xmlrpc_value of type array.  Note that an
   array is normally represented in XML by a <value> element.  We use
   type xmlrpc_value to represent the parameter list just for convenience.
-----------------------------------------------------------------------------*/
    xmlrpc_value *array, *item;
    int size, i;
    xml_element **params, *param, *value;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(elemP != NULL);

    /* Set up our error-handling preconditions. */
    array = item = NULL;

    /* Allocate an array to hold our parameters. */
    array = xmlrpc_build_value(envP, "()");
    XMLRPC_FAIL_IF_FAULT(envP);

    /* We're responsible for checking our own element name. */
    CHECK_NAME(envP, elemP, "params");    

    /* Iterate over our children. */
    size = xml_element_children_size(elemP);
    params = xml_element_children(elemP);
    for (i = 0; i < size; ++i) {
        unsigned int const maxNest = xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);

        param = params[i];
        CHECK_NAME(envP, param, "param");
        CHECK_CHILD_COUNT(envP, param, 1);

        value = xml_element_children(param)[0];

        CHECK_NAME(envP, value, "value");

        xmlrpc_parseValue(envP, maxNest, value, &item);
        XMLRPC_FAIL_IF_FAULT(envP);

        xmlrpc_array_append_item(envP, array, item);
        xmlrpc_DECREF(item);
        item = NULL;
        XMLRPC_FAIL_IF_FAULT(envP);
    }

 cleanup:
    if (envP->fault_occurred) {
        if (array)
            xmlrpc_DECREF(array);
        if (item)
            xmlrpc_DECREF(item);
        return NULL;
    }
    return array;
}
コード例 #15
0
ファイル: xmlrpc_libxml2.c プロジェクト: mirror/xmlrpc-c
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;
}
コード例 #16
0
static void
parseInt(xmlrpc_env *    const envP,
         const char *    const str,
         xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Parse the content of a <int> 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, "<int> XML element content is empty");
    else if (isspace(str[0]))
        setParseFault(envP, "<int> 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, "<int> 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 <int> 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,
                              "<int> 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,
                              "<int> value %ld is above the range allowed "
                              "by XML-RPC (maximum is %d)",
                              i, XMLRPC_INT32_MAX);
            else {
                if (tail[0] != '\0')
                    setParseFault(envP,
                                  "<int> value '%s' contains non-numerical "
                                  "junk: '%s'", str, tail);
                else
                    *valuePP = xmlrpc_int_new(envP, i);
            }
        }
    }
}
コード例 #17
0
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", &paramArrayP);
        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);
        }
    }
}
コード例 #18
0
ファイル: xmlrpc_libxml2.c プロジェクト: mirror/xmlrpc-c
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);
}
コード例 #19
0
ファイル: xmlrpc_client.c プロジェクト: hoyin29/XML_RPC
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);
            }
        }
    }
}
コード例 #20
0
ファイル: xmlrpc_libxml2.c プロジェクト: mirror/xmlrpc-c
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();
}
コード例 #21
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);

    ++globallyInitialized;
}
コード例 #22
0
static void
parseStruct(xmlrpc_env *    const envP,
            unsigned int    const maxRecursion,
            xml_element *   const elemP,
            xmlrpc_value ** const structPP) {
/*----------------------------------------------------------------------------
   Parse the <struct> 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 <member> "
                              "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;
    }
}
コード例 #23
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
void
xmlrpc_parse_value_xml(xmlrpc_env *    const envP,
                       const char *    const xmlData,
                       size_t          const xmlDataLen,
                       xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Compute the xmlrpc_value represented by the XML document 'xmlData' (of
   length 'xmlDataLen' characters), which must consist of a single <value>
   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 <value> 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, &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 <value> element.  This has a <%s> instead.",
                          xml_element_name(valueEltP));
        xml_element_free(valueEltP);
    }
    xmlrpc_env_clean(&env);
}
コード例 #24
0
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->_block) + originalSize, data, len);
    }
}
コード例 #25
0
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;
}
コード例 #26
0
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);
        }
コード例 #27
0
xmlrpc_registry *
xmlrpc_registry_new(xmlrpc_env *env) {

    xmlrpc_value *methods;
    xmlrpc_registry *registry;
    int registry_valid;
    
    XMLRPC_ASSERT_ENV_OK(env);
    
    /* Error-handling preconditions. */
    methods = NULL;
    registry = NULL;
    registry_valid = 0;

    /* Allocate our memory. */
    methods = xmlrpc_struct_new(env);
    XMLRPC_FAIL_IF_FAULT(env);
    registry = (xmlrpc_registry*) malloc(sizeof(xmlrpc_registry));
    XMLRPC_FAIL_IF_NULL(registry, env, XMLRPC_INTERNAL_ERROR,
                        "Could not allocate memory for registry");
    
    /* Set everything up. */
    registry->_introspection_enabled = 1;
    registry->_methods = methods;
    registry->_default_method = NULL;
    registry->_preinvoke_method = NULL;
    registry_valid = 1;

    /* Install our system methods. */
    install_system_methods(env, registry);
    XMLRPC_FAIL_IF_FAULT(env);

 cleanup:
    if (env->fault_occurred) {
        if (registry_valid) {
            xmlrpc_registry_free(registry);
        } else {
            if (methods)
                xmlrpc_DECREF(methods);
            if (registry)
                free(registry);
        }
        return NULL;
    }
    return registry;
}
コード例 #28
0
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;

        XMLRPC_MEMBLOCK_INIT(_struct_member, envP, &valP->_block, 0);

        if (envP->fault_occurred)
            free(valP);
    }
    return valP;
}
コード例 #29
0
ファイル: xmlrpc_client.c プロジェクト: hoyin29/XML_RPC
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);
}
コード例 #30
0
ファイル: xmlrpc_client.c プロジェクト: hoyin29/XML_RPC
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;
}