|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN |
|
|
|
|
|
#include <cassert> |
|
|
#include <stdexcept> |
|
|
#include <iostream> |
|
|
#include <unistd.h> |
|
|
#include <stdio.h> |
|
|
#ifndef _WIN32 |
|
|
#include <sys/socket.h> |
|
|
#include <netinet/in.h> |
|
|
#endif |
|
|
|
|
|
using namespace std; |
|
|
|
|
|
#include <xmlrpc-c/base.hpp> |
|
|
#include <xmlrpc-c/registry.hpp> |
|
|
#include <xmlrpc-c/server_abyss.hpp> |
|
|
#include <xmlrpc-c/abyss.h> |
|
|
|
|
|
|
|
|
struct tcpPortAddr { |
|
|
unsigned char ipAddr[4]; |
|
|
unsigned short portNumber; |
|
|
}; |
|
|
|
|
|
|
|
|
static struct tcpPortAddr |
|
|
tcpAddrFromSockAddr(struct sockaddr const sockAddr) { |
|
|
|
|
|
const struct sockaddr_in * const sockAddrInP( |
|
|
static_cast<struct sockaddr_in *>((void *)&sockAddr)); |
|
|
|
|
|
const unsigned char * const ipAddr( |
|
|
static_cast<const unsigned char *>( |
|
|
(const void *)&sockAddrInP->sin_addr.s_addr) |
|
|
); |
|
|
|
|
|
assert(sockAddrInP->sin_family == AF_INET); |
|
|
|
|
|
struct tcpPortAddr retval; |
|
|
|
|
|
retval.ipAddr[0] = ipAddr[0]; |
|
|
retval.ipAddr[1] = ipAddr[1]; |
|
|
retval.ipAddr[2] = ipAddr[2]; |
|
|
retval.ipAddr[3] = ipAddr[3]; |
|
|
retval.portNumber = ntohs(sockAddrInP->sin_port); |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
#define CHANINFO_TYPE abyss_win_chaninfo |
|
|
#else |
|
|
#define CHANINFO_TYPE abyss_unix_chaninfo |
|
|
#endif |
|
|
|
|
|
static string |
|
|
rpcIpAddrMsg(xmlrpc_c::callInfo_serverAbyss const& callInfo) { |
|
|
|
|
|
void * chanInfoPtr; |
|
|
SessionGetChannelInfo(callInfo.abyssSessionP, &chanInfoPtr); |
|
|
|
|
|
struct CHANINFO_TYPE * const chanInfoP( |
|
|
static_cast<struct CHANINFO_TYPE *>(chanInfoPtr)); |
|
|
|
|
|
struct tcpPortAddr const tcpAddr(tcpAddrFromSockAddr(chanInfoP->peerAddr)); |
|
|
|
|
|
char msg[128]; |
|
|
|
|
|
sprintf(msg, "RPC is from IP address %u.%u.%u.%u, Port %hu", |
|
|
tcpAddr.ipAddr[0], |
|
|
tcpAddr.ipAddr[1], |
|
|
tcpAddr.ipAddr[2], |
|
|
tcpAddr.ipAddr[3], |
|
|
tcpAddr.portNumber); |
|
|
|
|
|
return string(msg); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class getCallInfoMethod : public xmlrpc_c::method2 { |
|
|
public: |
|
|
void |
|
|
execute(xmlrpc_c::paramList const& paramList, |
|
|
const xmlrpc_c::callInfo * const callInfoPtr, |
|
|
xmlrpc_c::value * const retvalP) { |
|
|
|
|
|
const xmlrpc_c::callInfo_serverAbyss * const callInfoP( |
|
|
dynamic_cast<const xmlrpc_c::callInfo_serverAbyss *>(callInfoPtr)); |
|
|
|
|
|
paramList.verifyEnd(0); |
|
|
|
|
|
|
|
|
assert(callInfoP != NULL); |
|
|
|
|
|
*retvalP = xmlrpc_c::value_string(rpcIpAddrMsg(*callInfoP)); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
main(int const, |
|
|
const char ** const) { |
|
|
|
|
|
try { |
|
|
xmlrpc_c::registry myRegistry; |
|
|
|
|
|
xmlrpc_c::methodPtr const getCallInfoMethodP(new getCallInfoMethod); |
|
|
|
|
|
myRegistry.addMethod("getCallInfo", getCallInfoMethodP); |
|
|
|
|
|
xmlrpc_c::serverAbyss myAbyssServer(xmlrpc_c::serverAbyss::constrOpt() |
|
|
.registryP(&myRegistry) |
|
|
.portNumber(8080) |
|
|
); |
|
|
|
|
|
myAbyssServer.run(); |
|
|
|
|
|
assert(false); |
|
|
} catch (exception const& e) { |
|
|
cerr << "Something failed. " << e.what() << endl; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|