/* A simple news-searcher, written in C to demonstrate how to use the xmplrpc-c client library. This program connects to an XMLRPC server that O'Reilly runs on the Internet, gets some information, and displays it on Standard Output. Note that that server is not in any way designed specifically for xmlrpc-c. It simply implements the XMLRPC protocol, and works with any client that implements XMLRPC. The service that the aforementioned server provides is that it gives you a list of news articles that match a certain regular expression. You give that regular expression an argument to this client program. For more details about O'Reilly's excellent Meerkat news service, see: http://www.oreillynet.com/pub/a/rss/2000/11/14/meerkat_xmlrpc.html */ #include #include #include #include #include #include "config.h" /* information about this build environment */ #define NAME "XML-RPC C Meerkat Query Demo" #define VERSION "1.0" #define MEERKAT_URL "http://www.oreillynet.com/meerkat/xml-rpc/server.php" struct cmdline { const char * searchArg; int hours; }; static void parseCommandLine(int const argc, const char ** const argv, struct cmdline * const cmdlineP) { if (argc-1 < 1) { fprintf(stderr, "Need at least one argument: " "A mysql regular expression " "search pattern. Try 'query-meerkat Linux'\n"); exit(1); } else { cmdlineP->searchArg = argv[1]; if (argc-1 < 2) { cmdlineP->hours = 24; } else { cmdlineP->hours = atoi(argv[2]); if (cmdlineP->hours > 49) { fprintf(stderr, "It's not nice to ask for > 49 hours " "at once.\n"); exit(1); } if (argc-1 > 2) { fprintf(stderr, "There are at most 2 arguments: " "search pattern " "and number of hours."); exit(1); } } } } static void die_if_fault_occurred(xmlrpc_env * const env) { /* We're a command-line utility, so we abort if an error occurs. */ if (env->fault_occurred) { fprintf(stderr, "XML-RPC Fault #%d: %s\n", env->fault_code, env->fault_string); exit(1); } } /* Hey! We fit in one function. */ int main(int const argc, const char** const argv) { struct cmdline cmdline; char time_period[16]; xmlrpc_env env; xmlrpc_value *stories, *story; size_t size, i; int first; parseCommandLine(argc, argv, &cmdline); snprintf(time_period, sizeof(time_period), "%dHOUR", cmdline.hours); xmlrpc_env_init(&env); /* Set up our client. */ xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0); die_if_fault_occurred(&env); /* Ask Meerkat to look for matching stories. */ stories = xmlrpc_client_call(&env, MEERKAT_URL, "meerkat.getItems", "({s:s,s:i,s:s})", "search", cmdline.searchArg, "descriptions", (xmlrpc_int32) 76, "time_period", time_period); die_if_fault_occurred(&env); /* Loop over the stories. */ size = xmlrpc_array_size(&env, stories); die_if_fault_occurred(&env); first = 1; for (i = 0; i < size; i++) { const char * title; const char * link; const char * description; /* Extract the useful information from our story. */ story = xmlrpc_array_get_item(&env, stories, i); die_if_fault_occurred(&env); xmlrpc_decompose_value(&env, story, "{s:s,s:s,s:s,*}", "title", &title, "link", &link, "description", &description); die_if_fault_occurred(&env); /* Print a separator line if necessary. */ if (first) first = 0; else printf("\n"); /* Print the story. */ if (strlen(description) > 0) { printf("%s\n%s\n%s\n", title, description, link); } else { printf("%s\n%s\n", title, link); } free((char*)title); free((char*)link); free((char*)description); } /* Shut down our client. */ xmlrpc_DECREF(stories); xmlrpc_env_clean(&env); xmlrpc_client_cleanup(); return 0; }