Browse Source

Merge pull request #412 from PurpleI2P/openssl

recent changes
pull/436/head
orignal 9 years ago
parent
commit
18cc6a184f
  1. 33
      AddressBook.cpp
  2. 1
      Config.cpp
  3. 61
      DaemonWin32.cpp
  4. 4
      FS.cpp
  5. 20
      HTTPProxy.cpp
  6. 22
      HTTPServer.cpp
  7. 1
      HTTPServer.h
  8. 17
      Identity.cpp
  9. 2
      Makefile
  10. 10
      Makefile.mingw
  11. 2
      Transports.cpp
  12. 41
      UPnP.cpp
  13. 1
      Win32/Resource.rc
  14. 51
      Win32/Win32App.cpp
  15. BIN
      Win32/ictoopie_16.ico
  16. 2
      Win32/resource.h
  17. 6
      appveyor.yml
  18. 15
      build/CMakeLists.txt
  19. 17
      i2pd.cpp

33
AddressBook.cpp

@ -56,7 +56,7 @@ namespace client @@ -56,7 +56,7 @@ namespace client
f.seekg (0,std::ios::end);
size_t len = f.tellg ();
if (len < i2p::data::DEFAULT_IDENTITY_SIZE) {
LogPrint (eLogError, "Addresbook: File ", filename, " is too short: ", len);
LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
return nullptr;
}
f.seekg(0, std::ios::beg);
@ -72,7 +72,7 @@ namespace client @@ -72,7 +72,7 @@ namespace client
std::string path = storage.Path( address->GetIdentHash().ToBase32() );
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
if (!f.is_open ()) {
LogPrint (eLogError, "Addresbook: can't open file ", path);
LogPrint (eLogError, "Addressbook: can't open file ", path);
return;
}
size_t len = address->GetFullLen ();
@ -174,17 +174,17 @@ namespace client @@ -174,17 +174,17 @@ namespace client
}
if (m_IsDownloading)
{
LogPrint (eLogInfo, "Addresbook: subscriptions is downloading, abort");
LogPrint (eLogInfo, "Addressbook: subscriptions is downloading, abort");
for (int i = 0; i < 30; i++)
{
if (!m_IsDownloading)
{
LogPrint (eLogInfo, "Addresbook: subscriptions download complete");
LogPrint (eLogInfo, "Addressbook: subscriptions download complete");
break;
}
std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds
}
LogPrint (eLogError, "Addresbook: subscription download timeout");
LogPrint (eLogError, "Addressbook: subscription download timeout");
m_IsDownloading = false;
}
if (m_Storage)
@ -303,10 +303,10 @@ namespace client @@ -303,10 +303,10 @@ namespace client
numAddresses++;
}
else
LogPrint (eLogError, "Addresbook: malformed address ", addr, " for ", name);
LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name);
}
}
LogPrint (eLogInfo, "Addresbook: ", numAddresses, " addresses processed");
LogPrint (eLogInfo, "Addressbook: ", numAddresses, " addresses processed");
if (numAddresses > 0)
{
m_IsLoaded = true;
@ -331,7 +331,7 @@ namespace client @@ -331,7 +331,7 @@ namespace client
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
}
else
LogPrint (eLogWarning, "Addresbook: subscriptions.txt not found in datadir");
LogPrint (eLogWarning, "Addressbook: subscriptions.txt not found in datadir");
}
else
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
@ -340,15 +340,18 @@ namespace client @@ -340,15 +340,18 @@ namespace client
void AddressBook::DownloadComplete (bool success)
{
m_IsDownloading = false;
if (success && m_DefaultSubscription)
int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
if (success)
{
m_DefaultSubscription.reset (nullptr);
if (m_DefaultSubscription) m_DefaultSubscription.reset (nullptr);
if (m_IsLoaded)
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
else
m_IsLoaded = true;
}
if (m_SubscriptionsUpdateTimer)
{
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(
success ? CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT : CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT));
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(nextUpdateTimeout));
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
this, std::placeholders::_1));
}
@ -368,7 +371,7 @@ namespace client @@ -368,7 +371,7 @@ namespace client
this, std::placeholders::_1));
}
else
LogPrint (eLogError, "Addresbook: can't start subscriptions: missing shared local destination");
LogPrint (eLogError, "Addressbook: can't start subscriptions: missing shared local destination");
}
void AddressBook::StopSubscriptions ()
@ -429,7 +432,7 @@ namespace client @@ -429,7 +432,7 @@ namespace client
void AddressBookSubscription::Request ()
{
// must be run in separate thread
LogPrint (eLogInfo, "Addresbook: Downloading hosts database from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
bool success = false;
i2p::util::http::url u (m_Link);
i2p::data::IdentHash ident;
@ -488,7 +491,7 @@ namespace client @@ -488,7 +491,7 @@ namespace client
30); // wait for 30 seconds
std::unique_lock<std::mutex> l(newDataReceivedMutex);
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
LogPrint (eLogError, "Addresbook: subscriptions request timeout expired");
LogPrint (eLogError, "Addressbook: subscriptions request timeout expired");
}
// process remaining buffer
while (size_t len = stream->ReadSome (buf, 4096))

