mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
Add simple Linux, Win32 daemons
This commit is contained in:
parent
e6e11590c8
commit
0b210ee99d
83
Daemon.cpp
Normal file
83
Daemon.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
Daemon.h
Normal file
63
Daemon.h
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
109
DaemonLinux.cpp
Normal file
109
DaemonLinux.cpp
Normal file
|
@ -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
|
31
DaemonWin32.cpp
Normal file
31
DaemonWin32.cpp
Normal file
|
@ -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
|
|
@ -13,6 +13,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\AddressBook.cpp" />
|
<ClCompile Include="..\AddressBook.cpp" />
|
||||||
<ClCompile Include="..\base64.cpp" />
|
<ClCompile Include="..\base64.cpp" />
|
||||||
|
<ClCompile Include="..\Daemon.cpp" />
|
||||||
|
<ClCompile Include="..\DaemonLinux.cpp" />
|
||||||
|
<ClCompile Include="..\DaemonWin32.cpp" />
|
||||||
<ClCompile Include="..\Garlic.cpp" />
|
<ClCompile Include="..\Garlic.cpp" />
|
||||||
<ClCompile Include="..\HTTPProxy.cpp" />
|
<ClCompile Include="..\HTTPProxy.cpp" />
|
||||||
<ClCompile Include="..\HTTPServer.cpp" />
|
<ClCompile Include="..\HTTPServer.cpp" />
|
||||||
|
@ -43,6 +46,7 @@
|
||||||
<ClInclude Include="..\AddressBook.h" />
|
<ClInclude Include="..\AddressBook.h" />
|
||||||
<ClInclude Include="..\base64.h" />
|
<ClInclude Include="..\base64.h" />
|
||||||
<ClInclude Include="..\CryptoConst.h" />
|
<ClInclude Include="..\CryptoConst.h" />
|
||||||
|
<ClInclude Include="..\Daemon.h" />
|
||||||
<ClInclude Include="..\ElGamal.h" />
|
<ClInclude Include="..\ElGamal.h" />
|
||||||
<ClInclude Include="..\Garlic.h" />
|
<ClInclude Include="..\Garlic.h" />
|
||||||
<ClInclude Include="..\HTTPProxy.h" />
|
<ClInclude Include="..\HTTPProxy.h" />
|
||||||
|
|
|
@ -99,6 +99,15 @@
|
||||||
<ClCompile Include="Win32Service.cpp">
|
<ClCompile Include="Win32Service.cpp">
|
||||||
<Filter>Win32</Filter>
|
<Filter>Win32</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Daemon.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\DaemonLinux.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\DaemonWin32.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\Identity.h">
|
<ClInclude Include="..\Identity.h">
|
||||||
|
@ -200,5 +209,8 @@
|
||||||
<ClInclude Include="Win32Service.h">
|
<ClInclude Include="Win32Service.h">
|
||||||
<Filter>Win32</Filter>
|
<Filter>Win32</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Daemon.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
196
i2p.cpp
196
i2p.cpp
|
@ -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
|
LogPrint("\n\n\n\ni2pd starting\n");
|
||||||
service_control(isDaemon);
|
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
|
||||||
#endif
|
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
||||||
|
|
||||||
LogPrint("\n\n\n\ni2pd starting\n");
|
Daemon.start();
|
||||||
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
|
while (Daemon.running)
|
||||||
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
{
|
||||||
|
//TODO Meeh: Find something better to do here.
|
||||||
|
std::this_thread::sleep_for (std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
Daemon.start();
|
||||||
|
|
||||||
volatile int isLogging = i2p::util::config::GetArg("-log", 0);
|
return 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)
|
|
||||||
{
|
|
||||||
//TODO Meeh: Find something better to do here.
|
|
||||||
std::this_thread::sleep_for (std::chrono::seconds(1));
|
|
||||||
}
|
|
||||||
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 ();
|
|
||||||
|
|
||||||
if (isLogging == 1)
|
|
||||||
{
|
|
||||||
fclose (stdout);
|
|
||||||
}
|
|
||||||
#ifndef _WIN32
|
|
||||||
close(pidFilehandle);
|
|
||||||
unlink(pidfile.c_str());
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue