1 /*------------------------------------------------------------------------------
  2 Name:      client.c
  3 
  4 Project:   xmlBlaster.org
  5 
  6 Comment:   Example how to access xmlBlaster with C and XmlRpc
  7            See http://xmlrpc-c.sourceforge.net/
  8            Usually you start first the callbackServer to receive
  9            asynchronous update from xmlBlaster as well (see README)
 10 
 11 Author:    xmlBlaster@marcelruff.info
 12 
 13 Compile:   Read xmlrpc-c/doc/overview.txt
 14            CLIENT_CFLAGS=`xmlrpc-c-config libwww-client --cflags`
 15            CLIENT_LIBS=`xmlrpc-c-config libwww-client --libs`
 16            gcc $CLIENT_CFLAGS -o client client.c $CLIENT_LIBS -Wall
 17 
 18 Invoke:    See usage text below
 19 ------------------------------------------------------------------------------*/
 20 #include <stdio.h>
 21 #include <unistd.h>
 22 #include <string.h>
 23 #include <sys/types.h> // for file-read only
 24 #include <sys/stat.h>  // for file-read only
 25 #include <fcntl.h>     // for file-read only
 26 #include <malloc.h>    // for file-read only
 27 #include <xmlrpc.h>
 28 #include <xmlrpc_client.h>
 29 #define NAME       "XMLRPC xmlBlaster.org C Client"
 30 #define VERSION    "0.79d"
 31 
 32 char *readFile(const char *const fileName);
 33 void usage();
 34 void die_if_fault_occurred (xmlrpc_env *env);
 35 
 36 
 37 int main (int argc, char** argv)
 38 {
 39    xmlrpc_env env;
 40    xmlrpc_value *result;
 41    char sessionId[256], *tmpP;
 42    char key[256], *content, qos[256], *retVal, *loginName, *passwd, loginQos[256], *cbUrl;
 43    char *keyOid = "PIB_REQUEST";
 44    char *serverUrl = NULL; // "http://localhost:8080/"
 45    char *msgFile = NULL, *data = NULL;
 46    char *destination = NULL;
 47    char serverHostName[256];
 48    char tmp[256];
 49    int iarg;
 50 
 51    for (iarg=0; iarg < argc-1; iarg++) {
 52      if (strcmp(argv[iarg], "-xmlrpc.serverUrl") == 0)
 53         serverUrl = argv[++iarg];
 54      else if (strcmp(argv[iarg], "-xmlrpc.cbUrl") == 0) // URL of our here instantiated callback server
 55         cbUrl = argv[++iarg];
 56      else if (strcmp(argv[iarg], "-dest") == 0)
 57         destination = argv[++iarg];
 58      else if (strcmp(argv[iarg], "-msgFile") == 0)
 59         msgFile = argv[++iarg];
 60      else if (strcmp(argv[iarg], "-loginName") == 0)
 61         loginName = argv[++iarg];
 62      else if (strcmp(argv[iarg], "-passwd") == 0)
 63         passwd = argv[++iarg];
 64      else if (strcmp(argv[iarg], "--help") == 0 || strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "-?") == 0) {
 65         usage();
 66         exit(0);
 67      }
 68    }
 69 
 70    if (destination == NULL) // as default, we send messages to ourself (-> our callbackServer)
 71       destination = loginName;
 72 
 73    data = readFile(msgFile); // get the data we want to send
 74 
 75    if (destination == NULL || data == NULL) {
 76       printf("Missing arguments\n");
 77       usage();
 78       exit(0);
 79    }
 80 
 81    if (serverUrl == NULL) {
 82       gethostname(serverHostName, 125);
 83       sprintf(tmp, "http://%.255s:8080/", serverHostName);
 84       serverUrl = tmp;
 85    }
 86 
 87    printf("\n\n-------------------------------------------\n"
 88               "Hello as C XmlRpc client for xmlBlaster ...\n\n");
 89 
 90    /* Start up our XMLRPC client library. */
 91    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
 92    xmlrpc_env_init(&env);
 93 
 94 
 95    /* Login to xmlBlaster XMLRPC server. */
 96    {
 97       printf("Login to %s as user %s ...\n", serverUrl, loginName);
 98       sprintf(loginQos, "<qos><callback type='XMLRPC'>%.100s</callback></qos>", cbUrl);
 99       result = xmlrpc_client_call(&env, serverUrl,
100                                   "authenticate.login", "(ssss)",
101                                   loginName, passwd, loginQos, "");
102       die_if_fault_occurred(&env);
103       
104       /* Parse our result value. */
105       xmlrpc_parse_value(&env, result, "s", &tmpP);
106       die_if_fault_occurred(&env);
107       strncpy(sessionId, tmpP, 255); // remember sessionId, tmpP is empty after xmlrpc_DECREF(result)
108       printf("Login success, got sessionId=%s\n", sessionId);
109       
110       /* Dispose of our result value. */
111       xmlrpc_DECREF(result);
112    }
113 
114    /* Send message to destination. */
115    {
116       printf("publish %s to %s ...\n", keyOid, destination);
117       sprintf(key, "<key oid='%.100s' contentMime='text/xml'/>", keyOid);
118       sprintf(qos, "<qos><destination queryType='EXACT'>%.100s</destination></qos>", destination);
119       content = data;
120       printf("Key=%s Qos=%s\n", key, qos);
121       result = xmlrpc_client_call(&env, serverUrl,
122                                   "xmlBlaster.publish", "(ssss)",
123                                   sessionId, key, content, qos);
124       die_if_fault_occurred(&env);
125 
126       /* Parse our result value. */
127       xmlrpc_parse_value(&env, result, "s", &retVal);
128       die_if_fault_occurred(&env);
129       printf("Publish success, return value is %s\n", retVal);
130 
131       /* Dispose of our result value. */
132       xmlrpc_DECREF(result);
133    }
134 
135    printf("\nWait until callbackServer has received the response!\n");
136    printf("Than hit a key to logout ...\n");
137    getc(stdin);
138 
139    /* Logout from xmlBlaster XMLRPC server. */
140    {
141       printf("Logout from %s as user %s, sessionId=%s ...\n", serverUrl, loginName, sessionId);
142       strcpy(loginQos, "<qos></qos>");
143       result = xmlrpc_client_call(&env, serverUrl, "authenticate.logout", "(s)", sessionId);
144       die_if_fault_occurred(&env);
145       
146       /* Parse our result value. */
147       xmlrpc_parse_value(&env, result, "s", &retVal);
148       die_if_fault_occurred(&env);
149       printf("Logout success, got '%s'\n", retVal);
150       
151       /* Dispose of our result value. */
152       xmlrpc_DECREF(result);
153    }
154 
155    /* Shutdown our XMLRPC client library. */
156    xmlrpc_env_clean(&env);
157    xmlrpc_client_cleanup();
158 
159    free(data);
160 
161    printf("\nSuccessful communicated with xmlBlaster.\n"
162               "-------------------------------------------\n");
163 
164    return 0;
165 }
166 
167 
168 /*
169  * Some default error handling
170  */
171 void die_if_fault_occurred (xmlrpc_env *env)
172 {
173     /* Check our error-handling environment for an XMLRPC fault. */
174     if (env->fault_occurred) {
175         fprintf(stderr, "XMLRPC Fault: %s (%d)\n",
176                 env->fault_string, env->fault_code);
177         usage();
178         exit(1);
179     }
180 }
181 
182 
183 /*
184  * @return data from file, you need to call free() on this pointer!
185  */
186 char *readFile(const char *const fileName)
187 {
188    int n, fd;
189    const int BUFFSIZE=8192;
190    char buf[BUFFSIZE];
191    char *data;
192    struct stat statbuf;
193 
194    if (fileName == NULL)
195       return NULL;
196 
197    // get size of file ...
198    if (stat(fileName, &statbuf)) {
199       fprintf(stderr, "File %s not found\n", fileName);
200       return NULL;
201    }
202 
203    // read file ...
204    data = malloc((statbuf.st_size+1)*sizeof(char));
205    *data = 0;
206    fd = open(fileName, O_RDONLY);
207    if (fd < 0) {
208       fprintf(stderr, "Can't read file %s\n", fileName);
209       return NULL;
210    }
211    while((n=read(fd, buf, BUFFSIZE)) > 0) {
212       buf[n] = NULL;
213       strcat(data, buf);
214    }
215    *(data + statbuf.st_size) = 0;
216    close(fd);
217    return data;
218 }
219 
220 void usage()
221 {
222    fprintf(stderr,
223     "--------------------------------------------------\n"
224     "Usage:\n"
225     "   client -xmlrpc.serverUrl <serverURL> -xmlrpc.cbUrl <myCallbackServerURL> -loginName <loginName> -passwd <Password> -dest <loginName> -msgFile <xmlFile>\n"
226     "Example:\n"
227     "   client -xmlrpc.serverUrl http://anotherHost:8080/ -xmlrpc.cbUrl http://myHost:8080/RPC2 -loginName gesa -passwd secret -dest gesa -msgFile hello.xml\n"
228     "   This sends a message to myself, we have to start the callbackServer first\n"
229     "--------------------------------------------------\n");
230 }


syntax highlighted by Code2HTML, v. 0.9.1