aboutsummaryrefslogtreecommitdiff
path: root/vendor/voclient/libsamp/libxrpc/xrServer.c.bak
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/voclient/libsamp/libxrpc/xrServer.c.bak')
-rw-r--r--vendor/voclient/libsamp/libxrpc/xrServer.c.bak650
1 files changed, 650 insertions, 0 deletions
diff --git a/vendor/voclient/libsamp/libxrpc/xrServer.c.bak b/vendor/voclient/libsamp/libxrpc/xrServer.c.bak
new file mode 100644
index 00000000..c20b5a22
--- /dev/null
+++ b/vendor/voclient/libsamp/libxrpc/xrServer.c.bak
@@ -0,0 +1,650 @@
+/**
+ * XRSERVER.C
+ *
+ * Procedures used to implement an XML-RPC server in an application. To
+ * do this, we keep a local registry of method names and functions and
+ * rely on a default method to invoke the procedure using a common function
+ * prototype.
+ *
+ * Server methods:
+ *
+ * xr_createServer (path, port, logfile)
+ * xr_addServerMethod (name, *method, *userData)
+ * xr_removeServerMethod (name)
+ * xr_setServerParam (param, *value)
+ *
+ * xr_startServerThread () // never returns
+ * xr_shutdownServer ()
+ *
+ *
+ * @brief Procedures used to implement an XML-RPC server.
+ *
+ * @file xrServer.c
+ * @author Mike Fitzpatrick
+ * @date 6/10/09
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/client.h>
+#include <xmlrpc-c/server.h>
+#include <xmlrpc-c/server_abyss.h>
+
+#include "xrpcP.h"
+
+#define DEBUG 0
+
+#define SZ_CALL_RING 256
+
+int res_anum = -1; /* result array num */
+int res_snum = -1; /* result struct num */
+
+
+static Caller cs[SZ_CALL_RING];
+static int cindex = 0;
+
+static pthread_mutex_t svr_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#ifdef DEBUG_PROCS
+static void xr_dbgPrintParams (xmlrpc_server_abyss_parms s);
+static xmlrpc_server_shutdown_fn xr_requestShutdown;
+static void xr_requestShutdown(xmlrpc_env *envP, void *context, char *comment);
+#endif
+
+static void *xr_rpcListener (Server *svr);
+
+
+static xmlrpc_value *xr_defaultMethod (xmlrpc_env *envP, char *host,
+ char *methodName,
+ xmlrpc_value *paramArrayP,
+ void *serverInfo);
+
+static ServerP svr = (Server *) NULL;
+
+
+
+/*************************************************************************
+** CREATESERVER - Create an instance of the RPC server.
+*************************************************************************/
+
+int
+xr_createServer (char *path, int port, char *logfile)
+{
+
+ if (svr) {
+ perror ("createServer: Server already allocated");
+ return (ERR);
+ }
+ if (! (svr = (ServerP) calloc ((size_t) 1, sizeof (Server)))) {
+ perror ("createServer: Cannot allocate server");
+ return (ERR);
+ }
+
+
+ /* Initialize the structure.
+ */
+ strcpy (svr->path, (path ? path : ""));
+ strcpy (svr->logfile, (logfile ? logfile : ""));
+ svr->port = port;
+
+
+ /* Initialize XML-RPC interface.
+ */
+ xmlrpc_env_init (&svr->env);
+ bzero (svr->url, SZ_PATH);
+ sprintf (svr->url, "http://localhost:%d/RPC2", port);
+
+
+ /* Create the service registry and initialize server params.
+ */
+ svr->registry = xmlrpc_registry_new (&svr->env);
+
+
+ /* Set the default shutdown method.
+ xmlrpc_registry_set_shutdown (svr->registry, &xr_requestShutdown,
+ &shutdown);
+ */
+
+
+ /* In the "modern" form of the Abyss API, we supply parameters in memory
+ ** like a normal API. We select the modern form by setting
+ ** config_file_name to NULL:
+ */
+ svr->serverparm.config_file_name = NULL;
+ svr->serverparm.registryP = svr->registry;
+ svr->serverparm.port_number = svr->port;
+ if (svr->logfile[0])
+ svr->serverparm.log_file_name = svr->logfile;
+
+ svr->trace = 0;
+
+
+ return (OK);
+}
+
+
+
+/*************************************************************************
+** ADDSERVERMETHOD - Add a callback method to the RPC server.
+*************************************************************************/
+
+int
+xr_addServerMethod (char *name, void *method, void *userData)
+{
+ char *arg_signature, *ret_signature;
+
+
+ if (DEBUG)
+ fprintf (stderr, "addMethod: '%s'\n", name);
+
+ /* Create a method in the server. We also use this to let the
+ ** user set the default and shutdown methods.
+ */
+ if (strcmp (name, "default") == 0) {
+
+ /* Set the default method.
+ */
+ xmlrpc_registry_set_default_method (&svr->env, svr->registry,
+ (xmlrpc_default_method) &method, NULL);
+
+ } else if (strcmp (name, "shutdown") == 0) {
+ int shutdown;
+
+ xmlrpc_registry_set_shutdown (svr->registry, method, &shutdown);
+
+ } else {
+
+ /* All we really do at this stage is register the method with
+ ** the interface registry. When a method is called, the default
+ ** method is responsible for parsing the arguments and invoking
+ ** the client code using the standard prototype.
+ */
+ MethodP m = calloc (1, sizeof (Method));
+
+ if (svr->method_head == (MethodP) NULL) {
+ /* Initialize the list of methods;
+ */
+ svr->method_head = svr->method_tail = m;
+
+ } else {
+ /* Add the mthod to the tail of the list.
+ */
+ svr->method_tail->next = svr->method_tail = m;
+ }
+
+ /* Save information about the method. We force the argument
+ ** signature to always be an array to simply the process of getting
+ ** the parameters in the method. On return, we use the signature
+ ** provided by the user and rely on the implementation to extract
+ ** the results appropriately.
+ **
+ */
+ arg_signature = ret_signature = "not_currently_used";
+ strcpy (m->name, name);
+ strcpy (m->ret_signature, ret_signature);
+ if (arg_signature[0] != '(') {
+ sprintf (m->arg_signature, "(%s)", arg_signature);
+ } else
+ strcpy (m->arg_signature, arg_signature);
+
+
+ m->methodFunc = method;
+ m->serverInfo = userData;
+
+ svr->num_methods++;
+ }
+
+ return (OK);
+}
+
+
+/*************************************************************************
+** REMOVESERVERMETHOD - Delete a callback method to the RPC server.
+*************************************************************************/
+
+int
+xr_removeServerMethod (char *name)
+{
+ MethodP last = (MethodP) NULL;
+ MethodP m = svr->method_head;
+
+ while (m) {
+ if (strcmp (m->name, name) == 0) {
+ if (last) /* drop method from the list */
+ last->next = m->next;
+ else
+ svr->method_head = m->next;
+
+ free ((void *) m); /* free the struct */
+ if (svr->num_methods > 0)
+ svr->num_methods--;
+
+ return (OK);
+ }
+ last = m;
+ m = m->next;
+ }
+
+ return (ERR);
+}
+
+
+/*************************************************************************
+** SETSERVERPARAM - Set a parameter for the RPC server.
+*************************************************************************/
+
+void
+xr_setServerParam (char *param, void *value)
+{
+ if (strcmp (param, "port") == 0)
+ svr->serverparm.port_number = (xmlrpc_int) value;
+
+ else if (strcmp (param, "logfile") == 0)
+ svr->serverparm.log_file_name = (char *) value;
+
+ else if (strcmp (param, "keepalive_timeout") == 0)
+ svr->serverparm.keepalive_timeout = (unsigned int) value;
+
+ else if (strcmp (param, "keepalive_max_conn") == 0)
+ svr->serverparm.keepalive_max_conn = (unsigned int) value;
+
+ else if (strcmp (param, "timeout") == 0)
+ svr->serverparm.timeout = (unsigned int) value;
+
+ /*
+ else if (strcmp (param, "shutdown") == 0)
+ svr->serverparm.enable_shutdown = (xmlrpc_bool) value;
+ */
+
+ else if (strcmp (param, "trace") == 0)
+ svr->trace = (unsigned int) value;
+}
+
+
+/*************************************************************************
+** STARTSERVERTHREAD -- Start the server. Never returns.
+*************************************************************************/
+
+int
+xr_startServerThread ()
+{
+ /* Create a detatched thread in which to run.
+ */
+ pthread_attr_init (&svr->attr);
+ pthread_attr_setdetachstate (&svr->attr, PTHREAD_CREATE_DETACHED);
+
+
+ if (svr->trace)
+ fprintf (stderr, "Starting server thread on port %d....\n", svr->port);
+
+ /* Start the listener thread, i.e. the XML-RPC "server".
+ */
+ if (pthread_create (&svr->thread, NULL, (void *)xr_rpcListener,
+ (void *) svr)) {
+ perror ("Cannot start listener thread");
+ exit (-1);
+ }
+
+ return (OK);
+}
+
+void
+xr_startServer ()
+{
+ xr_rpcListener (svr);
+}
+
+
+/* ***********************************************************************
+** SHUTDOWNSERVER -- Stop the RPC server.
+*************************************************************************/
+
+int
+xr_shutdownServer ()
+{
+ /* Not yet implemented. */
+ if (! svr) {
+ perror ("destroyServer: Server already allocated");
+ return (ERR);
+ }
+
+ free ((void *) svr); /* free the server struct */
+ svr = (ServerP) NULL;
+
+ return (OK);
+}
+
+
+
+
+/************************************************************************ */
+/* PRIVATE METHODS */
+/************************************************************************ */
+
+
+/* The method to be called in the server.
+*/
+
+static xmlrpc_value *
+xr_defaultMethod (xmlrpc_env *envP, char *host, char *methodName,
+ xmlrpc_value *paramArrayP, void *serverInfo)
+{
+ int status;
+ ServerP svr = (Server *) serverInfo;
+ MethodP m = (Method *) NULL;
+
+ extern int xr_errstat;
+
+
+
+fprintf (stderr, "DEFAULT: method='%s' index= %d\n", methodName, cindex++);
+return xmlrpc_build_value(envP, "i", OK);
+
+ if (DEBUG)
+ fprintf (stderr, "DEFAULT: method='%s' data= 0x%x\n",
+ methodName, (int) serverInfo);
+
+
+ /* Now look for the method in the interface registry.
+ */
+ for (m=svr->method_head; m; m = m->next) {
+
+ if (strcmp (m->name, methodName) == 0) {
+
+ Caller *c = (Caller *) NULL;
+ xmlrpc_value *result = (xmlrpc_value *) NULL;
+
+
+ (void) pthread_mutex_lock (&svr_mutex);
+ c = &cs[(cindex = (cindex + 1) % SZ_CALL_RING)];
+ (void) pthread_mutex_unlock (&svr_mutex);
+
+ /* Free old result values.
+ if (res_anum >= 0) {
+ xr_freeArray (res_anum);
+ res_anum = -1;
+ }
+ if (res_snum >= 0) {
+ xr_freeStruct (res_snum);
+ res_snum = -1;
+ }
+ */
+
+fprintf (stderr, "DEFAULT: c=0x%x method='%s' data=0x%x cindex=%d\n",
+ (int)c,methodName,(int)serverInfo, cindex);
+
+ memset (c, 0, sizeof(Caller));
+ c->env = envP; /* setup the calling parameters */
+ c->host = host;
+ c->name = methodName;
+ c->param = paramArrayP;
+ c->info = serverInfo;
+
+ /* Call the function.
+ */
+ if ( (status = (*(PFI)(*m->methodFunc))((void *)c)) ) {
+ fprintf (stderr, "Matched failed '%s'...\n", m->name);
+ xr_errstat = ERR;
+ } else {
+ xr_errstat = OK;
+
+ xmlrpc_DECREF(paramArrayP);
+ result = c->result;
+ }
+fprintf (stderr, "DONE: c=0x%x method='%s'\n",(int) c, methodName);
+ return ( result ); /* return our result */
+ }
+ }
+
+
+ if (!m) {
+ char msg[256];
+
+ memset (msg, 0, 256);
+ sprintf (msg, "No such method '%s'", methodName);
+ xmlrpc_value *result = xmlrpc_string_new (envP, msg);
+
+ return ( result );
+
+ } else
+ return ((xmlrpc_value *) NULL); /* should never happen */
+}
+
+
+#ifdef GLOBAL_SERVER
+
+/**
+ * Thread process created to run a listener for the methods being
+ * called.
+ */
+static void *
+xr_rpcListener (Server *svr)
+{
+ xmlrpc_server_abyss_parms serverparm;
+
+
+fprintf (stderr, "Starting old rpcListener ....svr = 0x%x \n", (int) svr);
+ /* Initialize the environment and install the default dispatcher method.
+ */
+ xmlrpc_env_init (&svr->env); /* initialize XML-RPC interface */
+
+ svr->registry = xmlrpc_registry_new (&svr->env);
+ xmlrpc_registry_set_default_method (&svr->env,
+ (svr->serverparm.registryP = svr->registry),
+ (xmlrpc_default_method) &xr_defaultMethod, svr);
+
+ serverparm.config_file_name = NULL;
+ serverparm.registryP = svr->serverparm.registryP;
+ serverparm.port_number = svr->serverparm.port_number;
+ serverparm.log_file_name = svr->serverparm.log_file_name;
+ serverparm.keepalive_timeout = 0;
+ serverparm.keepalive_max_conn = 0;
+ /*
+ serverparm.keepalive_timeout = 30;
+ serverparm.keepalive_max_conn = 128;
+ */
+
+
+ /* Never returns .....
+ */
+ xmlrpc_server_abyss (&svr->env, &serverparm, XMLRPC_APSIZE(log_file_name));
+
+
+ /* Should never get here.
+ */
+ if (svr->env.fault_occurred) {
+ fprintf (stderr, "xmlrpc_server_abyss terminates.....\n");
+ exit (1);
+ } else
+ return ((void *) OK);
+}
+
+#else
+
+
+/*****************************************************************************
+ * For XMLRPC-C v1.14 or newer
+ ****************************************************************************/
+
+#define NEW_ABYSS 1
+
+#ifdef NEW_ABYSS
+
+static xmlrpc_server_abyss_t *serverToTerminateP;
+
+static void xr_dieIfFailed (char *description, xmlrpc_env env);
+static void xr_svrSigtermHandler (int signalClass);
+static void xr_setupSigtermHandler (xmlrpc_server_abyss_t *serverP);
+static void xr_restoreSigtermHandler (void);
+
+
+/**
+ *
+ */
+static void
+xr_dieIfFailed (char *description, xmlrpc_env env)
+{
+ if (env.fault_occurred) {
+ fprintf (stderr, "%s failed. %s\n", description, env.fault_string);
+ exit (1);
+ }
+}
+
+
+/**
+ *
+ */
+static void
+xr_svrSigtermHandler (int signalClass)
+{
+ xmlrpc_env env;
+
+ xmlrpc_env_init (&env);
+ xmlrpc_server_abyss_terminate (&env, serverToTerminateP);
+ xr_dieIfFailed ("xmlrpc_server_abyss_terminate", env);
+
+ xmlrpc_env_clean (&env);
+}
+
+static void
+xr_setupSigtermHandler (xmlrpc_server_abyss_t *serverP)
+{
+ struct sigaction mysigaction;
+
+ serverToTerminateP = serverP;
+
+ sigemptyset (&mysigaction.sa_mask);
+ mysigaction.sa_flags = 0;
+ mysigaction.sa_handler = xr_svrSigtermHandler;
+ sigaction (SIGTERM, &mysigaction, NULL);
+}
+
+
+static void
+xr_restoreSigtermHandler (void)
+{
+ struct sigaction mysigaction;
+
+ sigemptyset (&mysigaction.sa_mask);
+ mysigaction.sa_flags = 0;
+ mysigaction.sa_handler = SIG_DFL;
+ sigaction (SIGTERM, &mysigaction, NULL);
+}
+
+
+/**
+ * Thread process created to run a listener for the methods being
+ * called.
+ */
+static void *
+xr_rpcListener (Server *svr)
+{
+ xmlrpc_server_abyss_parms serverparm;
+ xmlrpc_server_abyss_t *serverP;
+ xmlrpc_server_abyss_sig *oldHandlersP;
+
+
+fprintf (stderr, "Starting new rpcListener ....svr = 0x%x \n", (int) svr);
+ xmlrpc_env_init (&svr->env);
+
+ xmlrpc_server_abyss_global_init (&svr->env);
+ xr_dieIfFailed ("xmlrpc_server_abyss_global_init", svr->env);
+
+ svr->registry = xmlrpc_registry_new (&svr->env);
+ xr_dieIfFailed ("xmlrpc_registry_new", svr->env);
+
+ xmlrpc_registry_set_default_method (&svr->env,
+ (svr->serverparm.registryP = svr->registry),
+ (xmlrpc_default_method) &xr_defaultMethod, svr);
+
+ serverparm.config_file_name = NULL;
+ serverparm.registryP = svr->serverparm.registryP;
+ serverparm.port_number = svr->serverparm.port_number;
+ serverparm.log_file_name = svr->serverparm.log_file_name;
+/*
+ serverparm.keepalive_timeout = 15;
+ serverparm.keepalive_max_conn = 4;
+*/
+ serverparm.keepalive_timeout = 0;
+ serverparm.keepalive_max_conn = 0;
+
+
+ xmlrpc_server_abyss_create (&svr->env,
+ &serverparm,
+ XMLRPC_APSIZE(keepalive_max_conn),
+ &serverP);
+ xr_dieIfFailed ("xmlrpc_server_abyss_create", svr->env);
+
+ xmlrpc_server_abyss_setup_sig (&svr->env, serverP, &oldHandlersP);
+ xr_dieIfFailed ("xmlrpc_server_abyss_setup_sig", svr->env);
+
+ xr_setupSigtermHandler (serverP);
+
+ /* Launch the server.
+ */
+ xmlrpc_server_abyss_run_server (&svr->env, serverP);
+ xr_dieIfFailed ("xmlrpc_server_abyss_run_server", svr->env);
+
+
+ /* We should never get here ....
+ */
+ fprintf (stderr, "Server has terminated\n");
+
+ xr_restoreSigtermHandler ();
+ xmlrpc_server_abyss_restore_sig (oldHandlersP);
+ xmlrpc_server_abyss_destroy (serverP);
+ xmlrpc_registry_free (svr->registry);
+ xmlrpc_server_abyss_global_term ();
+ xmlrpc_env_clean (&svr->env);
+
+ return ((void *) ERR);;
+}
+
+#endif /* NEW_ABYSS */
+
+#endif /* GLOBAL_SERVER */
+
+
+
+
+
+#ifdef DEBUG_PROCS
+
+static void
+xr_requestShutdown(xmlrpc_env * const envP,
+ void * const context,
+ const char * const comment)
+{
+ /* You make this run by executing the system method
+ ** 'system.shutdown'. This function is registered in the method
+ ** registry as the thing to call for that.
+ */
+ int * const terminationRequestedP = context;
+
+ xmlrpc_env_init (envP);
+
+ fprintf (stderr, "Termination requested: %s\n", comment);
+
+ *terminationRequestedP = 1;
+}
+
+
+static void
+xr_dbgPrintParams ( xmlrpc_server_abyss_parms s )
+{
+ fprintf (stderr, "Server Params:\n");
+ fprintf (stderr, "\tport = %d\n", s.port_number);
+ fprintf (stderr, "\tlogfile = %s\n", s.log_file_name);
+ fprintf (stderr, "\tkeepalive_timeout = %d\n", s.keepalive_timeout);
+ fprintf (stderr, "\tkeepalive_max_conn = %d\n", s.keepalive_max_conn);
+ fprintf (stderr, "\ttimeout = %d\n", s.timeout);
+}
+
+#endif