1
Config.cpp

@ -125,6 +125,7 @@ namespace config { @@ -125,6 +125,7 @@ namespace config {
("bandwidth", value<char>()->default_value('-'), "Bandwidth limiting: L - 32kbps, O - 256Kbps, P - unlimited")
#ifdef _WIN32
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
("insomnia", value<bool>()->zero_tokens()->default_value(false), "Prevent system from sleeping")
#endif
;

61
DaemonWin32.cpp

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
#include <thread>
#include "Config.h"
#include "Daemon.h"
#include "util.h"
@ -5,7 +6,10 @@ @@ -5,7 +6,10 @@
#ifdef _WIN32
#include "Win32/Win32Service.h"
#ifdef WIN32_APP
#include "Win32/Win32App.h"
#endif
namespace i2p
{
@ -16,8 +20,46 @@ namespace i2p @@ -16,8 +20,46 @@ namespace i2p
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
return Daemon_Singleton::init(argc, argv);
if (!Daemon_Singleton::init(argc, argv))
return false;
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
if (serviceControl == "install")
{
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
return false;
}
else if (serviceControl == "remove")
{
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
UninstallService(SERVICE_NAME);
return false;
}
if (isDaemon == 1)
{
LogPrint(eLogDebug, "Daemon: running as service");
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
return false;
}
return false;
}
else
LogPrint(eLogDebug, "Daemon: running as user");
return true;
}
bool DaemonWin32::start()
@ -26,10 +68,12 @@ namespace i2p @@ -26,10 +68,12 @@ namespace i2p
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
#ifdef WIN32_APP
if (!i2p::win32::StartWin32App ()) return false;
// override log
i2p::config::SetOption("log", std::string ("file"));
#endif
bool ret = Daemon_Singleton::start();
if (ret && IsLogToFile ())
{
@ -37,18 +81,31 @@ namespace i2p @@ -37,18 +81,31 @@ namespace i2p
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
}
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
if (insomnia)
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
return ret;
}
bool DaemonWin32::stop()
{
#ifdef WIN32_APP
i2p::win32::StopWin32App ();
#endif
return Daemon_Singleton::stop();
}
void DaemonWin32::run ()
{
#ifdef WIN32_APP
i2p::win32::RunWin32App ();
#else
while (running)
{
std::this_thread::sleep_for (std::chrono::seconds(1));
}
#endif
}
}
}

