123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- /* 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 <string.h> */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "xmlrpc_config.h" /* information about this build environment */
- #include "casprintf.h"
- #include "mallocvar.h"
- #include "cmdline_parser.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;
- }
|