mirror of https://github.com/PurpleI2P/i2pd.git
chertov
11 years ago
7 changed files with 315 additions and 183 deletions
@ -0,0 +1,83 @@ |
|||||||
|
#ifdef _WIN32 |
||||||
|
#define _CRT_SECURE_NO_WARNINGS // to use freopen
|
||||||
|
#endif |
||||||
|
|
||||||
|
#include "Daemon.h" |
||||||
|
|
||||||
|
#include "Log.h" |
||||||
|
#include "base64.h" |
||||||
|
#include "Transports.h" |
||||||
|
#include "NTCPSession.h" |
||||||
|
#include "RouterInfo.h" |
||||||
|
#include "RouterContext.h" |
||||||
|
#include "Tunnel.h" |
||||||
|
#include "NetDb.h" |
||||||
|
#include "Garlic.h" |
||||||
|
#include "util.h" |
||||||
|
#include "Streaming.h" |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
bool Daemon_Singleton::start() |
||||||
|
{ |
||||||
|
isDaemon = i2p::util::config::GetArg("-daemon", 0); |
||||||
|
isLogging = i2p::util::config::GetArg("-log", 0); |
||||||
|
|
||||||
|
//TODO: This is an ugly workaround. fix it.
|
||||||
|
//TODO: Autodetect public IP.
|
||||||
|
i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"), |
||||||
|
i2p::util::config::GetArg("-port", 17070)); |
||||||
|
|
||||||
|
if (isLogging == 1) |
||||||
|
{ |
||||||
|
std::string logfile = i2p::util::filesystem::GetDataDir().string(); |
||||||
|
#ifndef _WIN32 |
||||||
|
logfile.append("/debug.log"); |
||||||
|
#else |
||||||
|
logfile.append("\\debug.log"); |
||||||
|
#endif |
||||||
|
freopen(logfile.c_str(), "a", stdout); |
||||||
|
LogPrint("Logging to file enabled."); |
||||||
|
} |
||||||
|
|
||||||
|
httpServer = new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070)); |
||||||
|
httpServer->Start(); |
||||||
|
|
||||||
|
i2p::data::netdb.Start(); |
||||||
|
i2p::transports.Start(); |
||||||
|
i2p::tunnel::tunnels.Start(); |
||||||
|
i2p::garlic::routing.Start(); |
||||||
|
i2p::stream::StartStreaming(); |
||||||
|
|
||||||
|
httpProxy = new i2p::proxy::HTTPProxy(i2p::util::config::GetArg("-httpproxyport", 4446)); |
||||||
|
httpProxy->Start(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool Daemon_Singleton::stop() |
||||||
|
{ |
||||||
|
LogPrint("Shutdown started."); |
||||||
|
|
||||||
|
httpProxy->Stop(); |
||||||
|
i2p::stream::StopStreaming(); |
||||||
|
i2p::garlic::routing.Stop(); |
||||||
|
i2p::tunnel::tunnels.Stop(); |
||||||
|
i2p::transports.Stop(); |
||||||
|
i2p::data::netdb.Stop(); |
||||||
|
httpServer->Stop(); |
||||||
|
|
||||||
|
delete httpProxy; httpProxy = NULL; |
||||||
|
delete httpServer; httpServer = NULL; |
||||||
|
|
||||||
|
if (isLogging == 1) |
||||||
|
{ |
||||||
|
fclose(stdout); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "HTTPServer.h" |
||||||
|
#include "HTTPProxy.h" |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
class Daemon_Singleton |
||||||
|
{ |
||||||
|
public: |
||||||
|
virtual bool start(); |
||||||
|
virtual bool stop(); |
||||||
|
|
||||||
|
int isLogging; |
||||||
|
int isDaemon; |
||||||
|
|
||||||
|
int running = 1; |
||||||
|
|
||||||
|
private: |
||||||
|
i2p::util::HTTPServer *httpServer; |
||||||
|
i2p::proxy::HTTPProxy *httpProxy; |
||||||
|
|
||||||
|
protected: |
||||||
|
Daemon_Singleton() : running(1) {}; |
||||||
|
virtual ~Daemon_Singleton() { |
||||||
|
delete httpServer; |
||||||
|
delete httpProxy; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
#define Daemon i2p::util::DaemonWin32::Instance() |
||||||
|
class DaemonWin32 : public Daemon_Singleton |
||||||
|
{ |
||||||
|
public: |
||||||
|
static DaemonWin32& Instance() |
||||||
|
{ |
||||||
|
static DaemonWin32 instance; |
||||||
|
return instance; |
||||||
|
} |
||||||
|
|
||||||
|
virtual bool start(); |
||||||
|
virtual bool stop(); |
||||||
|
}; |
||||||
|
#else |
||||||
|
#define Daemon i2p::util::DaemonLinux::Instance() |
||||||
|
class DaemonLinux : public Daemon_Singleton |
||||||
|
{ |
||||||
|
public: |
||||||
|
static DaemonLinux& Instance() |
||||||
|
{ |
||||||
|
static DaemonLinux instance; |
||||||
|
return instance; |
||||||
|
} |
||||||
|
|
||||||
|
virtual bool start(); |
||||||
|
virtual bool stop(); |
||||||
|
}; |
||||||
|
#endif |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
#include "Daemon.h" |
||||||
|
|
||||||
|
#ifndef _WIN32 |
||||||
|
|
||||||
|
#include <signal.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
void handle_signal(int sig) |
||||||
|
{ |
||||||
|
switch (sig) |
||||||
|
{ |
||||||
|
case SIGHUP: |
||||||
|
if (i2p::util::config::GetArg("daemon", 0) == 1) |
||||||
|
{ |
||||||
|
static bool first=true; |
||||||
|
if (first) |
||||||
|
{ |
||||||
|
first=false; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
LogPrint("Reloading config."); |
||||||
|
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); |
||||||
|
break; |
||||||
|
case SIGABRT: |
||||||
|
case SIGTERM: |
||||||
|
case SIGINT: |
||||||
|
running = 0; // Exit loop
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
bool DaemonLinux::start() |
||||||
|
{ |
||||||
|
if (isDaemon == 1) |
||||||
|
{ |
||||||
|
pid_t pid; |
||||||
|
pid = fork(); |
||||||
|
if (pid > 0) |
||||||
|
{ |
||||||
|
g_Log.Stop(); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
if (pid < 0) |
||||||
|
{ |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
umask(0); |
||||||
|
int sid = setsid(); |
||||||
|
if (sid < 0) |
||||||
|
{ |
||||||
|
LogPrint("Error, could not create process group."); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
chdir(i2p::util::filesystem::GetDataDir().string().c_str()); |
||||||
|
} |
||||||
|
|
||||||
|
// Pidfile
|
||||||
|
std::string pidfile = i2p::util::filesystem::GetDataDir().string(); |
||||||
|
pidfile.append("/i2pd.pid"); |
||||||
|
int pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); |
||||||
|
if (pidFilehandle == -1) |
||||||
|
{ |
||||||
|
LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
if (lockf(pidFilehandle, F_TLOCK, 0) == -1) |
||||||
|
{ |
||||||
|
LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
char pid[10]; |
||||||
|
sprintf(pid, "%d\n", getpid()); |
||||||
|
write(pidFilehandle, pid, strlen(pid)); |
||||||
|
|
||||||
|
// Signal handler
|
||||||
|
struct sigaction sa; |
||||||
|
sa.sa_handler = handle_signal; |
||||||
|
sigemptyset(&sa.sa_mask); |
||||||
|
sa.sa_flags = SA_RESTART; |
||||||
|
sigaction(SIGHUP, &sa, 0); |
||||||
|
sigaction(SIGABRT, &sa, 0); |
||||||
|
sigaction(SIGTERM, &sa, 0); |
||||||
|
sigaction(SIGINT, &sa, 0); |
||||||
|
|
||||||
|
retunrn Daemon_Singleton::start(); |
||||||
|
} |
||||||
|
|
||||||
|
bool DaemonLinux::stop() |
||||||
|
{ |
||||||
|
Daemon_Singleton::stop(); |
||||||
|
|
||||||
|
close(pidFilehandle); |
||||||
|
unlink(pidfile.c_str()); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,31 @@ |
|||||||
|
#include "Daemon.h" |
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
|
||||||
|
#include "./Win32/Win32Service.h" |
||||||
|
|
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
bool DaemonWin32::start() |
||||||
|
{ |
||||||
|
setlocale(LC_CTYPE, ""); |
||||||
|
SetConsoleCP(1251); |
||||||
|
SetConsoleOutputCP(1251); |
||||||
|
setlocale(LC_ALL, "Russian"); |
||||||
|
|
||||||
|
service_control(isDaemon); |
||||||
|
|
||||||
|
return Daemon_Singleton::start(); |
||||||
|
} |
||||||
|
|
||||||
|
bool DaemonWin32::stop() |
||||||
|
{ |
||||||
|
return Daemon_Singleton::stop(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -1,193 +1,23 @@ |
|||||||
#ifdef _WIN32 |
|
||||||
#define _CRT_SECURE_NO_WARNINGS // to use freopen
|
|
||||||
#endif |
|
||||||
|
|
||||||
#include <iostream> |
|
||||||
#include <thread> |
|
||||||
#include <cryptopp/integer.h> |
|
||||||
#include <boost/filesystem.hpp> |
#include <boost/filesystem.hpp> |
||||||
|
|
||||||
#ifndef _WIN32 |
|
||||||
#include <signal.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <unistd.h> |
|
||||||
#else |
|
||||||
#include "./Win32/Win32Service.h" |
|
||||||
#endif |
|
||||||
|
|
||||||
#include "Log.h" |
|
||||||
#include "base64.h" |
|
||||||
#include "Transports.h" |
|
||||||
#include "NTCPSession.h" |
|
||||||
#include "RouterInfo.h" |
|
||||||
#include "RouterContext.h" |
|
||||||
#include "Tunnel.h" |
|
||||||
#include "NetDb.h" |
|
||||||
#include "HTTPServer.h" |
|
||||||
#include "HTTPProxy.h" |
|
||||||
#include "Garlic.h" |
|
||||||
#include "util.h" |
#include "util.h" |
||||||
#include "Streaming.h" |
#include "Daemon.h" |
||||||
|
|
||||||
|
|
||||||
// Global
|
|
||||||
volatile int running = 1; |
|
||||||
volatile int isDaemon; |
|
||||||
|
|
||||||
#ifndef _WIN32 |
|
||||||
void handle_signal(int sig) |
|
||||||
{ |
|
||||||
switch (sig) |
|
||||||
{ |
|
||||||
case SIGHUP: |
|
||||||
if (i2p::util::config::GetArg("daemon", 0) == 1) |
|
||||||
{ |
|
||||||
static bool first=true; |
|
||||||
if (first) |
|
||||||
{ |
|
||||||
first=false; |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
LogPrint("Reloading config."); |
|
||||||
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); |
|
||||||
break; |
|
||||||
case SIGABRT: |
|
||||||
case SIGTERM: |
|
||||||
case SIGINT: |
|
||||||
running = 0; // Exit loop
|
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char* argv[] ) |
int main( int argc, char* argv[] ) |
||||||
{ |
{ |
||||||
i2p::util::config::OptionParser(argc,argv); |
i2p::util::config::OptionParser(argc, argv); |
||||||
volatile int isDaemon = i2p::util::config::GetArg("-daemon", 0); |
|
||||||
#ifdef _WIN32 |
|
||||||
setlocale(LC_CTYPE, ""); |
|
||||||
SetConsoleCP(1251); |
|
||||||
SetConsoleOutputCP(1251); |
|
||||||
setlocale(LC_ALL, "Russian"); |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef _WIN32 |
|
||||||
service_control(isDaemon); |
|
||||||
#endif |
|
||||||
|
|
||||||
LogPrint("\n\n\n\ni2pd starting\n"); |
|
||||||
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string()); |
|
||||||
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); |
|
||||||
|
|
||||||
volatile int isLogging = i2p::util::config::GetArg("-log", 0); |
|
||||||
if (isLogging == 1) |
|
||||||
{ |
|
||||||
std::string logfile = i2p::util::filesystem::GetDataDir().string(); |
|
||||||
#ifndef _WIN32 |
|
||||||
logfile.append("/debug.log"); |
|
||||||
#else |
|
||||||
logfile.append("\\debug.log"); |
|
||||||
#endif |
|
||||||
freopen(logfile.c_str(),"a",stdout); |
|
||||||
LogPrint("Logging to file enabled."); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32 |
|
||||||
if (isDaemon == 1) |
|
||||||
{ |
|
||||||
pid_t pid; |
|
||||||
pid = fork(); |
|
||||||
if (pid > 0) |
|
||||||
{ |
|
||||||
g_Log.Stop(); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
if (pid < 0) |
|
||||||
{ |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
umask(0); |
|
||||||
int sid = setsid(); |
|
||||||
if (sid < 0) |
|
||||||
{ |
|
||||||
LogPrint("Error, could not create process group."); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
chdir(i2p::util::filesystem::GetDataDir().string().c_str()); |
|
||||||
} |
|
||||||
|
|
||||||
// Pidfile
|
|
||||||
std::string pidfile = i2p::util::filesystem::GetDataDir().string(); |
|
||||||
pidfile.append("/i2pd.pid"); |
|
||||||
int pidFilehandle = open(pidfile.c_str(), O_RDWR|O_CREAT, 0600); |
|
||||||
if (pidFilehandle == -1 ) |
|
||||||
{ |
|
||||||
LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?"); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
if (lockf(pidFilehandle,F_TLOCK,0) == -1) |
|
||||||
{ |
|
||||||
LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?"); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
char pid[10]; |
|
||||||
sprintf(pid,"%d\n",getpid()); |
|
||||||
write(pidFilehandle, pid, strlen(pid)); |
|
||||||
|
|
||||||
// Signal handler
|
|
||||||
struct sigaction sa; |
|
||||||
sa.sa_handler = handle_signal; |
|
||||||
sigemptyset(&sa.sa_mask); |
|
||||||
sa.sa_flags = SA_RESTART; |
|
||||||
sigaction(SIGHUP,&sa,0); |
|
||||||
sigaction(SIGABRT,&sa,0); |
|
||||||
sigaction(SIGTERM,&sa,0); |
|
||||||
sigaction(SIGINT,&sa,0); |
|
||||||
#endif |
|
||||||
|
|
||||||
//TODO: This is an ugly workaround. fix it.
|
|
||||||
//TODO: Autodetect public IP.
|
|
||||||
i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"), |
|
||||||
i2p::util::config::GetArg("-port", 17070)); |
|
||||||
|
|
||||||
i2p::util::HTTPServer httpServer (i2p::util::config::GetArg("-httpport", 7070)); |
|
||||||
|
|
||||||
httpServer.Start (); |
|
||||||
i2p::data::netdb.Start (); |
|
||||||
i2p::transports.Start (); |
|
||||||
i2p::tunnel::tunnels.Start (); |
|
||||||
i2p::garlic::routing.Start (); |
|
||||||
i2p::stream::StartStreaming (); |
|
||||||
|
|
||||||
i2p::proxy::HTTPProxy httpProxy (i2p::util::config::GetArg("-httpproxyport", 4446)); |
|
||||||
httpProxy.Start(); |
|
||||||
|
|
||||||
while (running) |
LogPrint("\n\n\n\ni2pd starting\n"); |
||||||
{ |
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string()); |
||||||
//TODO Meeh: Find something better to do here.
|
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); |
||||||
std::this_thread::sleep_for (std::chrono::seconds(1)); |
|
||||||
} |
|
||||||
LogPrint("Shutdown started."); |
|
||||||
|
|
||||||
httpProxy.Stop (); |
Daemon.start(); |
||||||
i2p::stream::StopStreaming (); |
while (Daemon.running) |
||||||
i2p::garlic::routing.Stop (); |
{ |
||||||
i2p::tunnel::tunnels.Stop (); |
//TODO Meeh: Find something better to do here.
|
||||||
i2p::transports.Stop (); |
std::this_thread::sleep_for (std::chrono::seconds(1)); |
||||||
i2p::data::netdb.Stop (); |
} |
||||||
httpServer.Stop (); |
Daemon.start(); |
||||||
|
|
||||||
if (isLogging == 1) |
return 0; |
||||||
{ |
|
||||||
fclose (stdout); |
|
||||||
} |
|
||||||
#ifndef _WIN32 |
|
||||||
close(pidFilehandle); |
|
||||||
unlink(pidfile.c_str()); |
|
||||||
#endif |
|
||||||
return 0; |
|
||||||
} |
} |
||||||
|
Loading…
Reference in new issue