4
FS.cpp

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
#include <algorithm>
#include <boost/filesystem.hpp>
#ifdef WIN32
#ifdef _WIN32
#include <shlobj.h>
#endif
@ -108,7 +108,7 @@ namespace fs { @@ -108,7 +108,7 @@ namespace fs {
bool HashedStorage::Init(const char * chars, size_t count) {
if (!boost::filesystem::exists(root)) {
boost::filesystem::create_directory(root);
boost::filesystem::create_directories(root);
}
for (size_t i = 0; i < count; i++) {

20
HTTPProxy.cpp

@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
#include "ClientContext.h"
#include "I2PEndian.h"
#include "I2PTunnel.h"
#include "Config.h"
namespace i2p
{
@ -36,6 +37,7 @@ namespace proxy @@ -36,6 +37,7 @@ namespace proxy
void Terminate();
void AsyncSockRead();
void HTTPRequestFailed(/*std::string message*/);
void RedirectToJumpService();
void ExtractRequest();
bool ValidateHTTPRequest();
void HandleJumpServices();
@ -95,6 +97,17 @@ namespace proxy @@ -95,6 +97,17 @@ namespace proxy
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
}
void HTTPProxyHandler::RedirectToJumpService(/*HTTPProxyHandler::errTypes error*/)
{
std::stringstream response;
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
response << "HTTP/1.1 302 Found\r\nLocation: http://" << httpAddr << ":" << httpPort << "/?jumpservices=&address=" << m_address << "\r\n\r\n";
boost::asio::async_write(*m_sock, boost::asio::buffer(response.str (),response.str ().length ()),
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
}
void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate)
{
m_state = nstate;
@ -168,6 +181,13 @@ namespace proxy @@ -168,6 +181,13 @@ namespace proxy
ExtractRequest(); //TODO: parse earlier
if (!ValidateHTTPRequest()) return false;
HandleJumpServices();
i2p::data::IdentHash identHash;
if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){
RedirectToJumpService();
return false;
}
m_request = m_method;
m_request.push_back(' ');
m_request += m_path;

22
HTTPServer.cpp

@ -203,6 +203,9 @@ namespace util @@ -203,6 +203,9 @@ namespace util
const char HTTP_COMMAND_SAM_SESSION[] = "sam_session";
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels";
const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices=";
const char HTTP_PARAM_ADDRESS[] = "address";
namespace misc_strings
{
@ -393,6 +396,7 @@ namespace util @@ -393,6 +396,7 @@ namespace util
else
s << "<a href=/?" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n<br>\r\n";
s << "<a href=/?" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n<br>\r\n";
s << "<a href=/?" << HTTP_COMMAND_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n<br>\r\n";
s << "</div><div class=right>";
if (address.length () > 1)
HandleCommand (address.substr (2), s);
@ -464,7 +468,13 @@ namespace util @@ -464,7 +468,13 @@ namespace util
ShowTransports (s);
else if (cmd == HTTP_COMMAND_TUNNELS)
ShowTunnels (s);
else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS)
else if (cmd == HTTP_COMMAND_JUMPSERVICES)
{
std::map<std::string, std::string> params;
ExtractParams (command.substr (paramsPos), params);
auto address = params[HTTP_PARAM_ADDRESS];
ShowJumpServices (address, s);
} else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS)
ShowTransitTunnels (s);
else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS)
StartAcceptingTunnels (s);
@ -494,6 +504,16 @@ namespace util @@ -494,6 +504,16 @@ namespace util
ShowI2PTunnels (s);
}
void HTTPConnection::ShowJumpServices (const std::string& address, std::stringstream& s)
{
s << "<form type=\"get\" action=\"/\">";
s << "<input type=\"hidden\" name=\"jumpservices\">";
s << "<input type=\"text\" value=\"" << address << "\" name=\"address\"> </form><br>\r\n";
s << "<b>Jump services for " << address << "</b>";
s << "<ul><li><a href=\"http://inr.i2p/search/?q=" << address << "\">inr.i2p jump service</a> <br>\r\n";
s << "<li><a href=\"http://stats.i2p/cgi-bin/jump.cgi?a=" << address << "\">stats.i2p jump service</a></ul>";
}
void HTTPConnection::ShowLocalDestinations (std::stringstream& s)
{
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";

1
HTTPServer.h

@ -62,6 +62,7 @@ namespace util @@ -62,6 +62,7 @@ namespace util
void HandleRequest (const std::string& address);
void HandleCommand (const std::string& command, std::stringstream& s);
void ShowJumpServices (const std::string& address, std::stringstream& s);
void ShowTransports (std::stringstream& s);
void ShowTunnels (std::stringstream& s);
void ShowTransitTunnels (std::stringstream& s);

17
Identity.cpp

@ -244,21 +244,20 @@ namespace data @@ -244,21 +244,20 @@ namespace data
size_t IdentityEx::FromBase64(const std::string& s)
{
const size_t slen = s.length();
uint8_t buf[slen]; // binary data can't exceed base64
const size_t len = Base64ToByteStream (s.c_str(), slen, buf, slen);
return FromBuffer (buf, len);
std::vector<uint8_t> buf(slen); // binary data can't exceed base64
const size_t len = Base64ToByteStream (s.c_str(), slen, buf.data(), slen);
return FromBuffer (buf.data(), len);
}
std::string IdentityEx::ToBase64 () const
{
const size_t bufLen = GetFullLen();
const size_t strLen = Base64EncodingBufferSize(bufLen);
uint8_t buf[bufLen];
char str[strLen];
size_t l = ToBuffer (buf, bufLen);
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, strLen);
str[l1] = 0;
return std::string (str);
std::vector<uint8_t> buf(bufLen);
std::vector<char> str(strLen);
size_t l = ToBuffer (buf.data(), bufLen);
size_t l1 = i2p::data::ByteStreamToBase64 (buf.data(), l, str.data(), strLen);
return std::string (str.data(), l1);
}
size_t IdentityEx::GetSigningPublicKeyLen () const

2
Makefile

@ -22,7 +22,7 @@ else ifeq ($(UNAME),Linux) @@ -22,7 +22,7 @@ else ifeq ($(UNAME),Linux)
DAEMON_SRC += DaemonLinux.cpp
include Makefile.linux
else # win32 mingw
DAEMON_SRC += DaemonWin32.cpp Win32/Win32App.cpp
DAEMON_SRC += DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
include Makefile.mingw
endif

10
Makefile.mingw

@ -1,10 +1,11 @@ @@ -1,10 +1,11 @@
USE_WIN32_APP=yes
CXX = g++
WINDRES = windres
CXXFLAGS = -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
NEEDED_CXXFLAGS = -std=c++11
BOOST_SUFFIX = -mt
INCFLAGS = -I/usr/include/ -I/usr/local/include/
LDFLAGS = -mwindows -Wl,-rpath,/usr/local/lib \
LDFLAGS = -Wl,-rpath,/usr/local/lib \
-L/usr/local/lib \
-L/c/dev/openssl \
-L/c/dev/boost/lib
@ -24,8 +25,13 @@ LDLIBS = \ @@ -24,8 +25,13 @@ LDLIBS = \
-static-libgcc -static-libstdc++ \
-Wl,-Bstatic -lstdc++ \
-Wl,-Bstatic -lpthread
ifeq ($(USE_WIN32_APP), yes)
CXXFLAGS += -DWIN32_APP
LDFLAGS += -mwindows -s
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
ifeq ($(USE_AESNI),1)
CPU_FLAGS = -maes -DAESNI

2
Transports.cpp

@ -261,7 +261,7 @@ namespace transport @@ -261,7 +261,7 @@ namespace transport
{
peer.numAttempts++;
auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ());
if (address)
if (address && m_NTCPServer)
{
#if BOOST_VERSION >= 104900
if (!address->host.is_unspecified ()) // we have address now

41
UPnP.cpp

@ -19,27 +19,19 @@ @@ -19,27 +19,19 @@
#include "UPnP.h"
#include "NetDb.h"
#include "util.h"
#include "RouterInfo.h"
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
// These are per-process and are safe to reuse for all threads
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int);
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *,
const char *, const char *, const char *, const char *);
#else
/* miniupnpc 1.6 */
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int, int, int *);
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *,
const char *, const char *, const char *, const char *, const char *);
#endif
int (*UPNP_GetValidIGDFunc) (struct UPNPDev *, struct UPNPUrls *, struct IGDdatas *, char *, int);
int (*UPNP_GetExternalIPAddressFunc) (const char *, const char *, char *);
int (*UPNP_DeletePortMappingFunc) (const char *, const char *, const char *, const char *, const char *);
void (*freeUPNPDevlistFunc) (struct UPNPDev *);
void (*FreeUPNPUrlsFunc) (struct UPNPUrls *);
decltype(upnpDiscover) *upnpDiscoverFunc;
decltype(UPNP_AddPortMapping) *UPNP_AddPortMappingFunc;
decltype(UPNP_GetValidIGD) *UPNP_GetValidIGDFunc;
decltype(UPNP_GetExternalIPAddress) *UPNP_GetExternalIPAddressFunc;
decltype(UPNP_DeletePortMapping) *UPNP_DeletePortMappingFunc;
decltype(freeUPNPDevlist) *freeUPNPDevlistFunc;
decltype(FreeUPNPUrls) *FreeUPNPUrlsFunc;
// Nice approach http://stackoverflow.com/a/21517513/673826
template<class M, typename F>
@ -109,7 +101,8 @@ namespace transport @@ -109,7 +101,8 @@ namespace transport
void UPnP::Run ()
{
for (auto& address : context.GetRouterInfo ().GetAddresses ())
std::vector<data::RouterInfo::Address> a = context.GetRouterInfo().GetAddresses();
for (auto& address : a)
{
if (!address.host.is_v6 ())
{
@ -128,12 +121,10 @@ namespace transport @@ -128,12 +121,10 @@ namespace transport
void UPnP::Discover ()
{
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0);
#else
/* miniupnpc 1.6 */
int nerror = 0;
#if MINIUPNPC_API_VERSION >= 14
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
#else
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif
@ -180,13 +171,7 @@ namespace transport @@ -180,13 +171,7 @@ namespace transport
std::string strDesc = "I2Pd";
try {
for (;;) {
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0);
#else
/* miniupnpc 1.6 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
#endif
if (r!=UPNPCOMMAND_SUCCESS)
{
LogPrint (eLogError, "UPnP: AddPortMapping (", strPort.c_str () ,", ", strPort.c_str () ,", ", m_NetworkAddr, ") failed with code ", r);

1
Win32/Resource.rc

@ -53,7 +53,6 @@ END @@ -53,7 +53,6 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
MAINICON ICON "ictoopie.ico"
IDI_ICON1 ICON "ictoopie_16.ico"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////

51
Win32/Win32App.cpp

@ -1,12 +1,14 @@ @@ -1,12 +1,14 @@
#include <string.h>
#include <windows.h>
#include <shellapi.h>
//#include "../Daemon.h"
#include "../Config.h"
#include "resource.h"
#include "Win32App.h"
#define ID_ABOUT 2000
#define ID_EXIT 2001
#define ID_CONSOLE 2002
#define ID_APP 2003
#define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1)
@ -18,10 +20,12 @@ namespace win32 @@ -18,10 +20,12 @@ namespace win32
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{
HMENU hPopup = CreatePopupMenu();
InsertMenu (hPopup, 0, MF_BYPOSITION | MF_STRING, ID_ABOUT, "About...");
InsertMenu (hPopup, 1, MF_BYPOSITION | MF_STRING, ID_EXIT , "Exit");
SetMenuDefaultItem (hPopup, ID_ABOUT, FALSE);
SetFocus (hWnd);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
POINT p;
@ -44,10 +48,11 @@ namespace win32 @@ -44,10 +48,11 @@ namespace win32
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = ID_TRAY_ICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
nid.uCallbackMessage = WM_TRAYICON;
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (IDI_ICON1));
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
strcpy (nid.szTip, "i2pd");
strcpy (nid.szInfo, "i2pd is running");
Shell_NotifyIcon(NIM_ADD, &nid );
}
@ -88,14 +93,39 @@ namespace win32 @@ -88,14 +93,39 @@ namespace win32
PostMessage (hWnd, WM_CLOSE, 0, 0);
return 0;
}
case ID_CONSOLE:
{
char buf[30];
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
std::snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
case ID_APP:
{
ShowWindow(hWnd, SW_SHOW);
return 0;
}
}
break;
}
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_MINIMIZE:
{
ShowWindow(hWnd, SW_HIDE);
return 0;
}
}
}
case WM_TRAYICON:
{
SetForegroundWindow (hWnd);
switch (lParam)
{
case WM_LBUTTONUP:
case WM_RBUTTONUP:
{
SetForegroundWindow (hWnd);
@ -127,15 +157,14 @@ namespace win32 @@ -127,15 +157,14 @@ namespace win32
wclx.cbClsExtra = 0;
wclx.cbWndExtra = 0;
wclx.hInstance = hInst;
wclx.hIcon = LoadIcon (hInst, IDI_APPLICATION);
wclx.hIconSm = LoadIcon (hInst, IDI_APPLICATION);
wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON));
wclx.hCursor = LoadCursor (NULL, IDC_ARROW);
wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wclx.lpszMenuName = NULL;
wclx.lpszClassName = I2PD_WIN32_CLASSNAME;
RegisterClassEx (&wclx);
// create new window
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 150, NULL, NULL, hInst, NULL))
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 250, 150, NULL, NULL, hInst, NULL))
{
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;

BIN
Win32/ictoopie_16.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

2
Win32/resource.h

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
//
#define IDI_ICON1 101
#define MAINICON 101
// Next default values for new objects
//

6
appveyor.yml

@ -142,9 +142,9 @@ install: @@ -142,9 +142,9 @@ install:
- if not defined msvc (
C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel"
&& if "%x64%" == "1" (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
) else (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-boost mingw-w64-i686-miniupnpc"
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc"
)
)
cache:
@ -167,7 +167,7 @@ build_script: @@ -167,7 +167,7 @@ build_script:
echo "bitness=%bitness%; static=%static%; dll=%dll%; type=%type%; generator=%generator%; variant=%variant%; cmake=%cmake%; cmake_extra=%cmake_extra%"
- if not defined msvc (
C:\msys64\usr\bin\bash -lc "export PATH=/mingw%bitness%/bin:/usr/bin && cd /c/projects/build && cmake /c/projects/i2pd/build -G 'Unix Makefiles' -DWITH_AESNI=ON -DWITH_UPNP=ON %cmake% %cmake_extra% -DWITH_STATIC=%static% -DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=/c/projects/instdir -DCMAKE_FIND_ROOT_PATH=/mingw%bitness% && make install"
C:\msys64\usr\bin\bash -lc "export PATH=/mingw%bitness%/bin:/usr/bin && cd /c/projects/build && CC=/mingw%bitness%/bin/gcc.exe CXX=/mingw%bitness%/bin/g++.exe /usr/bin/cmake /c/projects/i2pd/build -G 'Unix Makefiles' -DWITH_AESNI=ON -DWITH_UPNP=ON %cmake% %cmake_extra% -DWITH_STATIC=%static% -DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=/c/projects/instdir -DCMAKE_FIND_ROOT_PATH=/mingw%bitness% && make install"
&& 7z a -tzip -mx9 -mmt C:\projects\i2pd\i2pd-mingw-win%bitness%-%type%.zip C:\projects\instdir\* C:\msys64\mingw%bitness%\bin\zlib1.dll C:\msys64\mingw%bitness%\bin\*eay32.dll
)
- rem We are fine with multiple generated configurations in MS solution. Will use later

15
build/CMakeLists.txt

@ -11,6 +11,7 @@ option(WITH_BINARY "Build binary" ON) @@ -11,6 +11,7 @@ option(WITH_BINARY "Build binary" ON)
option(WITH_STATIC "Static build" OFF)
option(WITH_UPNP "Include support for UPnP client" OFF)
option(WITH_PCH "Use precompiled header" OFF)
option(WITH_GUI "Include GUI (currently MS Windows only)" ON)
# paths
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
@ -56,7 +57,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS) @@ -56,7 +57,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
endif ()
add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES OUTPUT_NAME "i2pd")
set_target_properties(libi2pd PROPERTIES PREFIX "")
install(TARGETS libi2pd
EXPORT libi2pd
ARCHIVE DESTINATION lib
@ -95,7 +96,7 @@ endif () @@ -95,7 +96,7 @@ endif ()
# compiler flags customization (by vendor)
if (MSVC)
add_definitions( -D_WIN32_WINNT=_WIN32_WINNT_WINXP -DWIN32_LEAN_AND_MEAN -DNOMINMAX ) #-DOPENSSL_NO_SSL2 -DOPENSSL_USE_DEPRECATED
add_definitions( -DWIN32_LEAN_AND_MEAN -DNOMINMAX )
# TODO Check & report to Boost dev, there should be no need for these two
add_definitions( -DBOOST_THREAD_NO_LIB -DBOOST_CHRONO_NO_LIB )
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL" )
@ -157,6 +158,11 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") @@ -157,6 +158,11 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonWin32.cpp")
if (WITH_GUI)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp")
set_source_files_properties("${CMAKE_SOURCE_DIR}/DaemonWin32.cpp"
PROPERTIES COMPILE_DEFINITIONS WIN32_APP)
endif ()
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp")
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Resource.rc")
endif ()
@ -309,7 +315,10 @@ include(GNUInstallDirs) @@ -309,7 +315,10 @@ include(GNUInstallDirs)
if (WITH_BINARY)
add_executable ( "${PROJECT_NAME}" ${DAEMON_SRC} )
if(NOT MSVC) # FIXME: incremental linker file name (.ilk) collision for dll & exe
if (WIN32 AND WITH_GUI)
set_target_properties("${PROJECT_NAME}" PROPERTIES WIN32_EXECUTABLE TRUE )
endif()
if(NOT MSVC)
if (WITH_STATIC)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static" )
endif ()

17
i2pd.cpp

@ -3,10 +3,25 @@ @@ -3,10 +3,25 @@
int main( int argc, char* argv[] )
{
Daemon.init(argc, argv);
if (Daemon.init(argc, argv))
{
if (Daemon.start())
Daemon.run ();
Daemon.stop();
}
return EXIT_SUCCESS;
}
#ifdef _WIN32
#include <windows.h>
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
return main(__argc, __argv);
}
#endif

Loading…
Cancel
Save