/*******************************************************************************************************
*Application:xmlrpc_client.c
*description:A simple string sort XML-RPC client program written in C.
*author:hemmingway
*time:26/05/2012 09:18:09
*compile with: gcc -Wall -c -I/usr/local/include -O2 -o xmlrpc_client.o xmlrpc_client.c
gcc -lxmlrpc_client -lxmlrpc -lxmlrpc_util -lcurl -o xmlrpc_client xmlrpc_client.o
*************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <xmlrpc-c/util.h>
/*xmlrpc_env is defined in xmlrpc-c/util.h*/
#define NAME "XMLRPC string sort C Client"
#define VERSION "0.1"
#define SLEEP(seconds) sleep(seconds);
#define MAXLEN 1000 /*max length of any input line*/
#define MAXLINES 500 /*max #lines to be sorted*/
char *lineptr[MAXLINES];
void die_if_fault_occurred (xmlrpc_env *env)
{
/* Check our error-handling environment for an XML-RPC fault. */
if (env->fault_occurred) {
fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
env->fault_string, env->fault_code);
exit(1);
}
}
/*getline:read a line into s, return length*/
int getline(char s[], int lim)
{
int c = 0 , i;
/*
for(i=0; i < lim-1 && (c=getchar()!=EOF) && c!='\n';++i)
s[i]=c;
*/
i = 0;
while(--lim > 0 && (c=getchar()) != EOF && c != '\n')
s[i++] = c;
if(c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
/*readlines: read input lines*/
int readlines(char *linrptr[], int maxlines)
{
int len,nlines;
char *p,line[MAXLEN];
nlines = 0;
while( (len = getline(line,MAXLEN) ) > 1)
if(nlines >= maxlines || (p = malloc(len*sizeof(char)) )== NULL)
return -1;
else
{
line[len-1] = '\0'; /*delete new line*/
strcpy(p,line);
lineptr[nlines++] = p;
}
return nlines;
}
void writelines(char *lineptr[], int nlines)
{
int i;
for(i= 0; i < nlines; i++)
printf("%s\n",lineptr[i]);
}
int main(int argc, char **argv)
{
xmlrpc_env env;
xmlrpc_value *myArrayP;
xmlrpc_value *resultArrayP;
xmlrpc_value *itemP;
const char * const serverUrl = "http://localhost:8080/RPC2";
const char * const methodName = "string.qsort";
char *line;
int nlines, i;
/* Initialize our error-handling environment. */
xmlrpc_env_init(&env);
/* Start up our XML-RPC client library. */
xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
die_if_fault_occurred(&env);
printf("Making XMLRPC call to server url '%s' method '%s' "
"to sort \'char *lineptr[]\' into increasing order...\n", serverUrl, methodName);
printf("\n\n");
printf(">>>plz input a line to be sort(press <ENTER><ENTER> to done!):\n");
/*
while(getline(line,MAXLEN) <= 0 )
;
printf(">>>input line is:\n%s\n\n",line);
*/
if ( (nlines = readlines(lineptr,MAXLINES) ) < 0 ){
printf("error:...");
return 1;
}
printf(">>>lines:%d\n",nlines);
printf(">>>input line's is:\n");
writelines(lineptr, nlines);
printf("\n\n");
printf(">>>\n");
myArrayP = xmlrpc_array_new(&env);
die_if_fault_occurred(&env);
/*build array*/
for( i= 0; i < nlines; i++)
{
itemP = xmlrpc_string_new(&env, lineptr[i]);
xmlrpc_array_append_item(&env, myArrayP, itemP);
xmlrpc_DECREF(itemP);
}
/*test...*/
printf("test input array size:%d\n\n\n",xmlrpc_array_size(&env,myArrayP)); /*Array size*/
/* Make the remote procedure call */
resultArrayP = xmlrpc_array_new(&env);
die_if_fault_occurred(&env);
resultArrayP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)", (xmlrpc_int32)nlines, myArrayP);
die_if_fault_occurred(&env);
/* print sort string out. */
printf(">>>string after sort.\n");
nlines = xmlrpc_array_size(&env,resultArrayP);
for( i= 0; i < nlines; i++)
{
xmlrpc_array_read_item(&env, resultArrayP, i, &itemP);
xmlrpc_read_string(&env, itemP, &line );
printf("%s\n",line);
xmlrpc_DECREF(itemP);
}
die_if_fault_occurred(&env);
/* Dispose of our result value. */
xmlrpc_DECREF(myArrayP);
xmlrpc_DECREF(resultArrayP);
/* Shutdown our XML-RPC client library. */
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
return 0;
}
/*******************************************************************************************************
*Application:xmlrpc_server.c
*description:A simple string sort XML-RPC client program written in C.
*author:hemmingway
*time:26/05/2012 09:18:09
*compile with: gcc -Wall -c -I/usr/local/include -O2 -o xmlrpc_server.o xmlrpc_server.c
gcc -lxmlrpc_server -lxmlrpc_server_abyss -lxmlrpc -lxmlrpc_util -lcurl -o xmlrpc_server xmlrpc_server.o
*************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h>
#include <xmlrpc-c/util.h>
#define SLEEP(seconds) sleep(seconds);
/*qsort:sort v[left]...v[right] into increasing order*/
void str_qsort(char *v[], int left, int right)
{
int i,last;
void swap(char *v[], int i, int j);
if(left >= right) /*do nothing if array contains fewer than two elements*/
return;
swap(v,left,(left + right)/2); /*move partition elem*/
last = left;
for(i = left + 1; i <= right; i++)
if( strcmp(v[i],v[left]) < 0 )
swap(v, ++last,i);
swap(v,left,last);
str_qsort(v, left,last-1);
str_qsort(v, last+1, right);
return;
}
/*swap: interchange v[i] and v[j]*/
void swap(char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
return ;
}
/*compare_rise: for qsort*/
int compare_rise(const void *a,const void *b)
{
return *(char*)a - *(char*)b;
}
/*sample_qsort:sort string's*/
static xmlrpc_value *
sample_qsort(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
void * const usr_data)
{
xmlrpc_value *arrayP;
xmlrpc_value *retval;
xmlrpc_int32 nlines;
char *line;
xmlrpc_decompose_value(envP, paramArrayP, "(iA)", &nlines, &arrayP);
if (envP->fault_occurred)
retval = NULL;
else
{
size_t size = xmlrpc_array_size(envP, arrayP);
fprintf(stderr,"service get of array size: %d\n", size);
if (envP->fault_occurred)
retval = NULL;
else /*sort string*/
{
retval = xmlrpc_array_new(envP);
unsigned int i;
for (i = 0; i < size && !envP->fault_occurred; ++i)
{
xmlrpc_value * itemP;
itemP = xmlrpc_array_get_item(envP, arrayP, i);
if (!envP->fault_occurred)
{
xmlrpc_read_string(envP, itemP, &line );
fprintf(stderr,"server test output:%s\n",line);
/*here we sort our current string*/
qsort(line, strlen(line), sizeof (char), compare_rise);
/*build sort string to retval*/
itemP = xmlrpc_string_new(envP, line);
xmlrpc_array_append_item(envP, retval, itemP);
} /*end if */
xmlrpc_DECREF(itemP);
}/*end for*/
xmlrpc_DECREF(arrayP);
if (envP->fault_occurred)
retval = NULL;
}/*end second else*/
}/*end firt else*/
/* Return our result. */
return retval;
}
int main(int argc, char **argv)
{
xmlrpc_server_abyss_parms serverparm;
xmlrpc_registry * registryP;
xmlrpc_env env;
xmlrpc_env_init(&env);
registryP = xmlrpc_registry_new(&env);
/*xmlrpc_registry_add_method往伺服器註冊一個新的方法。
所謂方法就是可以提供給用戶端的一個調用方法。
需要輸入方法名,以及方法的實現函數指標。
*/
xmlrpc_registry_add_method(&env, registryP, NULL, "string.qsort", &sample_qsort, NULL);
serverparm.config_file_name = NULL;
serverparm.registryP = registryP;
serverparm.port_number = 8080;
serverparm.log_file_name = "/tmp/xmlrpc_log";
printf("Starting XML-RPC server...\n");
/*xmlrpc_server_abyss啟動服務,這是個迴圈函數*/
xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(registryP));
return 0;
}