1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/* A simple standalone XML-RPC server based on Abyss that contains a
simple one-thread request processing loop.
xmlrpc_sample_add_server.c is a server that does the same thing, but
does it by running a full Abyss daemon in the background, so it has
less control over how the requests are served.
*/
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/abyss.h>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h>
#include "config.h" /* information about this build environment */
#define DEBUG 0
void xr_setupSigHandlers (void);
char *xr_getPeerIpAddr (TSession * const abyssSessionP);
void xr_requestShutdown (xmlrpc_env * const faultP, void * const context,
const char * const comment, void * const callInfo);
xmlrpc_server_shutdown_fn requestShutdown;
/**
* XR_SETUPSIGHANDLERS -- Setup the SIGPIPE handler.
*/
void
xr_setupSigHandlers (void)
{
struct sigaction mysigaction;
sigemptyset (&mysigaction.sa_mask);
mysigaction.sa_flags = 0;
mysigaction.sa_handler = SIG_IGN;
sigaction (SIGPIPE, &mysigaction, NULL);
}
/**
* XR_GETPEERIPADDR -- Get the IP addr of the host on the server channel.
*/
char *
xr_getPeerIpAddr (TSession * const abyssSessionP)
{
struct abyss_unix_chaninfo * channelInfoP;
struct sockaddr_in * sockAddrInP;
static unsigned char *ipAddr, buf[32];
SessionGetChannelInfo (abyssSessionP, (void*)&channelInfoP);
sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr;
ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr;
memset (buf, 0, 32);
sprintf (buf, "%u.%u.%u.%u", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return (buf);
}
/**
* XR_REQUESTSHUTDOWN -- Issue a shutdown request.
*/
void
xr_requestShutdown(xmlrpc_env * const faultP,
void * const context,
const char * const comment,
void * const callInfo) {
/* 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(faultP);
if (DEBUG)
fprintf (stderr, "Termination requested: %s\n", comment);
*terminationRequestedP = 1;
}
/** ************************************************************************ **/
static xmlrpc_value *
test_ping(xmlrpc_env *const envP, xmlrpc_value *const paramArrayP,
void *const serverInfo, void *const channelInfo)
{
static long count = 0;
fprintf (stderr, "count = %ld\n", (long) count++);
return xmlrpc_build_value(envP, "i", 0);
}
int
main(int const argc,
const char ** const argv) {
struct xmlrpc_method_info3 const methodInfo = {
/* .methodName = */ "ping",
/* .methodFunction = */ &test_ping,
};
TServer abyssServer;
xmlrpc_registry * registryP;
xmlrpc_env env;
int terminationRequested; /* A boolean value */
const char * error;
AbyssInit (&error);
xmlrpc_env_init (&env);
registryP = xmlrpc_registry_new (&env);
xmlrpc_registry_add_method3 (&env, registryP, &methodInfo);
xmlrpc_registry_set_shutdown (registryP,
&xr_requestShutdown, &terminationRequested);
ServerCreate (&abyssServer, "XmlRpcServer", 3000, NULL, NULL);
xmlrpc_server_abyss_set_handlers2 (&abyssServer, "/RPC2", registryP);
ServerInit (&abyssServer);
xr_setupSigHandlers ();
terminationRequested = 0;
while (!terminationRequested) {
printf ("Waiting for next RPC...\n");
/* This waits for the next connection, accepts it, reads the
* HTTP POST request, executes the indicated RPC, and closes
* the connection.
*/
ServerRunOnce (&abyssServer);
}
ServerFree (&abyssServer);
AbyssTerm ();
return 0;
}
|