Component::Ptr component;
Component *(*pCreateComponent)();
- Log("Loading component '%s'", path.c_str());
+ Log("Loading component '" + path + "'");
#ifdef _WIN32
HMODULE hModule = LoadLibrary(path.c_str());
{
string name = component->GetName();
- Log("Unloading component '%s'", name.c_str());
+ Log("Unloading component '" + name + "'");
map<string, Component::Ptr>::iterator i = m_Components.find(name);
if (i != m_Components.end())
m_Components.erase(i);
*
* Logs a message.
*
- * @param format The format string.
- * @param ... Additional parameters for the format string.
+ * @param message The message.
*/
-void Application::Log(const char *format, ...)
+void Application::Log(string message)
{
- char message[512];
- va_list marker;
+ char timestamp[100];
- va_start(marker, format);
- vsnprintf(message, sizeof(message), format, marker);
- va_end(marker);
+ time_t now;
+ time(&now);
+ tm tmnow = *localtime(&now);
- // TODO: log to file
- fprintf(stderr, "%s\n", message);
+ strftime(timestamp, sizeof(timestamp), "%a %B %d %Y %H:%M:%S", &tmnow);
+
+ cout << "[" << timestamp << "]: " << message << endl;
}
/**
try {
result = Application::Instance->Main(args);
} catch (const Exception& ex) {
- cerr << "---" << endl;
- cerr << "Exception: " << Utility::GetTypeName(ex) << endl;
- cerr << "Message: " << ex.GetMessage() << endl;
+ Application::Log("---");
+ Application::Log("Exception: " + Utility::GetTypeName(ex));
+ Application::Log("Message: " + ex.GetMessage());
return EXIT_FAILURE;
}
void Shutdown(void);
- static void Log(const char *format, ...);
+ static void Log(string message);
ConfigHive::Ptr GetConfigHive(void) const;
# include "config.h"
#endif /* _MSC_VER */
+#define PLATFORM_WINDOWS 1
+#define PLATFORM_UNIX 2
+
+#ifdef _WIN32
+# define I2_PLATFORM PLATFORM_WINDOWS
+# include "win32.h"
+#else
+# define I2_PLATFORM PLATFORM_UNIX
+# include "unix.h"
+#endif
+
#include <cstdlib>
#include <cstdarg>
#include <cstdio>
#include <memory>
#include <string>
+#include <sstream>
#include <vector>
#include <set>
#include <iostream>
# include "cxx11-compat.h"
#endif
-#define PLATFORM_WINDOWS 1
-#define PLATFORM_UNIX 2
-
-#ifdef _WIN32
-# define I2_PLATFORM PLATFORM_WINDOWS
-# include "win32.h"
-#else
-# define I2_PLATFORM PLATFORM_UNIX
-# include "unix.h"
-#endif
-
#ifdef I2_BASE_BUILD
# define I2_BASE_API I2_EXPORT
#else /* I2_BASE_BUILD */
if (::bind(GetFD(), (sockaddr *)&sin, sizeof(sin)) < 0)
HandleSocketError();
}
+
+string TCPSocket::GetAddressFromSockaddr(sockaddr *address)
+{
+ static char Buffer[256];
+
+#ifdef _WIN32
+ DWORD BufferLength = sizeof(Buffer);
+
+ socklen_t len;
+ if (address->sa_family == AF_INET)
+ len = sizeof(sockaddr_in);
+ else if (address->sa_family == AF_INET6)
+ len = sizeof(sockaddr_in6);
+ else {
+ assert(0);
+
+ return "";
+ }
+
+ if (WSAAddressToString(address, len, NULL, Buffer, &BufferLength) != 0) {
+ return NULL;
+ }
+#else /* _WIN32 */
+ void *IpAddress;
+
+ if (Address->sa_family == AF_INET) {
+ IpAddress = &(((sockaddr_in *)Address)->sin_addr);
+ } else {
+ IpAddress = &(((sockaddr_in6 *)Address)->sin6_addr);
+ }
+
+ if (inet_ntop(Address->sa_family, IpAddress, Buffer, sizeof(Buffer)) == NULL) {
+ return NULL;
+ }
+#endif /* _WIN32 */
+
+ return Buffer;
+}
+
+unsigned short TCPSocket::GetPortFromSockaddr(sockaddr *address)
+{
+ if (address->sa_family == AF_INET)
+ return htons(((sockaddr_in *)address)->sin_port);
+ else if (address->sa_family == AF_INET6)
+ return htons(((sockaddr_in6 *)address)->sin6_port);
+ else {
+ assert(0);
+
+ return 0;
+ }
+}
+
+void TCPSocket::GetClientSockaddr(sockaddr_storage *address)
+{
+ socklen_t len = sizeof(*address);
+
+ if (getsockname(GetFD(), (sockaddr *)address, &len) < 0)
+ HandleSocketError();
+}
+
+void TCPSocket::GetPeerSockaddr(sockaddr_storage *address)
+{
+ socklen_t len = sizeof(*address);
+
+ if (getpeername(GetFD(), (sockaddr *)address, &len) < 0)
+ HandleSocketError();
+}
+
+string TCPSocket::GetClientAddress(void)
+{
+ sockaddr_storage sin;
+
+ GetClientSockaddr(&sin);
+
+ return GetAddressFromSockaddr((sockaddr *)&sin);
+}
+
+string TCPSocket::GetPeerAddress(void)
+{
+ sockaddr_storage sin;
+
+ GetPeerSockaddr(&sin);
+
+ return GetAddressFromSockaddr((sockaddr *)&sin);
+}
class I2_BASE_API TCPSocket : public Socket
{
+private:
+ static string GetAddressFromSockaddr(sockaddr *address);
+ static unsigned short GetPortFromSockaddr(sockaddr *address);
+
public:
typedef shared_ptr<TCPSocket> Ptr;
typedef weak_ptr<TCPSocket> WeakPtr;
void Bind(unsigned short port);
void Bind(const char *hostname, unsigned short port);
+
+ void GetClientSockaddr(sockaddr_storage *address);
+ void GetPeerSockaddr(sockaddr_storage *address);
+
+ string TCPSocket::GetClientAddress(void);
+ string TCPSocket::GetPeerAddress(void);
};
}
#ifndef WIN32_H
#define WIN32_H
-#define NOGDI
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
#include <imagehlp.h>
#include <shlwapi.h>
if (fp.fail())
throw ConfigParserException("Could not open config file");
- GetApplication()->Log("Reading config file: %s", filename.c_str());
+ GetApplication()->Log("Reading config file: " + filename);
while (!fp.eof()) {
size_t bufferSize = 1024;
int DemoComponent::DemoTimerHandler(const TimerEventArgs& tea)
{
- cout << "Sending multicast 'hello world' message." << endl;
+ Application::Log("Sending multicast 'hello world' message.");
JsonRpcRequest request;
request.SetMethod("demo::HelloWorld");
int DemoComponent::HelloWorldRequestHandler(const NewRequestEventArgs& nrea)
{
- cout << "Got 'hello world' from " << nrea.Sender->GetAddress() << endl;
+ Application::Log("Got 'hello world' from address:" + nrea.Sender->GetAddress() + ", identity:" + nrea.Sender->GetIdentity());
return 0;
}
void EndpointManager::AddListener(unsigned short port)
{
- Application::Log("Adding new listener: port %d", port);
+ Application::Log("Adding new listener: port " + port);
JsonRpcServer::Ptr server = make_shared<JsonRpcServer>(m_SSLContext);
RegisterServer(server);
void EndpointManager::AddConnection(string host, unsigned short port)
{
- Application::Log("Adding new endpoint: %s:%d", host.c_str(), port);
+ stringstream s;
+ s << "Adding new endpoint: " << host << ":" << port;
+ Application::Log(s.str());
JsonRpcEndpoint::Ptr endpoint = make_shared<JsonRpcEndpoint>();
endpoint->Connect(host, port, m_SSLContext);
int EndpointManager::NewClientHandler(const NewClientEventArgs& ncea)
{
- Application::Log("Accepted new client");
+ string address = ncea.Client->GetPeerAddress();
+ Application::Log("Accepted new client from " + address);
JsonRpcEndpoint::Ptr endpoint = make_shared<JsonRpcEndpoint>();
endpoint->SetClient(static_pointer_cast<JsonRpcClient>(ncea.Client));
int IcingaApplication::Main(const vector<string>& args)
{
#ifdef _WIN32
- cout << "Icinga component loader" << endl;
+ Application::Log("Icinga component loader");
#else /* _WIN32 */
- cout << "Icinga component loader (version: " << ICINGA_VERSION << ")" << endl;
+ Application::Log("Icinga component loader (version: " ICINGA_VERSION ")");
#endif /* _WIN32 */
if (args.size() < 2) {
using namespace icinga;
-void JsonRpcEndpoint::SetAddress(string address)
-{
- m_Address = address;
-}
-
string JsonRpcEndpoint::GetAddress(void) const
{
- return m_Address;
+ if (!m_Client)
+ return "<disconnected endpoint>";
+
+ return m_Client->GetPeerAddress();
}
JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void)
void JsonRpcEndpoint::Connect(string host, unsigned short port, shared_ptr<SSL_CTX> sslContext)
{
- char portStr[20];
- sprintf(portStr, "%d", port);
- SetAddress("jsonrpc-tcp://" + host + ":" + portStr);
-
JsonRpcClient::Ptr client = make_shared<JsonRpcClient>(RoleOutbound, sslContext);
client->MakeSocket();
client->Connect(host, port);
int JsonRpcEndpoint::ClientClosedHandler(const EventArgs& ea)
{
string address = GetAddress();
- Application::Log("Lost connection to endpoint: %s", address.c_str());
+ Application::Log("Lost connection to endpoint: " + address);
m_PendingCalls.clear();
timer->Start();
m_ReconnectTimer = timer;
- Application::Log("Spawned reconnect timer (30 seconds)", address.c_str());
+ Application::Log("Spawned reconnect timer (30 seconds)");
}
// TODO: _only_ clear non-persistent method sources/sinks