diff --git a/.gitignore b/.gitignore
index c472d88e..5424262f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -254,4 +254,11 @@ docs/generated
build/Makefile
# debian stuff
-.pc/
\ No newline at end of file
+.pc/
+
+# qt
+
+qt/i2pd_qt/*.ui.autosave
+qt/i2pd_qt/*.ui.bk*
+qt/i2pd_qt/*.ui_*
+
diff --git a/Makefile.linux b/Makefile.linux
index 782b0203..0fd8873d 100644
--- a/Makefile.linux
+++ b/Makefile.linux
@@ -19,7 +19,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6
NEEDED_CXXFLAGS += -std=c++0x
-else ifeq ($(shell expr match ${CXXVER} "[5-6]\.[0-9]"),3) # gcc >= 5.0
+else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0
NEEDED_CXXFLAGS += -std=c++11
else # not supported
$(error Compiler too old)
diff --git a/Win32/.gitignore b/Win32/.gitignore
deleted file mode 100644
index 5aa0538d..00000000
--- a/Win32/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-*
-!*/
-
-!*.h
-!*.cpp
-
-!*.bat
-
-!*.sln
-!*.vcproj
-!*.vcxproj
-!*.vcxproj.filters
-!*.iss
-!.gitignore
diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp
index 6eb43dc0..698cf390 100644
--- a/Win32/DaemonWin32.cpp
+++ b/Win32/DaemonWin32.cpp
@@ -60,7 +60,6 @@ namespace i2p
}
else
LogPrint(eLogDebug, "Daemon: running as user");
-
return true;
}
@@ -71,10 +70,10 @@ namespace i2p
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
#ifdef WIN32_APP
- if (!i2p::win32::StartWin32App ()) return false;
+ if (!i2p::win32::StartWin32App ()) return false;
- // override log
- i2p::config::SetOption("log", std::string ("file"));
+ // override log
+ i2p::config::SetOption("log", std::string ("file"));
#endif
bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
@@ -92,24 +91,22 @@ namespace i2p
bool DaemonWin32::stop()
{
#ifdef WIN32_APP
- i2p::win32::StopWin32App ();
+ i2p::win32::StopWin32App ();
#endif
return Daemon_Singleton::stop();
}
void DaemonWin32::run ()
- {
+ {
#ifdef WIN32_APP
- i2p::win32::RunWin32App ();
+ i2p::win32::RunWin32App ();
#else
while (running)
{
std::this_thread::sleep_for (std::chrono::seconds(1));
}
-
#endif
- }
+ }
}
}
-
#endif
diff --git a/Win32/Itoopie.cmd b/Win32/Itoopie.cmd
deleted file mode 100644
index f7d895c8..00000000
--- a/Win32/Itoopie.cmd
+++ /dev/null
@@ -1,14 +0,0 @@
-@echo off
-convert Itoopie.svg ^
- -fuzz 90%% -fill transparent -floodfill 2x2 white -fuzz 20%% -fill #AE0E99 -opaque red ^
- -fill #FBBC11 -opaque yellow ^
- ( -clone 0 -resize 256x256 ) ^
- ( -clone 0 -resize 128x128 ) ^
- ( -clone 0 -resize 64x64 ) ^
- ( -clone 0 -resize 48x48 ) ^
- ( -clone 0 -resize 32x32 ) ^
- ( -clone 0 -resize 24x24 ) ^
- ( -clone 0 -resize 16x16 ) ^
- ( -size 150x57 xc:white -clone 0 -geometry 57x57+46+0 -composite -gravity center -write BMP3:ictoopie.bmp +delete ) ^
- ( -clone 0 -write Itoopie_purple.png +delete ) ^
- -delete 0 ictoopie.ico
diff --git a/Win32/PurpleI2P.nsi b/Win32/PurpleI2P.nsi
deleted file mode 100644
index 7aa69daf..00000000
--- a/Win32/PurpleI2P.nsi
+++ /dev/null
@@ -1,282 +0,0 @@
-# NSIS Installer script. (Tested with NSIS 2.64 on Windows 7)
-# Author: Mikal Villa (Meeh)
-# Version: 1.1
-Name PurpleI2P
-
-RequestExecutionLevel highest
-SetCompressor /SOLID lzma
-ShowInstDetails show
-
-# General Symbol Definitions
-!define REGKEY "SOFTWARE\$(^Name)"
-!define VERSION 0.3.0.0
-!define COMPANY "The Privacy Solutions Project"
-!define URL "https://i2p.io"
-
-# MUI Symbol Definitions
-!define MUI_ICON "mask.ico"
-#!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
-!define MUI_HEADERIMAGE
-!define MUI_HEADERIMAGE_RIGHT
-#!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp"
-!define MUI_FINISHPAGE_NOAUTOCLOSE
-!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
-!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
-!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
-!define MUI_STARTMENUPAGE_DEFAULTFOLDER PurpleI2P
-!define MUI_FINISHPAGE_RUN $INSTDIR\i2pd.exe
-!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\Readme.txt
-
-
-!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
-!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
-!define MUI_UNFINISHPAGE_NOAUTOCLOSE
-
-# Included files
-!include Sections.nsh
-!include MUI2.nsh
-!include nsDialogs.nsh
-!include winmessages.nsh
-!include logiclib.nsh
-# Local included files
-!include nsi\helper_readme.nsh
-;!include nsi\servicelib.nsh
-
-# Variables
-Var StartMenuGroup
-
-# Installer pages
-# Execution flow of installer windows
-!insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_README "../Readme.md"
-!insertmacro MUI_PAGE_DIRECTORY
-# Disabled for now. Use the bat
-;Page custom mode_selection # Meeh's hack for installing and starting service.
-!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
-!insertmacro MUI_PAGE_INSTFILES
-!insertmacro MUI_PAGE_FINISH
-
-# Uninstall pages
-!insertmacro MUI_UNPAGE_CONFIRM
-!insertmacro MUI_UNPAGE_INSTFILES
-
-# Installer languages
-!insertmacro MUI_LANGUAGE English
-
-# Installer attributes
-OutFile PurpleI2P-0.3.0.0-win32-setup.exe
-InstallDir $PROGRAMFILES\PurpleI2P
-CRCCheck on
-XPStyle on
-BrandingText " "
-ShowInstDetails show
-VIProductVersion 0.3.0.0
-VIAddVersionKey ProductName PurpleI2P
-VIAddVersionKey ProductVersion "${VERSION}"
-VIAddVersionKey CompanyName "${COMPANY}"
-VIAddVersionKey CompanyWebsite "${URL}"
-VIAddVersionKey FileVersion "${VERSION}"
-VIAddVersionKey FileDescription ""
-VIAddVersionKey LegalCopyright ""
-InstallDirRegKey HKCU "${REGKEY}" Path
-ShowUninstDetails show
-
-# Readme definitions
-
-;--------------------------------
-;Languages
- ;Set up install lang strings for 1st lang
- ${ReadmeLanguage} "${LANG_ENGLISH}" \
- "Read Me" \
- "Please review the following important information." \
- "About $(^name):" \
- "$\n Click on scrollbar arrows or press Page Down to review the entire text."
-
- ;Add 2nd language
- !insertmacro MUI_LANGUAGE "Norwegian"
-
- ;set up install lang strings for second lang
- ${ReadmeLanguage} "${LANG_NORWEGIAN}" \
- "Les meg!" \
- "Vennligst les informasjonen om hvordan du skal bruke PurpleI2P." \
- "Om $(^name):" \
- "$\n Klikk på scrollbaren til høyre for å se hele innholdet."
-
-;--------------------------------
-
-# Installer sections
-Section -Main SEC0000
- SetOutPath $INSTDIR
- SetOverwrite on
- File /oname=i2pd.exe Release\i2pd.exe
- File /oname=install_service.bat install_service.bat
- File /oname=uninstall_service.bat uninstall_service.bat
- File /oname=LICENSE.txt ..\LICENSE
- File /oname=Readme.txt ..\README.md
- SetOutPath $INSTDIR\src
- File /r /x *.nsi /x *.rc /x *.exe /x *.obj /x *.nsh /x *.sln /x *.vcxproj /x *.tlog /x *.log /x *.res /x *.pdb /x *.suo /x *.opensdf /x *.filters /x *.sdf /x *.iss /x *.aps /x .gitignore /x *.o ../\*.*
- SetOutPath $INSTDIR
- RMDir /r /REBOOTOK $INSTDIR\src\.git # Remove git directory
- RMDir /r /REBOOTOK $INSTDIR\src\Win32\Release # Removing release directory
- RMDir /r /REBOOTOK $INSTDIR\src\Win32\nsi
- WriteRegStr HKCU "${REGKEY}\Components" Main 1
-SectionEnd
-
-Section -post SEC0001
- WriteRegStr HKCU "${REGKEY}" Path $INSTDIR
- SetOutPath $INSTDIR
- WriteUninstaller $INSTDIR\uninstall.exe
- !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
- CreateDirectory $SMPROGRAMS\$StartMenuGroup
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk" $INSTDIR\i2pd.exe
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk" $INSTDIR\install_service.bat
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P Service.lnk" $INSTDIR\uninstall_service.bat
- CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk" $INSTDIR\uninstall.exe
- !insertmacro MUI_STARTMENU_WRITE_END
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe
- WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
- WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
- WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
- WriteRegStr HKCR "i2pd" "URL Protocol" ""
- WriteRegStr HKCR "i2pd" "" "URL:i2pd" # TODO: if a instance of own is found, relaunch with a proxyfied browser to open webage. (e.g i2pd://meeh.i2p)
- WriteRegStr HKCR "i2pd\DefaultIcon" "" $INSTDIR\i2pd.exe
- WriteRegStr HKCR "i2pd\shell\open\command" "" '"$INSTDIR\i2pd.exe" "%1"'
-SectionEnd
-
-# Macro for selecting uninstaller sections
-!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
- Push $R0
- ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}"
- StrCmp $R0 1 0 next${UNSECTION_ID}
- !insertmacro SelectSection "${UNSECTION_ID}"
- GoTo done${UNSECTION_ID}
-next${UNSECTION_ID}:
- !insertmacro UnselectSection "${UNSECTION_ID}"
-done${UNSECTION_ID}:
- Pop $R0
-!macroend
-
-
-# Uninstaller sections
-Section /o -un.Main UNSEC0000
- Delete /REBOOTOK $INSTDIR\i2pd.exe
- Delete /REBOOTOK $INSTDIR\LICENSE.txt
- Delete /REBOOTOK $INSTDIR\Readme.txt
- Delete /REBOOTOK $INSTDIR\install_service.bat
- Delete /REBOOTOK $INSTDIR\uninstall_service.bat
- RMDir /r /REBOOTOK $INSTDIR\src
- DeleteRegValue HKCU "${REGKEY}\Components" Main
-SectionEnd
-
-Section -un.post UNSEC0001
- DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk"
- Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\UnInstall PurpleI2P Service.lnk"
- Delete /REBOOTOK "$SMSTARTUP\PurpleI2P.lnk"
- Delete /REBOOTOK $INSTDIR\uninstall.exe
- Delete /REBOOTOK $INSTDIR\debug.log
- DeleteRegValue HKCU "${REGKEY}" StartMenuGroup
- DeleteRegValue HKCU "${REGKEY}" Path
- DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
- DeleteRegKey /IfEmpty HKCU "${REGKEY}"
- DeleteRegKey HKCR "i2pd"
- RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
- RmDir /REBOOTOK $INSTDIR
- Push $R0
- StrCpy $R0 $StartMenuGroup 1
- StrCmp $R0 ">" no_smgroup
-no_smgroup:
- Pop $R0
-SectionEnd
-
-; var hwndExecModeRadio
-; var hwndRunServiceNowRadio
-
-; Function mode_selection
-; nsDialogs::Create 1018
-; Pop $0
-; ${NSD_CreateLabel} 0 10 75% 20u "How would you like PurpleI2P (i2pd) to run?"
-; Pop $0
-
-; ${NSD_CreateRadioButton} 20 60 80% 25u "Service Mode"
-; Pop $hwndExecModeRadio
-; ${NSD_AddStyle} $hwndExecModeRadio ${WS_GROUP}
-
-; ${NSD_CreateRadioButton} 20 90 80% 25u "Command line Mode"
-; Pop $0
-
-; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
-; Pop $0
-; ${NSD_OnClick} $0 perform_mode
-
-; nsDialogs::Show
-; FunctionEnd
-
-; Function start_now_selection
-; nsDialogs::Create 1018
-; Pop $0
-; ${NSD_CreateLabel} 0 10 75% 20u "Enable the service now?"
-; Pop $0
-
-; ${NSD_CreateRadioButton} 20 60 80% 25u "Yes"
-; Pop $hwndRunServiceNowRadio
-; ${NSD_AddStyle} $hwndRunServiceNowRadio ${WS_GROUP}
-
-; ${NSD_CreateRadioButton} 20 90 80% 25u "No"
-; Pop $0
-
-; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
-; Pop $0
-; ${NSD_OnClick} $0 perform_mode
-
-; nsDialogs::Show
-; FunctionEnd
-
-; Function perform_mode
-; ${NSD_GetState} $hwndExecModeRadio $0
-; ${If} $0 = ${BST_CHECKED}
-; Call service_mode
-; ${EndIF}
-; FunctionEnd
-
-; Function start_now
-; ${NSD_GetState} $hwndRunServiceNowRadio $0
-; ${If} $0 = ${BST_CHECKED}
-; Call start_now_selection
-; ${EndIF}
-; FunctionEnd
-
-; Function service_mode
-; Push "create"
-; Push "PurpleI2P Service"
-; Push "$INSTDIR\i2pd.exe;autostart=1;display=PurpleI2P"
-; Call Service
-; Pop $0 ; Actually more to write than !insertmacro, but much more fun :D
-; Push "start"
-; Push "PurpleI2P Service"
-; Call Service
-; Pop $0
-; Call start_now
-; !define MUI_FINISHPAGE_RUN_NOTCHECKED
-; !define MUI_FINISHPAGE_RUN_TEXT "No need to run now since we already installed and launched it as a Windows service!"
-; FunctionEnd
-
-# Installer functions
-Function .onInit
- InitPluginsDir
- !insertmacro MUI_LANGDLL_DISPLAY
-FunctionEnd
-
-# Uninstaller functions
-Function un.onInit
- ReadRegStr $INSTDIR HKCU "${REGKEY}" Path
- !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
- !insertmacro SELECT_UNSECTION Main ${UNSEC0000}
- !insertmacro MUI_UNGETLANGUAGE
-FunctionEnd
\ No newline at end of file
diff --git a/Win32/Resource.rc b/Win32/Resource.rc
index cca1c16e..5d394d1a 100644
--- a/Win32/Resource.rc
+++ b/Win32/Resource.rc
@@ -1,73 +1,36 @@
-// Microsoft Visual C++ generated resource script.
-//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
#include "winres.h"
-
-/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-// English (United States) resources
-
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
-2 TEXTINCLUDE
+2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
-3 TEXTINCLUDE
+3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
+#endif // APSTUDIO_INVOKED
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-MAINICON ICON "mask.ico"
-//MAINICON ICON "anke.ico"
-
-#endif // English (United States) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
+MAINICON ICON "mask.ico"
+#endif // English (United States) resources
#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
#include "Resource.rc2"
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
+#endif // not APSTUDIO_INVOKED
diff --git a/Win32/Resource.rc2 b/Win32/Resource.rc2
index b001be82..6a4f481d 100644
--- a/Win32/Resource.rc2
+++ b/Win32/Resource.rc2
@@ -1,18 +1,9 @@
-//
-// Resource.RC2 - resources Microsoft Visual C++ does not edit directly
-//
-
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
#include "../libi2pd/version.h"
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH
@@ -34,7 +25,7 @@ BEGIN
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", CODENAME
- VALUE "LegalCopyright", "Copyright (C) 2013-2015, The PurpleI2P Project"
+ VALUE "LegalCopyright", "Copyright (C) 2013-2017, The PurpleI2P Project"
VALUE "OriginalFilename", "i2pd"
VALUE "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION
diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp
index 8f0f7abd..e66b5f08 100644
--- a/Win32/Win32App.cpp
+++ b/Win32/Win32App.cpp
@@ -38,7 +38,7 @@ namespace win32
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_SEPARATOR, 0, NULL);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h
index 097cb111..95cad3b5 100644
--- a/Win32/Win32Service.h
+++ b/Win32/Win32Service.h
@@ -7,10 +7,10 @@
#ifdef _WIN32
// Internal name of the service
-#define SERVICE_NAME "i2pService"
+#define SERVICE_NAME "i2pdService"
// Displayed name of the service
-#define SERVICE_DISPLAY_NAME "i2p router service"
+#define SERVICE_DISPLAY_NAME "i2pd router service"
// Service start options.
#define SERVICE_START_TYPE SERVICE_DEMAND_START
diff --git a/Win32/i2pd.sln b/Win32/i2pd.sln
deleted file mode 100644
index 4606b24b..00000000
--- a/Win32/i2pd.sln
+++ /dev/null
@@ -1,30 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.30723.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i2pd", "i2pd.vcxproj", "{930568EC-31C9-406A-AD1C-9636DF5D8FAA}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Deploy.0 = Debug|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.ActiveCfg = Debug|x64
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.Build.0 = Debug|x64
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Deploy.0 = Release|Win32
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.ActiveCfg = Release|x64
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Win32/i2pd.vcxproj b/Win32/i2pd.vcxproj
deleted file mode 100644
index 6426af09..00000000
--- a/Win32/i2pd.vcxproj
+++ /dev/null
@@ -1,292 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {930568EC-31C9-406A-AD1C-9636DF5D8FAA}
- i2pd
-
-
-
- Application
- true
- v120_xp
- NotSet
-
-
- Application
- true
- v120_xp
- NotSet
-
-
- Application
- false
- v120_xp
- true
- NotSet
-
-
- Application
- false
- v120_xp
- true
- NotSet
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ./..;$(IncludePath);$(BOOST);$(CRYPTOPP);C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\
- $(BOOST)\stage\lib;C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)
- ./..;$(VC_SourcePath);
- $(ProjectName)_d
-
-
- ./..;$(IncludePath);$(BOOST);$(CRYPTOPP)
- $(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)
- ./..;$(VC_SourcePath);
- $(ProjectName)_d
-
-
- ./..;$(IncludePath);$(BOOST);C:\build-lib\boost_1_57_0\;C:\build-lib
- C:\build-lib\boost_1_57_0\stage\lib;C:\build-lib\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)
- ./..;$(VC_SourcePath);
-
-
- ./..;$(IncludePath);$(BOOST);$(CRYPTOPP)
- $(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)
- ./..;$(VC_SourcePath);
-
-
-
- Level3
- Disabled
- true
- MultiThreadedDebug
- _MBCS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)
-
-
- true
- cryptlib.lib;%(AdditionalDependencies)
- $(OutDir)$(TargetName)$(TargetExt)
- AsInvoker
- 0.2
- Console
-
-
-
-
- Level3
- Disabled
- true
- MultiThreadedDebug
- _MBCS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
-
-
- true
- cryptlib.lib;%(AdditionalDependencies)
- $(OutDir)$(TargetName)$(TargetExt)
- AsInvoker
- 0.2
- Console
-
-
-
-
- Level2
- MaxSpeed
- true
- true
- MultiThreaded
- _WIN32_WINNT=0x0501;%(PreprocessorDefinitions)
- true
- true
-
-
- false
- true
- false
- cryptlib.lib;%(AdditionalDependencies)
- $(OutDir)$(TargetName)$(TargetExt)
- AsInvoker
-
-
- Console
- 5.01
- NoErrorReport
-
-
-
-
-
-
-
-
-
-
- Level3
- MaxSpeed
- true
- true
- MultiThreaded
- _WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
- true
- true
-
-
- false
- true
- false
- cryptlib.lib;%(AdditionalDependencies)
- $(OutDir)$(TargetName)$(TargetExt)
- AsInvoker
-
-
- Console
- 5.02
- NoErrorReport
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Win32/i2pd.vcxproj.filters b/Win32/i2pd.vcxproj.filters
deleted file mode 100644
index 4402ec7a..00000000
--- a/Win32/i2pd.vcxproj.filters
+++ /dev/null
@@ -1,302 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
- {a880a08c-16b8-4243-82ea-6bfc63bb7dab}
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Win32
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Win32
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Source Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
-
-
- Resource Files
-
-
-
\ No newline at end of file
diff --git a/Win32/ictoopie.bmp b/Win32/ictoopie.bmp
deleted file mode 100644
index c92f7c58..00000000
Binary files a/Win32/ictoopie.bmp and /dev/null differ
diff --git a/Win32/ictoopie.ico b/Win32/ictoopie.ico
deleted file mode 100644
index 077479a2..00000000
Binary files a/Win32/ictoopie.ico and /dev/null differ
diff --git a/Win32/inno_installer.iss b/Win32/inno_installer.iss
deleted file mode 100644
index 67acc431..00000000
--- a/Win32/inno_installer.iss
+++ /dev/null
@@ -1,149 +0,0 @@
-
-#define I2Pd_AppName "i2pd"
-#define I2Pd_ver "0.2"
-
-[Setup]
-AppName={#I2Pd_AppName}
-AppVersion={#I2Pd_ver}
-DefaultDirName={pf}\I2Pd
-DefaultGroupName=I2Pd
-UninstallDisplayIcon={app}\I2Pd.exe
-Compression=lzma2
-SolidCompression=yes
-OutputDir=.
-LicenseFile=.\..\LICENSE
-OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
-ArchitecturesInstallIn64BitMode=x64
-
-
-[Files]
-Source: "x64\Release\i2pd.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Check: Is64BitInstallMode
-Source: "Release\i2pd.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode
-Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; AfterInstall: ConvertLineEndings
-
-[Icons]
-Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
-Name: "{group}\Readme"; Filename: "{app}\Readme.txt"
-
-
-[Registry]
-Root: HKCU; Subkey: "Environment"; ValueName: "Path"; ValueType: "string"; ValueData: "{app};{olddata}"; Check: NotOnPathAlready(); Flags: preservestringtype;
-
-[Code]
-
-var
- DefaultTop,
- DefaultLeft,
- DefaultHeight,
- DefaultBackTop,
- DefaultNextTop,
- DefaultCancelTop,
- DefaultBevelTop,
- DefaultOuterHeight: Integer;
-
-const
- LicenseHeight = 400;
- LF = #10;
- CR = #13;
- CRLF = CR + LF;
-
-procedure ConvertLineEndings();
- var
- FilePath : String;
- FileContents : String;
-begin
- FilePath := ExpandConstant(CurrentFileName)
- LoadStringFromFile(FilePath, FileContents);
- StringChangeEx(FileContents, LF, CRLF, False);
- SaveStringToFile(FilePath, FileContents, False);
-end;
-
-procedure InitializeWizard();
-begin
- DefaultTop := WizardForm.Top;
- DefaultLeft := WizardForm.Left;
- DefaultHeight := WizardForm.Height;
- DefaultBackTop := WizardForm.BackButton.Top;
- DefaultNextTop := WizardForm.NextButton.Top;
- DefaultCancelTop := WizardForm.CancelButton.Top;
- DefaultBevelTop := WizardForm.Bevel.Top;
- DefaultOuterHeight := WizardForm.OuterNotebook.Height;
-
- WizardForm.InnerPage.Height := WizardForm.InnerPage.Height + (LicenseHeight - DefaultHeight);
- WizardForm.InnerNotebook.Height := WizardForm.InnerNotebook.Height + (LicenseHeight - DefaultHeight);
- WizardForm.LicensePage.Height := WizardForm.LicensePage.Height + (LicenseHeight - DefaultHeight);
- WizardForm.LicenseMemo.Height := WizardForm.LicenseMemo.Height + (LicenseHeight - DefaultHeight);
- WizardForm.LicenseNotAcceptedRadio.Top := WizardForm.LicenseNotAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
- WizardForm.LicenseAcceptedRadio.Top := WizardForm.LicenseAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
-
-end;
-
-procedure CurPageChanged(CurPageID: Integer);
-begin
- if CurPageID = wpLicense then
- begin
- WizardForm.Top := DefaultTop - (LicenseHeight - DefaultHeight) div 2;
- WizardForm.Height := LicenseHeight;
- WizardForm.OuterNotebook.Height := WizardForm.OuterNotebook.Height + (LicenseHeight - DefaultHeight);
- WizardForm.CancelButton.Top := DefaultCancelTop + (LicenseHeight - DefaultHeight);
- WizardForm.NextButton.Top := DefaultNextTop + (LicenseHeight - DefaultHeight);
- WizardForm.BackButton.Top := DefaultBackTop + (LicenseHeight - DefaultHeight);
- WizardForm.Bevel.Top := DefaultBevelTop + (LicenseHeight - DefaultHeight);
- end
- else
- begin
- WizardForm.Top := DefaultTop;
- WizardForm.Left := DefaultLeft;
- WizardForm.Height := DefaultHeight;
- WizardForm.OuterNotebook.Height := DefaultOuterHeight;
- WizardForm.CancelButton.Top := DefaultCancelTop;
- WizardForm.NextButton.Top := DefaultNextTop;
- WizardForm.BackButton.Top := DefaultBackTop;
- WizardForm.Bevel.Top := DefaultBevelTop;
- end;
-end;
-
-function NotOnPathAlready(): Boolean;
-var
- BinDir, Path: String;
-begin
- Log('Checking if i2pd dir is already in the %PATH%');
- if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then
- begin // Successfully read the value
- Log('HKCUEnvironmentPATH = ' + Path);
- BinDir := ExpandConstant('{app}');
- Log('Looking for i2pd dir in %PATH%: ' + BinDir + ' in ' + Path);
- if Pos(LowerCase(BinDir), Lowercase(Path)) = 0 then
- begin
- Log('Did not find i2pd dir in %PATH% so I will add it');
- Result := True;
- end
- else
- begin
- Log('Found i2pd dir in %PATH% so will not add it again');
- Result := False;
- end
- end
- else // The key probably doesn't exist
- begin
- Log('Could not access HKCUEnvironmentPATH so I assume that it is OK to add it');
- Result := True;
- end;
-end;
-
-
-procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
-var
- BinDir, Path: String;
-begin
- if (CurUninstallStep = usPostUninstall)
- and (RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path)) then
- begin
- BinDir := ExpandConstant('{app}');
- if Pos(LowerCase(BinDir) + ';', Lowercase(Path)) <> 0 then
- begin
- StringChange(Path, BinDir + ';', '');
- RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path);
- end;
- end;
-end;
diff --git a/Win32/install_service.bat b/Win32/install_service.bat
deleted file mode 100644
index b03c11b6..00000000
--- a/Win32/install_service.bat
+++ /dev/null
@@ -1 +0,0 @@
-i2pd --service=install
\ No newline at end of file
diff --git a/Win32/nsi/helper_readme.nsh b/Win32/nsi/helper_readme.nsh
deleted file mode 100644
index a3baaca1..00000000
--- a/Win32/nsi/helper_readme.nsh
+++ /dev/null
@@ -1,57 +0,0 @@
-!verbose push
-!verbose 3
-
-!ifndef _MUI_EXTRAPAGES_NSH
-!define _MUI_EXTRAPAGES_NSH
-
-!ifmacrondef MUI_EXTRAPAGE_README & MUI_PAGE_README & MUI_UNPAGE_README & ReadmeLangStrings
-
-!macro MUI_EXTRAPAGE_README UN ReadmeFile
-!verbose push
-!verbose 3
- !define MUI_PAGE_HEADER_TEXT "$(${UN}ReadmeHeader)"
- !define MUI_PAGE_HEADER_SUBTEXT "$(${UN}ReadmeSubHeader)"
- !define MUI_LICENSEPAGE_TEXT_TOP "$(${UN}ReadmeTextTop)"
- !define MUI_LICENSEPAGE_TEXT_BOTTOM "$(${UN}ReadmeTextBottom)"
- !define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
- !insertmacro MUI_${UN}PAGE_LICENSE "${ReadmeFile}"
-!verbose pop
-!macroend
-
-!define ReadmeRun "!insertmacro MUI_EXTRAPAGE_README"
-
-
-!macro MUI_PAGE_README ReadmeFile
-!verbose push
-!verbose 3
- ${ReadmeRun} "" "${ReadmeFile}"
-!verbose pop
-!macroend
-
-
-!macro MUI_UNPAGE_README ReadmeFile
-!verbose push
-!verbose 3
- ${ReadmeRun} "UN" "${ReadmeFile}"
-!verbose pop
-!macroend
-
-
-!macro ReadmeLangStrings UN MUI_LANG ReadmeHeader ReadmeSubHeader ReadmeTextTop ReadmeTextBottom
-!verbose push
-!verbose 3
- LangString ${UN}ReadmeHeader ${MUI_LANG} "${ReadmeHeader}"
- LangString ${UN}ReadmeSubHeader ${MUI_LANG} "${ReadmeSubHeader}"
- LangString ${UN}ReadmeTextTop ${MUI_LANG} "${ReadmeTextTop}"
- LangString ${UN}ReadmeTextBottom ${MUI_LANG} "${ReadmeTextBottom}"
-!verbose pop
-!macroend
-
-!define ReadmeLanguage `!insertmacro ReadmeLangStrings ""`
-
-!define Un.ReadmeLanguage `!insertmacro ReadmeLangStrings "UN"`
-
-!endif
-!endif
-
-!verbose pop
\ No newline at end of file
diff --git a/Win32/nsi/servicelib.nsh b/Win32/nsi/servicelib.nsh
deleted file mode 100644
index 7f4b5861..00000000
--- a/Win32/nsi/servicelib.nsh
+++ /dev/null
@@ -1,419 +0,0 @@
-; NSIS SERVICE LIBRARY - servicelib.nsh
-; Version 1.8.1 - Jun 21th, 2013
-; Questions/Comments - dselkirk@hotmail.com
-;
-; Description:
-; Provides an interface to window services
-;
-; Inputs:
-; action - systemlib action ie. create, delete, start, stop, pause,
-; continue, installed, running, status
-; name - name of service to manipulate
-; param - action parameters; usage: var1=value1;var2=value2;...etc.
-; (don't forget to add a ';' after the last value!)
-;
-; Actions:
-; create - creates a new windows service
-; Parameters:
-; path - path to service executable
-; autostart - automatically start with system ie. 1|0
-; interact - interact with the desktop ie. 1|0
-; depend - service dependencies
-; user - user that runs the service
-; password - password of the above user
-; display - display name in service's console
-; description - Description of service
-; starttype - start type (supersedes autostart)
-; servicetype - service type (supersedes interact)
-;
-; delete - deletes a windows service
-; start - start a stopped windows service
-; stop - stops a running windows service
-; pause - pauses a running windows service
-; continue - continues a paused windows service
-; installed - is the provided service installed
-; Parameters:
-; action - if true then invokes the specified action
-; running - is the provided service running
-; Parameters:
-; action - if true then invokes the specified action
-; status - check the status of the provided service
-;
-; Usage:
-; Method 1:
-; Push "action"
-; Push "name"
-; Push "param"
-; Call Service
-; Pop $0 ;response
-;
-; Method 2:
-; !insertmacro SERVICE "action" "name" "param"
-;
-; History:
-; 1.0 - 09/15/2003 - Initial release
-; 1.1 - 09/16/2003 - Changed &l to i, thx brainsucker
-; 1.2 - 02/29/2004 - Fixed documentation.
-; 1.3 - 01/05/2006 - Fixed interactive flag and pop order (Kichik)
-; 1.4 - 12/07/2006 - Added display and depend, fixed datatypes (Vitoco)
-; 1.5 - 06/25/2008 - Added description of service.(DeSafe.com/liuqixing#gmail.com)
-; 1.5.1 - 06/12/2009 - Added use of __UNINSTALL__
-; 1.6 - 08/02/2010 - Fixed description implementation (Anders)
-; 1.7 - 04/11/2010 - Added get running service process id (Nico)
-; 1.8 - 24/03/2011 - Added starttype and servicetype (Sergius)
-; 1.8.1 - 21/06/2013 - Added dynamic ASCII & Unicode support (Zinthose)
-
-!ifndef SERVICELIB
- !define SERVICELIB
-
- !define SC_MANAGER_ALL_ACCESS 0x3F
- !define SC_STATUS_PROCESS_INFO 0x0
- !define SERVICE_ALL_ACCESS 0xF01FF
-
- !define SERVICE_CONTROL_STOP 1
- !define SERVICE_CONTROL_PAUSE 2
- !define SERVICE_CONTROL_CONTINUE 3
-
- !define SERVICE_STOPPED 0x1
- !define SERVICE_START_PENDING 0x2
- !define SERVICE_STOP_PENDING 0x3
- !define SERVICE_RUNNING 0x4
- !define SERVICE_CONTINUE_PENDING 0x5
- !define SERVICE_PAUSE_PENDING 0x6
- !define SERVICE_PAUSED 0x7
-
- !define SERVICE_KERNEL_DRIVER 0x00000001
- !define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
- !define SERVICE_WIN32_OWN_PROCESS 0x00000010
- !define SERVICE_WIN32_SHARE_PROCESS 0x00000020
- !define SERVICE_INTERACTIVE_PROCESS 0x00000100
-
-
- !define SERVICE_BOOT_START 0x00000000
- !define SERVICE_SYSTEM_START 0x00000001
- !define SERVICE_AUTO_START 0x00000002
- !define SERVICE_DEMAND_START 0x00000003
- !define SERVICE_DISABLED 0x00000004
-
- ## Added by Zinthose for Native Unicode Support
- !ifdef NSIS_UNICODE
- !define APITAG "W"
- !else
- !define APITAG "A"
- !endif
-
- !macro SERVICE ACTION NAME PARAM
- Push '${ACTION}'
- Push '${NAME}'
- Push '${PARAM}'
- !ifdef __UNINSTALL__
- Call un.Service
- !else
- Call Service
- !endif
- !macroend
-
- !macro FUNC_GETPARAM
- Push $0
- Push $1
- Push $2
- Push $3
- Push $4
- Push $5
- Push $6
- Push $7
- Exch 8
- Pop $1 ;name
- Exch 8
- Pop $2 ;source
- StrCpy $0 ""
- StrLen $7 $2
- StrCpy $3 0
- lbl_loop:
- IntCmp $3 $7 0 0 lbl_done
- StrLen $4 "$1="
- StrCpy $5 $2 $4 $3
- StrCmp $5 "$1=" 0 lbl_next
- IntOp $5 $3 + $4
- StrCpy $3 $5
- lbl_loop2:
- IntCmp $3 $7 0 0 lbl_done
- StrCpy $6 $2 1 $3
- StrCmp $6 ";" 0 lbl_next2
- IntOp $6 $3 - $5
- StrCpy $0 $2 $6 $5
- Goto lbl_done
- lbl_next2:
- IntOp $3 $3 + 1
- Goto lbl_loop2
- lbl_next:
- IntOp $3 $3 + 1
- Goto lbl_loop
- lbl_done:
- Pop $5
- Pop $4
- Pop $3
- Pop $2
- Pop $1
- Exch 2
- Pop $6
- Pop $7
- Exch $0
- !macroend
-
- !macro CALL_GETPARAM VAR NAME DEFAULT LABEL
- Push $1
- Push ${NAME}
- Call ${UN}GETPARAM
- Pop $6
- StrCpy ${VAR} "${DEFAULT}"
- StrCmp $6 "" "${LABEL}" 0
- StrCpy ${VAR} $6
- !macroend
-
- !macro FUNC_SERVICE UN
- Push $0
- Push $1
- Push $2
- Push $3
- Push $4
- Push $5
- Push $6
- Push $7
- Exch 8
- Pop $1 ;param
- Exch 8
- Pop $2 ;name
- Exch 8
- Pop $3 ;action
- ;$0 return
- ;$4 OpenSCManager
- ;$5 OpenService
-
- StrCpy $0 "false"
- System::Call 'advapi32::OpenSCManager${APITAG}(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.r4'
- IntCmp $4 0 lbl_done
- StrCmp $3 "create" lbl_create
- System::Call 'advapi32::OpenService${APITAG}(i r4, t r2, i ${SERVICE_ALL_ACCESS}) i.r5'
- IntCmp $5 0 lbl_done
-
- lbl_select:
- StrCmp $3 "delete" lbl_delete
- StrCmp $3 "start" lbl_start
- StrCmp $3 "stop" lbl_stop
- StrCmp $3 "pause" lbl_pause
- StrCmp $3 "continue" lbl_continue
- StrCmp $3 "installed" lbl_installed
- StrCmp $3 "running" lbl_running
- StrCmp $3 "status" lbl_status
- StrCmp $3 "processid" lbl_processid
- Goto lbl_done
-
- ; create service
- lbl_create:
- Push $R1 ;depend
- Push $R2 ;user
- Push $R3 ;password
- Push $R4 ;servicetype/interact
- Push $R5 ;starttype/autostart
- Push $R6 ;path
- Push $R7 ;display
- Push $R8 ;description
-
- !insertmacro CALL_GETPARAM $R1 "depend" "n" "lbl_depend"
- StrCpy $R1 't "$R1"'
- lbl_depend:
- StrCmp $R1 "n" 0 lbl_machine ;old name of depend param
- !insertmacro CALL_GETPARAM $R1 "machine" "n" "lbl_machine"
- StrCpy $R1 't "$R1"'
- lbl_machine:
-
- !insertmacro CALL_GETPARAM $R2 "user" "n" "lbl_user"
- StrCpy $R2 't "$R2"'
- lbl_user:
-
- !insertmacro CALL_GETPARAM $R3 "password" "n" "lbl_password"
- StrCpy $R3 't "$R3"'
- lbl_password:
-
- !insertmacro CALL_GETPARAM $R4 "interact" "${SERVICE_WIN32_OWN_PROCESS}" "lbl_interact"
- StrCpy $6 ${SERVICE_WIN32_OWN_PROCESS}
- IntCmp $R4 0 +2
- IntOp $6 $6 | ${SERVICE_INTERACTIVE_PROCESS}
- StrCpy $R4 $6
- lbl_interact:
-
- !insertmacro CALL_GETPARAM $R4 "servicetype" "$R4" "lbl_servicetype"
- lbl_servicetype:
-
- !insertmacro CALL_GETPARAM $R5 "autostart" "${SERVICE_DEMAND_START}" "lbl_autostart"
- StrCpy $6 ${SERVICE_DEMAND_START}
- IntCmp $R5 0 +2
- StrCpy $6 ${SERVICE_AUTO_START}
- StrCpy $R5 $6
- lbl_autostart:
-
- !insertmacro CALL_GETPARAM $R5 "starttype" "$R5" "lbl_starttype"
- lbl_starttype:
-
- !insertmacro CALL_GETPARAM $R6 "path" "n" "lbl_path"
- lbl_path:
-
- !insertmacro CALL_GETPARAM $R7 "display" "$2" "lbl_display"
- lbl_display:
-
- !insertmacro CALL_GETPARAM $R8 "description" "$2" "lbl_description"
- lbl_description:
-
- System::Call 'advapi32::CreateService${APITAG}(i r4, t r2, t R7, i ${SERVICE_ALL_ACCESS}, \
- i R4, i R5, i 0, t R6, n, n, $R1, $R2, $R3) i.r6'
-
- ; write description of service (SERVICE_CONFIG_DESCRIPTION)
- System::Call 'advapi32::ChangeServiceConfig2${APITAG}(ir6,i1,*t "$R8")i.R7'
- strcmp $R7 "error" 0 lbl_descriptioncomplete
- WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\$2" "Description" $R8
- lbl_descriptioncomplete:
-
- Pop $R8
- Pop $R7
- Pop $R6
- Pop $R5
- Pop $R4
- Pop $R3
- Pop $R2
- Pop $R1
- StrCmp $6 0 lbl_done lbl_good
-
- ; delete service
- lbl_delete:
- System::Call 'advapi32::DeleteService(i r5) i.r6'
- StrCmp $6 0 lbl_done lbl_good
-
- ; start service
- lbl_start:
- System::Call 'advapi32::StartService${APITAG}(i r5, i 0, i 0) i.r6'
- StrCmp $6 0 lbl_done lbl_good
-
- ; stop service
- lbl_stop:
- Push $R1
- System::Call '*(i,i,i,i,i,i,i) i.R1'
- System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_STOP}, i $R1) i'
- System::Free $R1
- Pop $R1
- StrCmp $6 0 lbl_done lbl_good
-
- ; pause service
- lbl_pause:
- Push $R1
- System::Call '*(i,i,i,i,i,i,i) i.R1'
- System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_PAUSE}, i $R1) i'
- System::Free $R1
- Pop $R1
- StrCmp $6 0 lbl_done lbl_good
-
- ; continue service
- lbl_continue:
- Push $R1
- System::Call '*(i,i,i,i,i,i,i) i.R1'
- System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_CONTINUE}, i $R1) i'
- System::Free $R1
- Pop $R1
- StrCmp $6 0 lbl_done lbl_good
-
- ; is installed
- lbl_installed:
- !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
- StrCpy $3 $7
- Goto lbl_select
-
- ; is service running
- lbl_running:
- Push $R1
- System::Call '*(i,i,i,i,i,i,i) i.R1'
- System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
- System::Call '*$R1(i, i.r6)'
- System::Free $R1
- Pop $R1
- IntFmt $6 "0x%X" $6
- StrCmp $6 ${SERVICE_RUNNING} 0 lbl_done
- !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
- StrCpy $3 $7
- Goto lbl_select
-
- lbl_status:
- Push $R1
- System::Call '*(i,i,i,i,i,i,i) i.R1'
- System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
- System::Call '*$R1(i, i .r6)'
- System::Free $R1
- Pop $R1
- IntFmt $6 "0x%X" $6
- StrCpy $0 "running"
- IntCmp $6 ${SERVICE_RUNNING} lbl_done
- StrCpy $0 "stopped"
- IntCmp $6 ${SERVICE_STOPPED} lbl_done
- StrCpy $0 "start_pending"
- IntCmp $6 ${SERVICE_START_PENDING} lbl_done
- StrCpy $0 "stop_pending"
- IntCmp $6 ${SERVICE_STOP_PENDING} lbl_done
- StrCpy $0 "running"
- IntCmp $6 ${SERVICE_RUNNING} lbl_done
- StrCpy $0 "continue_pending"
- IntCmp $6 ${SERVICE_CONTINUE_PENDING} lbl_done
- StrCpy $0 "pause_pending"
- IntCmp $6 ${SERVICE_PAUSE_PENDING} lbl_done
- StrCpy $0 "paused"
- IntCmp $6 ${SERVICE_PAUSED} lbl_done
- StrCpy $0 "unknown"
- Goto lbl_done
-
- lbl_processid:
- Push $R1
- Push $R2
- System::Call '*(i,i,i,i,i,i,i,i,i) i.R1'
- System::Call '*(i 0) i.R2'
- System::Call "advapi32::QueryServiceStatusEx(i r5, i ${SC_STATUS_PROCESS_INFO}, i $R1, i 36, i $R2) i"
- System::Call "*$R1(i,i,i,i,i,i,i, i .r0)"
- System::Free $R2
- System::Free $R1
- Pop $R2
- Pop $R1
- Goto lbl_done
-
- lbl_good:
- StrCpy $0 "true"
- lbl_done:
- IntCmp $5 0 +2
- System::Call 'advapi32::CloseServiceHandle(i r5) n'
- IntCmp $4 0 +2
- System::Call 'advapi32::CloseServiceHandle(i r4) n'
- Pop $4
- Pop $3
- Pop $2
- Pop $1
- Exch 3
- Pop $5
- Pop $7
- Pop $6
- Exch $0
- !macroend
-
- Function Service
- !insertmacro FUNC_SERVICE ""
- FunctionEnd
-
- Function un.Service
- !insertmacro FUNC_SERVICE "un."
- FunctionEnd
-
- Function GetParam
- !insertmacro FUNC_GETPARAM
- FunctionEnd
-
- Function un.GetParam
- !insertmacro FUNC_GETPARAM
- FunctionEnd
-
- !undef APITAG
-!endif
\ No newline at end of file
diff --git a/Win32/resource.h b/Win32/resource.h
index a8309c8b..3b188481 100644
--- a/Win32/resource.h
+++ b/Win32/resource.h
@@ -1,16 +1,11 @@
//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by Resource.rc
-//
-#define MAINICON 101
+#define MAINICON 101
-// Next default values for new objects
-//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 102
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/Win32/uninstall_service.bat b/Win32/uninstall_service.bat
deleted file mode 100644
index 0289c24a..00000000
--- a/Win32/uninstall_service.bat
+++ /dev/null
@@ -1 +0,0 @@
-i2pd --service=remove
\ No newline at end of file
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index 8c78e88b..0b8bef38 100755
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -2,6 +2,8 @@
i2pd
i2pd started
+ i2pd service started
+ i2pd service stopped
Quit
Graceful Quit
Graceful quit is already in progress
diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java
index 5e0ac4d0..e1ebc269 100644
--- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java
+++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java
@@ -8,20 +8,20 @@ import android.util.Log;
public class DaemonSingleton {
private static final String TAG="i2pd";
private static final DaemonSingleton instance = new DaemonSingleton();
- public static interface StateChangeListener { void daemonStateChanged(); }
- private final Set stateChangeListeners = new HashSet();
+ public static interface StateUpdateListener { void daemonStateUpdate(); }
+ private final Set stateUpdateListeners = new HashSet();
public static DaemonSingleton getInstance() {
return instance;
}
- public synchronized void addStateChangeListener(StateChangeListener listener) { stateChangeListeners.add(listener); }
- public synchronized void removeStateChangeListener(StateChangeListener listener) { stateChangeListeners.remove(listener); }
+ public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
+ public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
public synchronized void stopAcceptingTunnels() {
if(isStartedOkay()){
state=State.gracefulShutdownInProgress;
- fireStateChange();
+ fireStateUpdate();
I2PD_JNI.stopAcceptingTunnels();
}
}
@@ -32,61 +32,63 @@ public class DaemonSingleton {
private boolean startedOkay;
- public static enum State {starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress};
+ public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress};
- private State state = State.starting;
+ private State state = State.uninitialized;
public State getState() { return state; }
- {
- synchronized(this){
- fireStateChange();
- new Thread(new Runnable(){
-
- @Override
- public void run() {
- try {
- I2PD_JNI.loadLibraries();
- synchronized (DaemonSingleton.this) {
- state = State.jniLibraryLoaded;
- fireStateChange();
- }
- } catch (Throwable tr) {
- lastThrowable=tr;
- synchronized (DaemonSingleton.this) {
- state = State.startFailed;
- fireStateChange();
- }
- return;
+ public synchronized void start() {
+ if(state != State.uninitialized)return;
+ state = State.starting;
+ fireStateUpdate();
+ new Thread(new Runnable(){
+
+ @Override
+ public void run() {
+ try {
+ I2PD_JNI.loadLibraries();
+ synchronized (DaemonSingleton.this) {
+ state = State.jniLibraryLoaded;
+ fireStateUpdate();
}
- try {
- synchronized (DaemonSingleton.this) {
- daemonStartResult = I2PD_JNI.startDaemon();
- if("ok".equals(daemonStartResult)){state=State.startedOkay;setStartedOkay(true);}
- else state=State.startFailed;
- fireStateChange();
- }
- } catch (Throwable tr) {
- lastThrowable=tr;
- synchronized (DaemonSingleton.this) {
- state = State.startFailed;
- fireStateChange();
- }
- return;
- }
+ } catch (Throwable tr) {
+ lastThrowable=tr;
+ synchronized (DaemonSingleton.this) {
+ state = State.startFailed;
+ fireStateUpdate();
+ }
+ return;
}
-
- }, "i2pdDaemonStart").start();
- }
+ try {
+ synchronized (DaemonSingleton.this) {
+ daemonStartResult = I2PD_JNI.startDaemon();
+ if("ok".equals(daemonStartResult)){
+ state=State.startedOkay;
+ setStartedOkay(true);
+ }else state=State.startFailed;
+ fireStateUpdate();
+ }
+ } catch (Throwable tr) {
+ lastThrowable=tr;
+ synchronized (DaemonSingleton.this) {
+ state = State.startFailed;
+ fireStateUpdate();
+ }
+ return;
+ }
+ }
+
+ }, "i2pdDaemonStart").start();
}
private Throwable lastThrowable;
private String daemonStartResult="N/A";
- private synchronized void fireStateChange() {
+ private synchronized void fireStateUpdate() {
Log.i(TAG, "daemon state change: "+state);
- for(StateChangeListener listener : stateChangeListeners) {
+ for(StateUpdateListener listener : stateUpdateListeners) {
try {
- listener.daemonStateChanged();
+ listener.daemonStateUpdate();
} catch (Throwable tr) {
Log.e(TAG, "exception in listener ignored", tr);
}
diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java
index 16155651..d25d0a88 100644
--- a/android/src/org/purplei2p/i2pd/ForegroundService.java
+++ b/android/src/org/purplei2p/i2pd/ForegroundService.java
@@ -1,15 +1,17 @@
package org.purplei2p.i2pd;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
+import android.widget.Toast;
public class ForegroundService extends Service {
-// private NotificationManager mNM;
+ private NotificationManager notificationManager;
// Unique Identification Number for the Notification.
// We use it on Notification start, and to cancel it.
@@ -28,26 +30,31 @@ public class ForegroundService extends Service {
@Override
public void onCreate() {
-// mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Display a notification about us starting. We put an icon in the status bar.
showNotification();
+ daemon.start();
+ // Tell the user we started.
+ Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
- return START_NOT_STICKY;
+ daemon.start();
+ return START_STICKY;
}
@Override
public void onDestroy() {
// Cancel the persistent notification.
- //mNM.cancel(NOTIFICATION);
+ notificationManager.cancel(NOTIFICATION);
+
stopForeground(true);
// Tell the user we stopped.
- //Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
}
@Override
@@ -84,4 +91,7 @@ public class ForegroundService extends Service {
//mNM.notify(NOTIFICATION, notification);
startForeground(NOTIFICATION, notification);
}
+
+ private final DaemonSingleton daemon = DaemonSingleton.getInstance();
}
+
diff --git a/android/src/org/purplei2p/i2pd/I2PD.java b/android/src/org/purplei2p/i2pd/I2PD.java
index 0397cf03..86b877ac 100755
--- a/android/src/org/purplei2p/i2pd/I2PD.java
+++ b/android/src/org/purplei2p/i2pd/I2PD.java
@@ -22,12 +22,16 @@ import android.widget.Toast;
public class I2PD extends Activity {
private static final String TAG = "i2pd";
- private DaemonSingleton daemon = DaemonSingleton.getInstance();
- private DaemonSingleton.StateChangeListener daemonStateChangeListener =
- new DaemonSingleton.StateChangeListener() {
+
+ private TextView textView;
+
+ private final DaemonSingleton daemon = DaemonSingleton.getInstance();
+
+ private DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
+ new DaemonSingleton.StateUpdateListener() {
@Override
- public void daemonStateChanged() {
+ public void daemonStateUpdate() {
runOnUiThread(new Runnable(){
@Override
@@ -50,19 +54,17 @@ public class I2PD extends Activity {
}
};
- private TextView textView;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //set the app be foreground (do not unload when RAM needed)
- doBindService();
-
textView = new TextView(this);
setContentView(textView);
- daemonStateChangeListener.daemonStateChanged();
- daemon.addStateChangeListener(daemonStateChangeListener);
+ DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
+ daemonStateUpdatedListener.daemonStateUpdate();
+
+ //set the app be foreground
+ doBindService();
}
@Override
@@ -73,7 +75,7 @@ public class I2PD extends Activity {
private void localDestroy() {
textView = null;
- daemon.removeStateChangeListener(daemonStateChangeListener);
+ DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener);
Timer gracefulQuitTimer = getGracefulQuitTimer();
if(gracefulQuitTimer!=null) {
gracefulQuitTimer.cancel();
diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd
index 022df45e..6c7407f1 100644
--- a/build/build_mingw.cmd
+++ b/build/build_mingw.cmd
@@ -33,6 +33,8 @@ FOR /F "usebackq" %%a IN (`%WD%bash -lc 'git describe --tags'`) DO (
set tag=%%a
)
+"%WD%bash" -lc "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
+
REM starting building
set MSYSTEM=MINGW32
set bitness=32
@@ -44,6 +46,8 @@ set bitness=64
call :BUILDING
echo.
+del README.txt >> nul
+
echo Build complete...
pause
exit /b 0
@@ -51,12 +55,12 @@ exit /b 0
:BUILDING
echo Building i2pd %tag% for win%bitness%:
echo Build AVX+AESNI...
-"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
+"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
echo Build AVX...
-"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe && make clean" > build/build_win%bitness%_avx.log 2>&1
+"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx.log 2>&1
echo Build AESNI...
-"%WD%bash" -lc "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_aesni.log 2>&1
+"%WD%bash" -lc "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_aesni.log 2>&1
echo Build without extensions...
-"%WD%bash" -lc "make USE_UPNP=yes -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe && make clean" > build/build_win%bitness%.log 2>&1
+"%WD%bash" -lc "make USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%.log 2>&1
:EOF
\ No newline at end of file
diff --git a/build/cmake_modules/NSIS.template.in b/build/cmake_modules/NSIS.template.in
deleted file mode 100644
index f7d5a7f7..00000000
--- a/build/cmake_modules/NSIS.template.in
+++ /dev/null
@@ -1,978 +0,0 @@
-; CPack install script designed for a nmake build
-
-;--------------------------------
-; You must define these values
-
- !define VERSION "@CPACK_PACKAGE_VERSION@"
- !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@"
- !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"
-
-;--------------------------------
-;Variables
-
- Var MUI_TEMP
- Var STARTMENU_FOLDER
- Var SV_ALLUSERS
- Var START_MENU
- Var DO_NOT_ADD_TO_PATH
- Var ADD_TO_PATH_ALL_USERS
- Var ADD_TO_PATH_CURRENT_USER
- Var INSTALL_DESKTOP
- Var IS_DEFAULT_INSTALLDIR
-;--------------------------------
-;Include Modern UI
-
- !include "MUI.nsh"
-
- ;Default installation folder
- InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
-
-;--------------------------------
-;General
-
- ;Name and file
- Name "@CPACK_NSIS_PACKAGE_NAME@"
- OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
-
- ;Set compression
- SetCompressor @CPACK_NSIS_COMPRESSOR@
-
- ;Require administrator access
- RequestExecutionLevel admin
-
-@CPACK_NSIS_DEFINES@
-
- !include Sections.nsh
-
-;--- Component support macros: ---
-; The code for the add/remove functionality is from:
-; http://nsis.sourceforge.net/Add/Remove_Functionality
-; It has been modified slightly and extended to provide
-; inter-component dependencies.
-Var AR_SecFlags
-Var AR_RegFlags
-@CPACK_NSIS_SECTION_SELECTED_VARS@
-
-; Loads the "selected" flag for the section named SecName into the
-; variable VarName.
-!macro LoadSectionSelectedIntoVar SecName VarName
- SectionGetFlags ${${SecName}} $${VarName}
- IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits
-!macroend
-
-; Loads the value of a variable... can we get around this?
-!macro LoadVar VarName
- IntOp $R0 0 + $${VarName}
-!macroend
-
-; Sets the value of a variable
-!macro StoreVar VarName IntValue
- IntOp $${VarName} 0 + ${IntValue}
-!macroend
-
-!macro InitSection SecName
- ; This macro reads component installed flag from the registry and
- ;changes checked state of the section on the components page.
- ;Input: section index constant name specified in Section command.
-
- ClearErrors
- ;Reading component status from registry
- ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed"
- IfErrors "default_${SecName}"
- ;Status will stay default if registry value not found
- ;(component was never installed)
- IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits
- SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags
- IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off
- IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit
-
- ; Note whether this component was installed before
- !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags
- IntOp $R0 $AR_RegFlags & $AR_RegFlags
-
- ;Writing modified flags
- SectionSetFlags ${${SecName}} $AR_SecFlags
-
- "default_${SecName}:"
- !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
-!macroend
-
-!macro FinishSection SecName
- ; This macro reads section flag set by user and removes the section
- ;if it is not selected.
- ;Then it writes component installed flag to registry
- ;Input: section index constant name specified in Section command.
-
- SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags
- ;Checking lowest bit:
- IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED}
- IntCmp $AR_SecFlags 1 "leave_${SecName}"
- ;Section is not selected:
- ;Calling Section uninstall macro and writing zero installed flag
- !insertmacro "Remove_${${SecName}}"
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
- "Installed" 0
- Goto "exit_${SecName}"
-
- "leave_${SecName}:"
- ;Section is selected:
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
- "Installed" 1
-
- "exit_${SecName}:"
-!macroend
-
-!macro RemoveSection_CPack SecName
- ; This macro is used to call section's Remove_... macro
- ;from the uninstaller.
- ;Input: section index constant name specified in Section command.
-
- !insertmacro "Remove_${${SecName}}"
-!macroend
-
-; Determine whether the selection of SecName changed
-!macro MaybeSelectionChanged SecName
- !insertmacro LoadVar ${SecName}_selected
- SectionGetFlags ${${SecName}} $R1
- IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits
-
- ; See if the status has changed:
- IntCmp $R0 $R1 "${SecName}_unchanged"
- !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
-
- IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected"
- !insertmacro "Deselect_required_by_${SecName}"
- goto "${SecName}_unchanged"
-
- "${SecName}_was_selected:"
- !insertmacro "Select_${SecName}_depends"
-
- "${SecName}_unchanged:"
-!macroend
-;--- End of Add/Remove macros ---
-
-;--------------------------------
-;Interface Settings
-
- !define MUI_HEADERIMAGE
- !define MUI_ABORTWARNING
-
-;--------------------------------
-; path functions
-
-!verbose 3
-!include "WinMessages.NSH"
-!verbose 4
-
-;----------------------------------------
-; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02"
-;----------------------------------------
-!verbose 3
-!include "WinMessages.NSH"
-!verbose 4
-;====================================================
-; get_NT_environment
-; Returns: the selected environment
-; Output : head of the stack
-;====================================================
-!macro select_NT_profile UN
-Function ${UN}select_NT_profile
- StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single
- DetailPrint "Selected environment for all users"
- Push "all"
- Return
- environment_single:
- DetailPrint "Selected environment for current user only."
- Push "current"
- Return
-FunctionEnd
-!macroend
-!insertmacro select_NT_profile ""
-!insertmacro select_NT_profile "un."
-;----------------------------------------------------
-!define NT_current_env 'HKCU "Environment"'
-!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
-
-!ifndef WriteEnvStr_RegKey
- !ifdef ALL_USERS
- !define WriteEnvStr_RegKey \
- 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
- !else
- !define WriteEnvStr_RegKey 'HKCU "Environment"'
- !endif
-!endif
-
-; AddToPath - Adds the given dir to the search path.
-; Input - head of the stack
-; Note - Win9x systems requires reboot
-
-Function AddToPath
- Exch $0
- Push $1
- Push $2
- Push $3
-
- # don't add if the path doesn't exist
- IfFileExists "$0\*.*" "" AddToPath_done
-
- ReadEnvStr $1 PATH
- ; if the path is too long for a NSIS variable NSIS will return a 0
- ; length string. If we find that, then warn and skip any path
- ; modification as it will trash the existing path.
- StrLen $2 $1
- IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done
- CheckPathLength_ShowPathWarning:
- Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!"
- Goto AddToPath_done
- CheckPathLength_Done:
- Push "$1;"
- Push "$0;"
- Call StrStr
- Pop $2
- StrCmp $2 "" "" AddToPath_done
- Push "$1;"
- Push "$0\;"
- Call StrStr
- Pop $2
- StrCmp $2 "" "" AddToPath_done
- GetFullPathName /SHORT $3 $0
- Push "$1;"
- Push "$3;"
- Call StrStr
- Pop $2
- StrCmp $2 "" "" AddToPath_done
- Push "$1;"
- Push "$3\;"
- Call StrStr
- Pop $2
- StrCmp $2 "" "" AddToPath_done
-
- Call IsNT
- Pop $1
- StrCmp $1 1 AddToPath_NT
- ; Not on NT
- StrCpy $1 $WINDIR 2
- FileOpen $1 "$1\autoexec.bat" a
- FileSeek $1 -1 END
- FileReadByte $1 $2
- IntCmp $2 26 0 +2 +2 # DOS EOF
- FileSeek $1 -1 END # write over EOF
- FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
- FileClose $1
- SetRebootFlag true
- Goto AddToPath_done
-
- AddToPath_NT:
- StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey
- ReadRegStr $1 ${NT_current_env} "PATH"
- Goto DoTrim
- ReadAllKey:
- ReadRegStr $1 ${NT_all_env} "PATH"
- DoTrim:
- StrCmp $1 "" AddToPath_NTdoIt
- Push $1
- Call Trim
- Pop $1
- StrCpy $0 "$1;$0"
- AddToPath_NTdoIt:
- StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey
- WriteRegExpandStr ${NT_current_env} "PATH" $0
- Goto DoSend
- WriteAllKey:
- WriteRegExpandStr ${NT_all_env} "PATH" $0
- DoSend:
- SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-
- AddToPath_done:
- Pop $3
- Pop $2
- Pop $1
- Pop $0
-FunctionEnd
-
-
-; RemoveFromPath - Remove a given dir from the path
-; Input: head of the stack
-
-Function un.RemoveFromPath
- Exch $0
- Push $1
- Push $2
- Push $3
- Push $4
- Push $5
- Push $6
-
- IntFmt $6 "%c" 26 # DOS EOF
-
- Call un.IsNT
- Pop $1
- StrCmp $1 1 unRemoveFromPath_NT
- ; Not on NT
- StrCpy $1 $WINDIR 2
- FileOpen $1 "$1\autoexec.bat" r
- GetTempFileName $4
- FileOpen $2 $4 w
- GetFullPathName /SHORT $0 $0
- StrCpy $0 "SET PATH=%PATH%;$0"
- Goto unRemoveFromPath_dosLoop
-
- unRemoveFromPath_dosLoop:
- FileRead $1 $3
- StrCpy $5 $3 1 -1 # read last char
- StrCmp $5 $6 0 +2 # if DOS EOF
- StrCpy $3 $3 -1 # remove DOS EOF so we can compare
- StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
- StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
- StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
- StrCmp $3 "" unRemoveFromPath_dosLoopEnd
- FileWrite $2 $3
- Goto unRemoveFromPath_dosLoop
- unRemoveFromPath_dosLoopRemoveLine:
- SetRebootFlag true
- Goto unRemoveFromPath_dosLoop
-
- unRemoveFromPath_dosLoopEnd:
- FileClose $2
- FileClose $1
- StrCpy $1 $WINDIR 2
- Delete "$1\autoexec.bat"
- CopyFiles /SILENT $4 "$1\autoexec.bat"
- Delete $4
- Goto unRemoveFromPath_done
-
- unRemoveFromPath_NT:
- StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey
- ReadRegStr $1 ${NT_current_env} "PATH"
- Goto unDoTrim
- unReadAllKey:
- ReadRegStr $1 ${NT_all_env} "PATH"
- unDoTrim:
- StrCpy $5 $1 1 -1 # copy last char
- StrCmp $5 ";" +2 # if last char != ;
- StrCpy $1 "$1;" # append ;
- Push $1
- Push "$0;"
- Call un.StrStr ; Find `$0;` in $1
- Pop $2 ; pos of our dir
- StrCmp $2 "" unRemoveFromPath_done
- ; else, it is in path
- # $0 - path to add
- # $1 - path var
- StrLen $3 "$0;"
- StrLen $4 $2
- StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
- StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
- StrCpy $3 $5$6
-
- StrCpy $5 $3 1 -1 # copy last char
- StrCmp $5 ";" 0 +2 # if last char == ;
- StrCpy $3 $3 -1 # remove last char
-
- StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey
- WriteRegExpandStr ${NT_current_env} "PATH" $3
- Goto unDoSend
- unWriteAllKey:
- WriteRegExpandStr ${NT_all_env} "PATH" $3
- unDoSend:
- SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-
- unRemoveFromPath_done:
- Pop $6
- Pop $5
- Pop $4
- Pop $3
- Pop $2
- Pop $1
- Pop $0
-FunctionEnd
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Uninstall sutff
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-###########################################
-# Utility Functions #
-###########################################
-
-;====================================================
-; IsNT - Returns 1 if the current system is NT, 0
-; otherwise.
-; Output: head of the stack
-;====================================================
-; IsNT
-; no input
-; output, top of the stack = 1 if NT or 0 if not
-;
-; Usage:
-; Call IsNT
-; Pop $R0
-; ($R0 at this point is 1 or 0)
-
-!macro IsNT un
-Function ${un}IsNT
- Push $0
- ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
- StrCmp $0 "" 0 IsNT_yes
- ; we are not NT.
- Pop $0
- Push 0
- Return
-
- IsNT_yes:
- ; NT!!!
- Pop $0
- Push 1
-FunctionEnd
-!macroend
-!insertmacro IsNT ""
-!insertmacro IsNT "un."
-
-; StrStr
-; input, top of stack = string to search for
-; top of stack-1 = string to search in
-; output, top of stack (replaces with the portion of the string remaining)
-; modifies no other variables.
-;
-; Usage:
-; Push "this is a long ass string"
-; Push "ass"
-; Call StrStr
-; Pop $R0
-; ($R0 at this point is "ass string")
-
-!macro StrStr un
-Function ${un}StrStr
-Exch $R1 ; st=haystack,old$R1, $R1=needle
- Exch ; st=old$R1,haystack
- Exch $R2 ; st=old$R1,old$R2, $R2=haystack
- Push $R3
- Push $R4
- Push $R5
- StrLen $R3 $R1
- StrCpy $R4 0
- ; $R1=needle
- ; $R2=haystack
- ; $R3=len(needle)
- ; $R4=cnt
- ; $R5=tmp
- loop:
- StrCpy $R5 $R2 $R3 $R4
- StrCmp $R5 $R1 done
- StrCmp $R5 "" done
- IntOp $R4 $R4 + 1
- Goto loop
-done:
- StrCpy $R1 $R2 "" $R4
- Pop $R5
- Pop $R4
- Pop $R3
- Pop $R2
- Exch $R1
-FunctionEnd
-!macroend
-!insertmacro StrStr ""
-!insertmacro StrStr "un."
-
-Function Trim ; Added by Pelaca
- Exch $R1
- Push $R2
-Loop:
- StrCpy $R2 "$R1" 1 -1
- StrCmp "$R2" " " RTrim
- StrCmp "$R2" "$\n" RTrim
- StrCmp "$R2" "$\r" RTrim
- StrCmp "$R2" ";" RTrim
- GoTo Done
-RTrim:
- StrCpy $R1 "$R1" -1
- Goto Loop
-Done:
- Pop $R2
- Exch $R1
-FunctionEnd
-
-Function ConditionalAddToRegisty
- Pop $0
- Pop $1
- StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
- WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
- "$1" "$0"
- ;MessageBox MB_OK "Set Registry: '$1' to '$0'"
- DetailPrint "Set install registry entry: '$1' to '$0'"
- ConditionalAddToRegisty_EmptyString:
-FunctionEnd
-
-;--------------------------------
-
-!ifdef CPACK_USES_DOWNLOAD
-Function DownloadFile
- IfFileExists $INSTDIR\* +2
- CreateDirectory $INSTDIR
- Pop $0
-
- ; Skip if already downloaded
- IfFileExists $INSTDIR\$0 0 +2
- Return
-
- StrCpy $1 "@CPACK_DOWNLOAD_SITE@"
-
- try_again:
- NSISdl::download "$1/$0" "$INSTDIR\$0"
-
- Pop $1
- StrCmp $1 "success" success
- StrCmp $1 "Cancelled" cancel
- MessageBox MB_OK "Download failed: $1"
- cancel:
- Return
- success:
-FunctionEnd
-!endif
-
-;--------------------------------
-; Installation types
-@CPACK_NSIS_INSTALLATION_TYPES@
-
-;--------------------------------
-; Component sections
-@CPACK_NSIS_COMPONENT_SECTIONS@
-
-;--------------------------------
-; Define some macro setting for the gui
-@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
-@CPACK_NSIS_INSTALLER_ICON_CODE@
-@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@
-@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@
-
-;--------------------------------
-;Pages
- !insertmacro MUI_PAGE_WELCOME
-
- !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
- Page custom InstallOptionsPage
- !insertmacro MUI_PAGE_DIRECTORY
-
- ;Start Menu Folder Page Configuration
- !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
- !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
- !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
- !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Purple I2P"
- !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
-
- @CPACK_NSIS_PAGE_COMPONENTS@
-
- !insertmacro MUI_PAGE_INSTFILES
- !insertmacro MUI_PAGE_FINISH
-
- !insertmacro MUI_UNPAGE_CONFIRM
- !insertmacro MUI_UNPAGE_INSTFILES
-
-;--------------------------------
-;Languages
-
- !insertmacro MUI_LANGUAGE "English" ;first language is the default language
- !insertmacro MUI_LANGUAGE "Albanian"
- !insertmacro MUI_LANGUAGE "Arabic"
- !insertmacro MUI_LANGUAGE "Basque"
- !insertmacro MUI_LANGUAGE "Belarusian"
- !insertmacro MUI_LANGUAGE "Bosnian"
- !insertmacro MUI_LANGUAGE "Breton"
- !insertmacro MUI_LANGUAGE "Bulgarian"
- !insertmacro MUI_LANGUAGE "Croatian"
- !insertmacro MUI_LANGUAGE "Czech"
- !insertmacro MUI_LANGUAGE "Danish"
- !insertmacro MUI_LANGUAGE "Dutch"
- !insertmacro MUI_LANGUAGE "Estonian"
- !insertmacro MUI_LANGUAGE "Farsi"
- !insertmacro MUI_LANGUAGE "Finnish"
- !insertmacro MUI_LANGUAGE "French"
- !insertmacro MUI_LANGUAGE "German"
- !insertmacro MUI_LANGUAGE "Greek"
- !insertmacro MUI_LANGUAGE "Hebrew"
- !insertmacro MUI_LANGUAGE "Hungarian"
- !insertmacro MUI_LANGUAGE "Icelandic"
- !insertmacro MUI_LANGUAGE "Indonesian"
- !insertmacro MUI_LANGUAGE "Irish"
- !insertmacro MUI_LANGUAGE "Italian"
- !insertmacro MUI_LANGUAGE "Japanese"
- !insertmacro MUI_LANGUAGE "Korean"
- !insertmacro MUI_LANGUAGE "Kurdish"
- !insertmacro MUI_LANGUAGE "Latvian"
- !insertmacro MUI_LANGUAGE "Lithuanian"
- !insertmacro MUI_LANGUAGE "Luxembourgish"
- !insertmacro MUI_LANGUAGE "Macedonian"
- !insertmacro MUI_LANGUAGE "Malay"
- !insertmacro MUI_LANGUAGE "Mongolian"
- !insertmacro MUI_LANGUAGE "Norwegian"
- !insertmacro MUI_LANGUAGE "Polish"
- !insertmacro MUI_LANGUAGE "Portuguese"
- !insertmacro MUI_LANGUAGE "PortugueseBR"
- !insertmacro MUI_LANGUAGE "Romanian"
- !insertmacro MUI_LANGUAGE "Russian"
- !insertmacro MUI_LANGUAGE "Serbian"
- !insertmacro MUI_LANGUAGE "SerbianLatin"
- !insertmacro MUI_LANGUAGE "SimpChinese"
- !insertmacro MUI_LANGUAGE "Slovak"
- !insertmacro MUI_LANGUAGE "Slovenian"
- !insertmacro MUI_LANGUAGE "Spanish"
- !insertmacro MUI_LANGUAGE "Swedish"
- !insertmacro MUI_LANGUAGE "Thai"
- !insertmacro MUI_LANGUAGE "TradChinese"
- !insertmacro MUI_LANGUAGE "Turkish"
- !insertmacro MUI_LANGUAGE "Ukrainian"
- !insertmacro MUI_LANGUAGE "Welsh"
-
-
-;--------------------------------
-;Reserve Files
-
- ;These files should be inserted before other files in the data block
- ;Keep these lines before any File command
- ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA)
-
- ReserveFile "NSIS.InstallOptions.ini"
- !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
-
-;--------------------------------
-;Installer Sections
-
-Section "-Core installation"
- ;Use the entire tree produced by the INSTALL target. Keep the
- ;list of directories here in sync with the RMDir commands below.
- SetOutPath "$INSTDIR"
- @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@
- @CPACK_NSIS_FULL_INSTALL@
-
- ;Store installation folder
- WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
-
- ;Create uninstaller
- WriteUninstaller "$INSTDIR\Uninstall.exe"
- Push "DisplayName"
- Push "@CPACK_NSIS_DISPLAY_NAME@"
- Call ConditionalAddToRegisty
- Push "DisplayVersion"
- Push "@CPACK_PACKAGE_VERSION@"
- Call ConditionalAddToRegisty
- Push "Publisher"
- Push "@CPACK_PACKAGE_VENDOR@"
- Call ConditionalAddToRegisty
- Push "UninstallString"
- Push "$INSTDIR\Uninstall.exe"
- Call ConditionalAddToRegisty
- Push "NoRepair"
- Push "1"
- Call ConditionalAddToRegisty
-
- !ifdef CPACK_NSIS_ADD_REMOVE
- ;Create add/remove functionality
- Push "ModifyPath"
- Push "$INSTDIR\AddRemove.exe"
- Call ConditionalAddToRegisty
- !else
- Push "NoModify"
- Push "1"
- Call ConditionalAddToRegisty
- !endif
-
- ; Optional registration
- Push "DisplayIcon"
- Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@"
- Call ConditionalAddToRegisty
- Push "HelpLink"
- Push "@CPACK_NSIS_HELP_LINK@"
- Call ConditionalAddToRegisty
- Push "URLInfoAbout"
- Push "@CPACK_NSIS_URL_INFO_ABOUT@"
- Call ConditionalAddToRegisty
- Push "Contact"
- Push "@CPACK_NSIS_CONTACT@"
- Call ConditionalAddToRegisty
- !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State"
- !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
-
- ;Create shortcuts
- CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
-@CPACK_NSIS_CREATE_ICONS@
-@CPACK_NSIS_CREATE_ICONS_EXTRA@
- CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
-
- ;Read a value from an InstallOptions INI file
- !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
- !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
- !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
-
- ; Write special uninstall registry entries
- Push "StartMenu"
- Push "$STARTMENU_FOLDER"
- Call ConditionalAddToRegisty
- Push "DoNotAddToPath"
- Push "$DO_NOT_ADD_TO_PATH"
- Call ConditionalAddToRegisty
- Push "AddToPathAllUsers"
- Push "$ADD_TO_PATH_ALL_USERS"
- Call ConditionalAddToRegisty
- Push "AddToPathCurrentUser"
- Push "$ADD_TO_PATH_CURRENT_USER"
- Call ConditionalAddToRegisty
- Push "InstallToDesktop"
- Push "$INSTALL_DESKTOP"
- Call ConditionalAddToRegisty
-
- !insertmacro MUI_STARTMENU_WRITE_END
-
-@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@
-
-SectionEnd
-
-Section "-Add to path"
- Push $INSTDIR\bin
- StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath
- StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
- Call AddToPath
- doNotAddToPath:
-SectionEnd
-
-;--------------------------------
-; Create custom pages
-Function InstallOptionsPage
- !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@"
- !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini"
-
-FunctionEnd
-
-;--------------------------------
-; determine admin versus local install
-Function un.onInit
-
- ClearErrors
- UserInfo::GetName
- IfErrors noLM
- Pop $0
- UserInfo::GetAccountType
- Pop $1
- StrCmp $1 "Admin" 0 +3
- SetShellVarContext all
- ;MessageBox MB_OK 'User "$0" is in the Admin group'
- Goto done
- StrCmp $1 "Power" 0 +3
- SetShellVarContext all
- ;MessageBox MB_OK 'User "$0" is in the Power Users group'
- Goto done
-
- noLM:
- ;Get installation folder from registry if available
-
- done:
-
-FunctionEnd
-
-;--- Add/Remove callback functions: ---
-!macro SectionList MacroName
- ;This macro used to perform operation on multiple sections.
- ;List all of your components in following manner here.
-@CPACK_NSIS_COMPONENT_SECTION_LIST@
-!macroend
-
-Section -FinishComponents
- ;Removes unselected components and writes component status to registry
- !insertmacro SectionList "FinishSection"
-
-!ifdef CPACK_NSIS_ADD_REMOVE
- ; Get the name of the installer executable
- System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1'
- StrCpy $R3 $R0
-
- ; Strip off the last 13 characters, to see if we have AddRemove.exe
- StrLen $R1 $R0
- IntOp $R1 $R0 - 13
- StrCpy $R2 $R0 13 $R1
- StrCmp $R2 "AddRemove.exe" addremove_installed
-
- ; We're not running AddRemove.exe, so install it
- CopyFiles $R3 $INSTDIR\AddRemove.exe
-
- addremove_installed:
-!endif
-SectionEnd
-;--- End of Add/Remove callback functions ---
-
-;--------------------------------
-; Component dependencies
-Function .onSelChange
- !insertmacro SectionList MaybeSelectionChanged
-FunctionEnd
-
-;--------------------------------
-;Uninstaller Section
-
-Section "Uninstall"
- ReadRegStr $START_MENU SHCTX \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
- ;MessageBox MB_OK "Start menu is in: $START_MENU"
- ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath"
- ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers"
- ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser"
- ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
- ReadRegStr $INSTALL_DESKTOP SHCTX \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop"
- ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
-
-@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
-
- ;Remove files we installed.
- ;Keep the list of directories here in sync with the File commands above.
-@CPACK_NSIS_DELETE_FILES@
-@CPACK_NSIS_DELETE_DIRECTORIES@
-
-!ifdef CPACK_NSIS_ADD_REMOVE
- ;Remove the add/remove program
- Delete "$INSTDIR\AddRemove.exe"
-!endif
-
- ;Remove the uninstaller itself.
- Delete "$INSTDIR\Uninstall.exe"
- DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
-
- ;Remove the installation directory if it is empty.
- RMDir "$INSTDIR"
-
- ; Remove the registry entries.
- DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
-
- ; Removes all optional components
- !insertmacro SectionList "RemoveSection_CPack"
-
- !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
-
- Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
-@CPACK_NSIS_DELETE_ICONS@
-@CPACK_NSIS_DELETE_ICONS_EXTRA@
-
- ;Delete empty start menu parent diretories
- StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
-
- startMenuDeleteLoop:
- ClearErrors
- RMDir $MUI_TEMP
- GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
-
- IfErrors startMenuDeleteLoopDone
-
- StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop
- startMenuDeleteLoopDone:
-
- ; If the user changed the shortcut, then untinstall may not work. This should
- ; try to fix it.
- StrCpy $MUI_TEMP "$START_MENU"
- Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
-@CPACK_NSIS_DELETE_ICONS_EXTRA@
-
- ;Delete empty start menu parent diretories
- StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
-
- secondStartMenuDeleteLoop:
- ClearErrors
- RMDir $MUI_TEMP
- GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
-
- IfErrors secondStartMenuDeleteLoopDone
-
- StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop
- secondStartMenuDeleteLoopDone:
-
- DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
-
- Push $INSTDIR\bin
- StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0
- Call un.RemoveFromPath
- doNotRemoveFromPath:
-SectionEnd
-
-;--------------------------------
-; determine admin versus local install
-; Is install for "AllUsers" or "JustMe"?
-; Default to "JustMe" - set to "AllUsers" if admin or on Win9x
-; This function is used for the very first "custom page" of the installer.
-; This custom page does not show up visibly, but it executes prior to the
-; first visible page and sets up $INSTDIR properly...
-; Choose different default installation folder based on SV_ALLUSERS...
-; "Program Files" for AllUsers, "My Documents" for JustMe...
-
-Function .onInit
- StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst
-
- ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString"
- StrCmp $0 "" inst
-
- MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
- "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \
- IDYES uninst IDNO inst
- Abort
-
-;Run the uninstaller
-uninst:
- ClearErrors
- StrLen $2 "\Uninstall.exe"
- StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path
- ExecWait '$0 _?=$3' ;Do not copy the uninstaller to a temp file
-
- IfErrors uninst_failed inst
-uninst_failed:
- MessageBox MB_OK|MB_ICONSTOP "Uninstall failed."
- Abort
-
-
-inst:
- ; Reads components status for registry
- !insertmacro SectionList "InitSection"
-
- ; check to see if /D has been used to change
- ; the install directory by comparing it to the
- ; install directory that is expected to be the
- ; default
- StrCpy $IS_DEFAULT_INSTALLDIR 0
- StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2
- StrCpy $IS_DEFAULT_INSTALLDIR 1
-
- StrCpy $SV_ALLUSERS "JustMe"
- ; if default install dir then change the default
- ; if it is installed for JustMe
- StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
- StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
-
- ClearErrors
- UserInfo::GetName
- IfErrors noLM
- Pop $0
- UserInfo::GetAccountType
- Pop $1
- StrCmp $1 "Admin" 0 +4
- SetShellVarContext all
- ;MessageBox MB_OK 'User "$0" is in the Admin group'
- StrCpy $SV_ALLUSERS "AllUsers"
- Goto done
- StrCmp $1 "Power" 0 +4
- SetShellVarContext all
- ;MessageBox MB_OK 'User "$0" is in the Power Users group'
- StrCpy $SV_ALLUSERS "AllUsers"
- Goto done
-
- noLM:
- StrCpy $SV_ALLUSERS "AllUsers"
- ;Get installation folder from registry if available
-
- done:
- StrCmp $SV_ALLUSERS "AllUsers" 0 +3
- StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
- StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
-
- StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini"
-
- noOptionsPage:
-FunctionEnd
diff --git a/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt b/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt
new file mode 100644
index 00000000..07fe75aa
--- /dev/null
+++ b/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGAzCCA+ugAwIBAgIRAJNGLpTSm2U3GjXmFkjT/0cwDQYJKoZIhvcNAQELBQAw
+dzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
+ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxIDAeBgNVBAMM
+F2NyZWF0aXZlY293cGF0QG1haWwuaTJwMB4XDTE3MDUyNjE5NDQzOVoXDTI3MDUy
+NjE5NDQzOVowdzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJY
+WDEeMBwGA1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAx
+IDAeBgNVBAMMF2NyZWF0aXZlY293cGF0QG1haWwuaTJwMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAo3XP4JToVbfM5e4GxyAqzu2DJV7ohpzlLqMLyz/9
+XgZ7ipctNoxVZytoaNgMeAHInJn5OhUC4D+emsgsLJqFjnb2pxf6v45sRZLBMieb
+wJlxUmskucpTXwDwuHBk/s3xmH4IluadmzwiCMyycQFH/CNXmu5bonAuZ075rT1Q
+a8W0vb8eSfNYXn+FKQBROqsL5Ep+iJM6FX+oWMxJPk/zNluIu9qTdZL7Fts2+ObP
+X5WLE4Dtot57vMI2Tg3fjnpgvk3ynQjacS8+CBEbvA/j32PBS1mQB+ebl56CQTBv
+glHrXiNdp24TAwy8mwWHknhpt4cvRXOJGZphSVNRYFVk0vv7CTjmQg6WOBGD+d/P
+cosvyKxQz4WUSmtaKUftgCBdnemeM7BppZv2URflEOY6Uv3f9xlEC6yVEzSaa2Md
+tG6XRkDyupWCBFwmSm1uS+SXXhxAQGn3eMXPFA1XkwNnZtmM9kvSVt34FBE231oN
+4oM7rE3ZDyTocZw7cv7bl8idmqsLXDTSFn5Q2iLwvw6ZeTenk8qHrq9kVH1UVE2l
+31iKDNdGQkkVcnTWYfiqriwGLpTqbeD/8n9OBgCke1TiKQzP1o66nhkGJTiiRLFK
+A8rlSpqBcjGbXDs/X+Ote9MrCxE089eCqN51kzDeQ4Yvy8gDOTBPGEhBLirx+3pp
+yWkCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUH
+AwIGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wIAYDVR0OBBkEF2NyZWF0aXZl
+Y293cGF0QG1haWwuaTJwMCIGA1UdIwQbMBmAF2NyZWF0aXZlY293cGF0QG1haWwu
+aTJwMA0GCSqGSIb3DQEBCwUAA4ICAQCYzeYyPYhW+/SZSfpDl6JTzXy8S6NG+yjq
+pcinxaIF4XFoXLwWD3uHR4jgpU750mhHJjpGIaltZjFaqLbqtysbqb0vdShyaK/n
+Td4CXrNBvEHvLI6DZyDX4BcDlhCI7/dMCSHXwFIhRHhYSnTsJO32BdP5DsUUAlSW
+G0FlEEWjlxcdRwIITv70cFNlNOqJeyvtk9DPT+nEzssKWxVZcqN4GK8dvQVWgL91
+8uzrcAYpAEQfmkKzsGmV4v5gWumLZmnzc24hUhVsHhIph4HAmjPMFCppI1tgiwg7
+fH71MYB8b9KBJKipkLdAL292mDLS4G3MGQwMbcjnTyIqOktmyyj/1CorZAKqBtzu
+Qyo7z8FM2pd5nzk7QDx/vsJ4bNAYvVu7titDW5mv5JDoQcp2uDVGePlonX3I8iFx
+CqKFzGHiR0EU8oWw0Pqf+y2rEV4L74agmUR7VbA+/ovz0UnDUoXIynSwpK7Kfo8D
+B7ky9RnmsxJX6TXaMVW06IlYuwIUsAWbMhKvdXbGZur5VVi1ZY1/HgZZnoXejzCe
+w3mMl6movkcA0noDXQ+eauUDHjktrVUJdZKYvZNjfnz2rB+MI5wB/hzeBv4KuYFE
+oTFt8SwTzs0joM4c7RomTxc+QFe832SvjPAnxQn17qSjD8z4c7Ako6sCKvpdBSDm
+Hz8KWVkHZg==
+-----END CERTIFICATE-----
diff --git a/contrib/certificates/reseed/parg_at_mail.i2p.crt b/contrib/certificates/reseed/parg_at_mail.i2p.crt
deleted file mode 100644
index e78b264c..00000000
--- a/contrib/certificates/reseed/parg_at_mail.i2p.crt
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF1TCCA7+gAwIBAgIRAPmuHtSxMcNIUXNc0N4+7RIwCwYJKoZIhvcNAQELMG0x
-CzAJBgNVBAYTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAK
-BgNVBAsTA0kyUDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMRYwFAYDVQQDDA1w
-YXJnQG1haWwuaTJwMB4XDTE1MDUxOTIwMjExM1oXDTI1MDUxOTIwMjExM1owbTEL
-MAkGA1UEBhMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoG
-A1UECxMDSTJQMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxFjAUBgNVBAMMDXBh
-cmdAbWFpbC5pMnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/jINR
-maFCnuCZwofrhtJoneIuJn6kauYYfjPF/nRrPffiooX2vo0Tp6cpTAulMul0Nh2I
-/trJSbBqzneg+0zDS2wpLb1U7FJ5WGqb+yk7eo8X+Upjsuu4JoFr6ap81+J5oFBR
-zTyYba6TYYwAZoBXAkY3qMjbfbYkqceY/p5WqAhEO7N4/DVLRA42FsQQMFwJYHnD
-SgcyrTXiBbWJzvEF/4LSpL2CXB3Efkti/1MggVhXBu83PSkPvYQQTGFmwKP+ivVZ
-V339xNGGKqPd+B1LOI8xUEAGGbOgfdB3c/x8weOwRip6bp+0SfLcVHO9X1lD95SA
-dvtz2qABWDhqcMTyfJIEuOQSpQO6DhhBViHR2cjcu+z5Ugf+X6ZWhtFMBJsLb0Um
-R3gKhPaMizCYVW6uRyA1B5SnO3Pd1ve1qX+K1h+NZPXoMpBxmyg+ds/WuhmAZUEB
-bzUr7DczImb29WlBFCbYjA/fBN8QOc2qZpQFckY4CrBhCmFevxSpwHOxSkVEeXet
-tYZ2BZIxN+I5p5SZc+6Ba1O3hqJsqv4D8H4TqXYZaw50ySRYIl9LDAEYp7owZzwA
-oMxmjnsZBVtkGZpKk/RColQVLT/xmUqDJPQlWRw2te7tr1LiH2ZkVu7TUuhIep+i
-4U8H4S9+zNQEAyn87L589AsGQ9hRtwrUOqy1ywIDAQABo3QwcjAOBgNVHQ8BAf8E
-BAMCAIQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA8GA1UdEwEB/wQF
-MAMBAf8wFgYDVR0OBA8EDXBhcmdAbWFpbC5pMnAwGAYDVR0jBBEwD4ANcGFyZ0Bt
-YWlsLmkycDALBgkqhkiG9w0BAQsDggIBAGaVJunmmO0EfDuTAN8Psjq7YVwwSyMk
-6h1dMHz/U1GwY/jjKIIyfzKh6SfZmBfQT5fnGLM84m1O0267s9PZpHFcw9Kn+KQ4
-YkfzVaYgsADjeyqQ1XIHJ/CZ60BWCs9aqWgYoTscbTtadaGscFBTegispkt8+Mj6
-aaEQnajCD4f2GFHEi0miG+gRu6MDgqG2ka5tg3j+zfSDiq5lclq5qS97Lu/EVLRr
-HlLKBDPnLKeGYnPOAlzTNqwWtvLho7jIFHt7DP1Qzn3nvDoOQb40ToHCAAcMr9jy
-ncS6Eo4veeWeaSIGMnaDuzZoTWadizZo1G9z3ADMXRJ5IxdLKbBZiSkCHuAMnDSe
-NKREmXewzjtRQBgf7RkyU0JwIqTKJsLTMX8oLecyvZHunmuKkqpJ/AgIyRB2X/nz
-/LFeg4cru20Q+mpzVBnZPCS6X45jbew14ajURRgp4MrX52Ph+9/mS4RVQhHL+GDU
-4OwF6tkqFD0umw1Gn1CAvKPOn9EVHa7nLDYxPo9LEX7Dnb5WkwKDqtALrcMDYjJr
-4TqJFbsijYehVn+kFQ4I4aN54ECzwu9RKmebrXyDDe0e0fErRsF5+qII8/wOo4WT
-XUjHCvK6THeaC8k5jcostgVszIx7rwqXj1ailbV/nAFr8NgADs04//5DJA0ieD+4
-N1tGWBZt9Prq
------END CERTIFICATE-----
diff --git a/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt b/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt
new file mode 100644
index 00000000..850b1afd
--- /dev/null
+++ b/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIEY2XeQjANBgkqhkiG9w0BAQ0FADB1MQswCQYDVQQGEwJY
+WDELMAkGA1UECAwCWFgxHjAcBgNVBAcMFUkyUCBBbm9ueW1vdXMgTmV0d29yazEL
+MAkGA1UECgwCWFgxDDAKBgNVBAsMA0kyUDEeMBwGA1UEAwwVcjRzYXMtcmVzZWVk
+QG1haWwuaTJwMB4XDTE3MDYyMjEwNTQ1NFoXDTI3MDYyMDEwNTQ1NFowdTELMAkG
+A1UEBhMCWFgxCzAJBgNVBAgMAlhYMR4wHAYDVQQHDBVJMlAgQW5vbnltb3VzIE5l
+dHdvcmsxCzAJBgNVBAoMAlhYMQwwCgYDVQQLDANJMlAxHjAcBgNVBAMMFXI0c2Fz
+LXJlc2VlZEBtYWlsLmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ANgsj5LhF4uGG4RDueShqYQZsG5Rz6XUAtK9sVGFdmdJTDZirUMZcCGCGZP/Harz
+QaZU9EYxOCztnpLCQksSCpdRsij56MURS0tW/1x7LHIDUOi911Of57jgIHH+3E5n
+6tuRxEk6J/9Ji3PI+89kl0sPKMVFMyKkINprVTA5zr/keyYEG0p6HSEYYiJkQH78
+8uoOCAmlk9mxkJFb+zviCk6jsYwdH+ofD6Lw5ueOlYUbeZ9Nd7jfSdf20XM7ofIw
+W2COtsbq3J7vNrQJMV7HkHxVx/7OqmjQF02OahZFZREVZqbHpL501iTn9Iqd5qKq
+IsxYjk7ZnP4UUCBk8NOU5TuWsy0qNw+TJDI9s55Fi4KPtXWf47HIl6CdpM5y/D5L
+eufCojSwPKlrD6x9gTyJdBggBZRIyplXdKffo/95hUhEkv86yfsVVR7Gu1uy0O8T
+Gtb8Da/oi5eEZBHWonLVicLPei5jeo+1gbR09PQ6s41uMZlOhMe4RSgiIQj/7UVo
+ffKdl1MPNKr1u2fgVj8kxqg8ZivWKQ2taEgimU2EkQcNcE96M9yQlNNpNvqSAQVk
+wYXlHt0AN6A1A8u1pItxaTwXnbmx+OBJZoKl4ZQeaC8wtKjTgAgVXp+g5iot2gir
+LjxCRx1WLG1c8vRg1W8CDZII8Swc8EWpMhI+0hPv7/4/AgMBAAGjITAfMB0GA1Ud
+DgQWBBTN5sKbrNzwE8sgMGDekfOPgX8/JDANBgkqhkiG9w0BAQ0FAAOCAgEAjLaB
+bHqvFTs0ikAtesk9r8+8XVIsP5FR57zZCek2vxkHcCQWw8Uqs3ndInRX4FirKSLT
+WRb4aSwFCkrmwueecTpXN/RBC+fZj+POCfdILEsA+FGreAM2q5ZXv/Q0jyIXOXEM
++KL0JZXnNS0/dqR3IYbC7f39CL6Sf40gRGTwTWWGg3KnynoS0v1zQcZLTMhHBD2X
+tgdIPbroq9t4gXa7Dhm0egYfQOI/7re2wiZT7UWVVwEpYqKf6JApFHa1nNOFMrLF
+45JHQIHArkoxpQdfSe9HBoyJiB5vz398rHZeqbJaF3PIg9rxWWY/NvvOVuIk8U5z
+0jExhg29a88B32U7ndvQJqIuGiQghzCiLxC/y1+wAdpeDSbD3OAOHqplvMj3BUn9
+yhDSLSjtfBJjnXKxtEcWLR0edHCGEk5mAcL7q1WNxDpxaICwGGpNZN53CtFx7amb
+egYil448DmiqoQTCTE9pBz8YjwiVfCYLYv17O0NJyYM9Efy/wL3rFlsPJniWHMuH
+imZybVU4ukjvfOZ+LY4COTwz6w4sfA7a+i+2mOynC7eKX8Yg6i1nXlcY1Z8ykNgi
+7B3kz1T/DV56CIm6QUWtepfuKTYq4C6QrBBIXLk1d5g95aWA21u1LRqNZ9GLH+eA
+gfvIm7v+cELj8a53EQY0LafzZqNC5kQAp916coU=
+-----END CERTIFICATE-----
diff --git a/contrib/certificates/reseed/randomrng_at_mail.i2p.crt b/contrib/certificates/reseed/randomrng_at_mail.i2p.crt
deleted file mode 100644
index aa3330ad..00000000
--- a/contrib/certificates/reseed/randomrng_at_mail.i2p.crt
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFzTCCA7WgAwIBAgIQAkW0dwrp8UmNi9MTzU4/QjANBgkqhkiG9w0BAQsFADBy
-MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
-ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEbMBkGA1UEAwwS
-cmFuZG9tcm5nQG1haWwuaTJwMB4XDTE3MDIyNTE2MTgyM1oXDTI3MDIyNTE2MTgy
-M1owcjELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwG
-A1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGzAZBgNV
-BAMMEnJhbmRvbXJuZ0BtYWlsLmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
-AgoCggIBAMSUiFKmGKb5sDkuB1mEGfXikfOJA5ATgMROXyY0XkwLWedBCC6pa1/X
-cVOfPDmDdmkPO8Brep7D2CLq21BBb4lAH7LrKHrABNjf1kfAwRAYMon9HsW3Yn+O
-yIAvGbVTXqQlWpeL1ZRGFhU/5h/D5UtEpcIyG0lkBYRfZ52wFKP2WP52TBcGVpj8
-wBQnXfGmAhRUQfKDmJVCB5GLzNSxrmbhbdyBzZMoeOLTaTfMfb7jSIakYzH4f0TZ
-1VE5+z+1BkJ53qVRH7IV1UBtSIBGD/L84wkqM5mIGKnZXiOyZxfKvS/sGr7WZuMu
-NK3ugCFfTZnxYtb0dDPaqeXrdB3OKE/d5ghAOcIyBWrfsRQJlaHSIwvpqz7Hr7vA
-3xSklkvvJoGwCIy2/+bFGP+Z6ietzvF9/mr1NcwxXGH32zjVmDSto+yaDjsMGFu1
-y4L4wUsOQOVsgNYPECC2HZOisUm/iYdw1+Y/PbgZS0sG3KzBZ1HYsvvFiTLZiyZR
-+ZFTLmBoI3DPMfmTf0lRWXXWgUnWXDkxqBAV/fvmAc3XQfpI4HrkAYOllmAIStr9
-7OVsBAJiMcYWzx0UIZGBG+PE9uxHnGxVX64n2lKYLoXLWFURVoFJIYn7AJaxTv0N
-r0IduERKqoQ0wyCjZ6RJOtz26GFUe1bPa7rc/VgfbZwUbF17lzAVAgMBAAGjXzBd
-MA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
-DwYDVR0TAQH/BAUwAwEB/zAbBgNVHQ4EFAQScmFuZG9tcm5nQG1haWwuaTJwMA0G
-CSqGSIb3DQEBCwUAA4ICAQAi4OOKzy7TcaFZccl2lmKp1wxDmaSaf/dhaqpaSKMS
-zzvgO9XIq6CLEY/YqSm5AjU8PsclaC8+g20THCSUHntL3Jxu2dw1m/H30Mg0I1uJ
-G7pyIVYwuwkdbalGQOaS0u3grzWnbCGMzuqeMBi8EBsZ5jsT5LGjgy1GE+BXl2tv
-9EEWhy8dSVh3cy1iaAM6ZhCyj4rSw4odQqH2NWDOFt52cycHe/rpvKKD1AlrmFHQ
-w18WnfUhr43JAyTWKxg/6uwdxb+cBTX0cad8lbOtQLiqNwOxQvEi/4uRrkdKtbRf
-Z+MUI0XIopH2XV5lLExtxXStAaB4mZTgAbFPCnBC0wKQh/sgdXmUWsEEk610NShC
-26jtXuPb43cDyCewUNCZ+jtzbc9pl6/SyatY/i2gAHamvGmeVJFzQkHe7YHRdzeR
-RIqnWGlwSh0roPPRCU2dNdBZ0uH9lYbkG0IzGmEtks+KQqG+1H0yZkSCmArarLfj
-aU5UslG+Zf1imqXtz5kFD/UMMuaQW05Sa/0YO6gW/hLtChHI5Jpd/Qb/KqLkPAM3
-PEVs4H5ZMVa6mLUsLIw9Ra2QozdB9lqoZBMRa0jqgJKxnAgNcWpYtTyJ2PtfA9oE
-xmjE6O3FlNSee4aKxZ2Kz7cTufd/+ndsSSeNuRLQVihXKNqkrQIuow+H/KDw930c
-Cw==
------END CERTIFICATE-----
diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile
new file mode 100644
index 00000000..2c2c4a03
--- /dev/null
+++ b/contrib/docker/Dockerfile
@@ -0,0 +1,54 @@
+FROM alpine:latest
+LABEL authors "Mikal Villa , Darknet Villain "
+
+# Expose git branch, tag and URL variables as arguments
+ARG GIT_BRANCH="master"
+ENV GIT_BRANCH=${GIT_BRANCH}
+ARG GIT_TAG=""
+ENV GIT_TAG=${GIT_TAG}
+ARG REPO_URL="https://github.com/PurpleI2P/i2pd.git"
+ENV REPO_URL=${REPO_URL}
+
+ENV I2PD_HOME="/home/i2pd"
+ENV DATA_DIR="${I2PD_HOME}/data"
+
+RUN mkdir -p "$I2PD_HOME" \
+ && adduser -S -h "$I2PD_HOME" i2pd \
+ && chown -R i2pd:nobody "$I2PD_HOME"
+
+#
+# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
+# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer.
+#
+
+# 1. install deps, clone and build.
+# 2. strip binaries.
+# 3. Purge all dependencies and other unrelated packages, including build directory.
+RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
+ && mkdir -p /tmp/build \
+ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
+ && cd i2pd \
+ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \
+ && make \
+ && cp -R contrib/certificates /i2pd_certificates \
+ && mkdir -p /usr/local/bin \
+ && mv i2pd /usr/local/bin \
+ && cd /usr/local/bin \
+ && strip i2pd \
+ && rm -fr /tmp/build && apk --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \
+ boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \
+ boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \
+ libtool g++ gcc pkgconfig
+
+# 2. Adding required libraries to run i2pd to ensure it will run.
+RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl musl-utils libstdc++
+
+COPY entrypoint.sh /entrypoint.sh
+RUN chmod a+x /entrypoint.sh
+
+RUN echo "export DATA_DIR=${DATA_DIR}" >> /etc/profile
+VOLUME "$DATA_DIR"
+EXPOSE 7070 4444 4447 7656 2827 7654 7650
+USER i2pd
+
+ENTRYPOINT [ "/entrypoint.sh" ]
diff --git a/contrib/docker/entrypoint.sh b/contrib/docker/entrypoint.sh
new file mode 100644
index 00000000..670ff577
--- /dev/null
+++ b/contrib/docker/entrypoint.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+COMMAND=/usr/local/bin/i2pd
+# To make ports exposeable
+# Note: $DATA_DIR is defined in /etc/profile
+DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0"
+
+if [ "$1" = "--help" ]; then
+ set -- $COMMAND --help
+else
+ # Create datadir
+ mkdir -p "$DATA_DIR"
+ ln -s /i2pd_certificates "$DATA_DIR"/certificates
+ set -- $COMMAND $DEFAULT_ARGS $@
+fi
+
+exec "$@"
diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp
index 309c0e9c..7668da66 100644
--- a/libi2pd/Config.cpp
+++ b/libi2pd/Config.cpp
@@ -182,14 +182,13 @@ namespace config {
// "https://us.reseed.i2p2.no:444/," // mamoth's shit
// "https://uk.reseed.i2p2.no:444/," // mamoth's shit
"https://i2p-0.manas.ca:8443/,"
- "https://reseed.i2p.vzaws.com:8443/,"
"https://download.xxlspeed.com/,"
"https://reseed-ru.lngserv.ru/,"
"https://reseed.atomike.ninja/,"
"https://reseed.memcpy.io/,"
"https://reseed.onion.im/,"
- "https://itoopie.atomike.ninja/"
-// "https://randomrng.ddns.net/" // dead
+ "https://itoopie.atomike.ninja/,"
+ "https://i2pseed.creativecowpat.net:8443/"
), "Reseed URLs, separated by comma")
;
@@ -301,5 +300,19 @@ namespace config {
return true;
return false;
}
+
+ bool GetOptionAsAny(const char *name, boost::any& value) {
+ if (!m_Options.count(name))
+ return false;
+ value = m_Options[name];
+ return true;
+ }
+
+ bool GetOptionAsAny(const std::string& name, boost::any& value)
+ {
+ return GetOptionAsAny (name.c_str (), value);
+ }
+
} // namespace config
} // namespace i2p
+
diff --git a/libi2pd/Config.h b/libi2pd/Config.h
index 1895da55..754618d7 100644
--- a/libi2pd/Config.h
+++ b/libi2pd/Config.h
@@ -84,6 +84,9 @@ namespace config {
return GetOption (name.c_str (), value);
}
+ bool GetOptionAsAny(const char *name, boost::any& value);
+ bool GetOptionAsAny(const std::string& name, boost::any& value);
+
/**
* @brief Set value of given parameter
* @param name Name of settable parameter
diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp
index 713d6ca6..bceda568 100644
--- a/libi2pd/FS.cpp
+++ b/libi2pd/FS.cpp
@@ -56,7 +56,7 @@ namespace fs {
else
{
// otherwise %appdata%
- SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData);
+ SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData);
dataDir = std::string(localAppData) + "\\" + appName;
}
return;
diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp
index 1edeb3bd..eabdd8c4 100644
--- a/libi2pd/SSU.cpp
+++ b/libi2pd/SSU.cpp
@@ -445,12 +445,14 @@ namespace transport
int numIntroducers = address->ssu->introducers.size ();
if (numIntroducers > 0)
{
+ uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
std::shared_ptr introducerSession;
const i2p::data::RouterInfo::Introducer * introducer = nullptr;
// we might have a session to introducer already
for (int i = 0; i < numIntroducers; i++)
{
auto intr = &(address->ssu->introducers[i]);
+ if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer
boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort);
if (ep.address ().is_v4 ()) // ipv4 only
{
@@ -465,7 +467,7 @@ namespace transport
}
if (!introducer)
{
- LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 introducers present");
+ LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented");
return;
}
diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp
index 42968c7a..778e0745 100644
--- a/libi2pd_client/SAM.cpp
+++ b/libi2pd_client/SAM.cpp
@@ -24,22 +24,23 @@ namespace client
SAMSocket::~SAMSocket ()
{
- Terminate ();
- }
+ Terminate ("~SAMSocket()");
+ }
- void SAMSocket::CloseStream ()
+ void SAMSocket::CloseStream (const char* reason)
{
+ LogPrint (eLogDebug, "SAMSocket::CloseStream, reason: ", reason);
if (m_Stream)
{
m_Stream->Close ();
m_Stream.reset ();
- }
- }
-
- void SAMSocket::Terminate ()
+ }
+ }
+
+ void SAMSocket::Terminate (const char* reason)
{
- CloseStream ();
-
+ CloseStream (reason);
+
switch (m_SocketType)
{
case eSAMSocketTypeSession:
@@ -82,7 +83,7 @@ namespace client
{
LogPrint (eLogError, "SAM: handshake read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("SAM: handshake read error");
}
else
{
@@ -130,7 +131,7 @@ namespace client
else
{
LogPrint (eLogError, "SAM: handshake mismatch");
- Terminate ();
+ Terminate ("SAM: handshake mismatch");
}
}
}
@@ -141,7 +142,7 @@ namespace client
{
LogPrint (eLogError, "SAM: handshake reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("SAM: handshake reply send error");
}
else
{
@@ -153,6 +154,8 @@ namespace client
void SAMSocket::SendMessageReply (const char * msg, size_t len, bool close)
{
+ LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg);
+
if (!m_IsSilent)
boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
@@ -160,7 +163,7 @@ namespace client
else
{
if (close)
- Terminate ();
+ Terminate ("SAMSocket::SendMessageReply(close=true)");
else
Receive ();
}
@@ -172,12 +175,12 @@ namespace client
{
LogPrint (eLogError, "SAM: reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("SAM: reply send error");
}
else
{
if (close)
- Terminate ();
+ Terminate ("SAMSocket::HandleMessageReplySent(close=true)");
else
Receive ();
}
@@ -189,7 +192,7 @@ namespace client
{
LogPrint (eLogError, "SAM: read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("SAM: read error");
}
else if (m_SocketType == eSAMSocketTypeStream)
HandleReceived (ecode, bytes_transferred);
@@ -243,13 +246,13 @@ namespace client
else
{
LogPrint (eLogError, "SAM: unexpected message ", m_Buffer);
- Terminate ();
+ Terminate ("SAM: unexpected message");
}
}
else
{
LogPrint (eLogError, "SAM: malformed message ", m_Buffer);
- Terminate ();
+ Terminate ("malformed message");
}
}
@@ -603,7 +606,7 @@ namespace client
if (m_BufferOffset >= SAM_SOCKET_BUFFER_SIZE)
{
LogPrint (eLogError, "SAM: Buffer is full, terminate");
- Terminate ();
+ Terminate ("Buffer is full");
return;
}
m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
@@ -617,7 +620,7 @@ namespace client
{
LogPrint (eLogError, "SAM: read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("read error");
}
else
{
@@ -631,8 +634,8 @@ namespace client
{
if (!ecode)
s->Receive ();
- else
- s->m_Owner.GetService ().post ([s] { s->Terminate (); });
+ else
+ s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); });
});
}
}
@@ -660,8 +663,8 @@ namespace client
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1));
}
else // no more data
- Terminate ();
- }
+ Terminate ("no more data");
+ }
}
}
@@ -678,14 +681,14 @@ namespace client
else
{
auto s = shared_from_this ();
- m_Owner.GetService ().post ([s] { s->Terminate (); });
+ m_Owner.GetService ().post ([s] { s->Terminate ("stream read error"); });
}
}
else
{
auto s = shared_from_this ();
- m_Owner.GetService ().post ([s] { s->Terminate (); });
- }
+ m_Owner.GetService ().post ([s] { s->Terminate ("stream read error (op aborted)"); });
+ }
}
else
{
@@ -700,7 +703,7 @@ namespace client
{
LogPrint (eLogError, "SAM: socket write error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
- Terminate ();
+ Terminate ("socket write error at HandleWriteI2PData");
}
else
I2PReceive ();
@@ -809,7 +812,7 @@ namespace client
socks.push_back(sock);
}
}
- for (auto & sock : socks ) sock->Terminate();
+ for (auto & sock : socks ) sock->Terminate("SAMSession::CloseStreams()");
m_Sockets.clear();
}
diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h
index d8a6ca1a..499f0da7 100644
--- a/libi2pd_client/SAM.h
+++ b/libi2pd_client/SAM.h
@@ -79,16 +79,17 @@ namespace client
public:
SAMSocket (SAMBridge& owner);
- ~SAMSocket ();
- void CloseStream (); // TODO: implement it better
+ ~SAMSocket ();
+ void CloseStream (const char* reason); // TODO: implement it better
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
void ReceiveHandshake ();
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
SAMSocketType GetSocketType () const { return m_SocketType; };
- void Terminate ();
- private:
+ void Terminate (const char* reason);
+
+ private:
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp
new file mode 100644
index 00000000..9fc00509
--- /dev/null
+++ b/qt/i2pd_qt/ClientTunnelPane.cpp
@@ -0,0 +1,199 @@
+#include "ClientTunnelPane.h"
+#include "ClientContext.h"
+#include "SignatureTypeComboboxFactory.h"
+#include "QVBoxLayout"
+
+ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf):
+ TunnelPane(tunnelsPageUpdateListener, tunconf) {}
+
+void ClientTunnelPane::setGroupBoxTitle(const QString & title) {
+ clientTunnelNameGroupBox->setTitle(title);
+}
+
+void ClientTunnelPane::deleteClientTunnelForm() {
+ delete clientTunnelNameGroupBox;
+ clientTunnelNameGroupBox=nullptr;
+
+ //gridLayoutWidget_2->deleteLater();
+ //gridLayoutWidget_2=nullptr;
+}
+
+int ClientTunnelPane::appendClientTunnelForm(
+ ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
+
+ ClientTunnelPane& ui = *this;
+
+ clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
+ clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox"));
+
+ //tunnel
+ gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox);
+
+ QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
+ tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
+ tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT);
+ tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS);
+ tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS);
+ tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY);
+ tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT);
+
+ int h=(7+4)*60;
+ gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
+ clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
+
+ {
+ const QString& type = tunnelConfig->getType();
+ int index=0;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ }
+
+ setupTunnelPane(tunnelConfig,
+ clientTunnelNameGroupBox,
+ gridLayoutWidget_2, tunnelTypeComboBox,
+ tunnelsFormGridLayoutWidget, tunnelsRow, height, h);
+ //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10));
+
+ /*
+ std::string destination;
+ */
+
+ //host
+ ui.horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.destinationLabel = new QLabel(gridLayoutWidget_2);
+ destinationLabel->setObjectName(QStringLiteral("destinationLabel"));
+ horizontalLayout_2->addWidget(destinationLabel);
+ ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2);
+ destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit"));
+ destinationLineEdit->setText(tunnelConfig->getdest().c_str());
+ QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(destinationLineEdit);
+ ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(destinationHorizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+
+ /*
+ * int port;
+ */
+ int gridIndex = 2;
+ {
+ int port = tunnelConfig->getport();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.portLabel = new QLabel(gridLayoutWidget_2);
+ portLabel->setObjectName(QStringLiteral("portLabel"));
+ horizontalLayout_2->addWidget(portLabel);
+ ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
+ portLineEdit->setObjectName(QStringLiteral("portLineEdit"));
+ portLineEdit->setText(QString::number(port));
+ portLineEdit->setMaximumWidth(80);
+ QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(portLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ /*
+ * std::string keys;
+*/
+ {
+ std::string keys = tunnelConfig->getkeys();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.keysLabel = new QLabel(gridLayoutWidget_2);
+ keysLabel->setObjectName(QStringLiteral("keysLabel"));
+ horizontalLayout_2->addWidget(keysLabel);
+ ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2);
+ keysLineEdit->setObjectName(QStringLiteral("keysLineEdit"));
+ keysLineEdit->setText(keys.c_str());
+ QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(keysLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ /*
+ * std::string address;
+ */
+ {
+ std::string address = tunnelConfig->getaddress();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.addressLabel = new QLabel(gridLayoutWidget_2);
+ addressLabel->setObjectName(QStringLiteral("addressLabel"));
+ horizontalLayout_2->addWidget(addressLabel);
+ ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2);
+ addressLineEdit->setObjectName(QStringLiteral("addressLineEdit"));
+ addressLineEdit->setText(address.c_str());
+ QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(addressLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ /*
+ int destinationPort;
+ i2p::data::SigningKeyType sigType;
+*/
+ {
+ int destinationPort = tunnelConfig->getdestinationPort();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.destinationPortLabel = new QLabel(gridLayoutWidget_2);
+ destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel"));
+ horizontalLayout_2->addWidget(destinationPortLabel);
+ ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2);
+ destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit"));
+ destinationPortLineEdit->setText(QString::number(destinationPort));
+ destinationPortLineEdit->setMaximumWidth(80);
+ QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(destinationPortLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
+ sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
+ horizontalLayout_2->addWidget(sigTypeLabel);
+ ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType);
+ sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox"));
+ QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(sigTypeComboBox);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
+ appendControlsForI2CPParameters(i2cpParameters, gridIndex);
+ }
+
+ retranslateClientTunnelForm(ui);
+
+ tunnelGridLayout->invalidate();
+
+ return h;
+}
+
+ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;}
+ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;}
diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h
new file mode 100644
index 00000000..16416cd8
--- /dev/null
+++ b/qt/i2pd_qt/ClientTunnelPane.h
@@ -0,0 +1,97 @@
+#ifndef CLIENTTUNNELPANE_H
+#define CLIENTTUNNELPANE_H
+
+#include "QGridLayout"
+#include "QVBoxLayout"
+
+#include "TunnelPane.h"
+
+class ClientTunnelConfig;
+
+class ServerTunnelPane;
+class TunnelPane;
+
+class ClientTunnelPane : public TunnelPane {
+ Q_OBJECT
+public:
+ ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf);
+ virtual ~ClientTunnelPane(){}
+ virtual ServerTunnelPane* asServerTunnelPane();
+ virtual ClientTunnelPane* asClientTunnelPane();
+ int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
+ int tunnelsRow, int height);
+ void deleteClientTunnelForm();
+private:
+ QGroupBox *clientTunnelNameGroupBox;
+
+ //tunnel
+ QWidget *gridLayoutWidget_2;
+
+ //destination
+ QHBoxLayout *horizontalLayout_2;
+ QLabel *destinationLabel;
+ QLineEdit *destinationLineEdit;
+ QSpacerItem *destinationHorizontalSpacer;
+
+ //port
+ QLabel * portLabel;
+ QLineEdit * portLineEdit;
+
+ //keys
+ QLabel * keysLabel;
+ QLineEdit * keysLineEdit;
+
+ //address
+ QLabel * addressLabel;
+ QLineEdit * addressLineEdit;
+
+ //destinationPort
+ QLabel * destinationPortLabel;
+ QLineEdit * destinationPortLineEdit;
+
+ //sigType
+ QLabel * sigTypeLabel;
+ QComboBox * sigTypeComboBox;
+
+protected slots:
+ virtual void setGroupBoxTitle(const QString & title);
+
+private:
+ void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) {
+ typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0));
+ destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0));
+ portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0));
+ keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0));
+ destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0));
+ addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0));
+ sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
+ }
+protected:
+ virtual bool applyDataFromUIToTunnelConfig() {
+ bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
+ if(!ok)return false;
+ ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig();
+ assert(ctc!=nullptr);
+
+ //destination
+ ctc->setdest(destinationLineEdit->text().toStdString());
+
+ auto portStr=portLineEdit->text();
+ int portInt=portStr.toInt(&ok);
+ if(!ok)return false;
+ ctc->setport(portInt);
+
+ ctc->setkeys(keysLineEdit->text().toStdString());
+
+ ctc->setaddress(addressLineEdit->text().toStdString());
+
+ auto dportStr=portLineEdit->text();
+ int dportInt=dportStr.toInt(&ok);
+ if(!ok)return false;
+ ctc->setdestinationPort(dportInt);
+
+ ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
+ }
+};
+
+#endif // CLIENTTUNNELPANE_H
diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp
index 585bd56c..accd69b1 100644
--- a/qt/i2pd_qt/DaemonQT.cpp
+++ b/qt/i2pd_qt/DaemonQT.cpp
@@ -18,23 +18,41 @@ namespace qt
void Worker::startDaemon()
{
qDebug("Performing daemon start...");
- m_Daemon.start();
- qDebug("Daemon started.");
- emit resultReady();
+ //try{
+ m_Daemon.start();
+ qDebug("Daemon started.");
+ emit resultReady(false, "");
+ /*}catch(std::exception ex){
+ emit resultReady(true, ex.what());
+ }catch(...){
+ emit resultReady(true, QObject::tr("Error: unknown exception"));
+ }*/
}
void Worker::restartDaemon()
{
qDebug("Performing daemon restart...");
- m_Daemon.restart();
- qDebug("Daemon restarted.");
- emit resultReady();
- }
+ //try{
+ m_Daemon.restart();
+ qDebug("Daemon restarted.");
+ emit resultReady(false, "");
+ /*}catch(std::exception ex){
+ emit resultReady(true, ex.what());
+ }catch(...){
+ emit resultReady(true, QObject::tr("Error: unknown exception"));
+ }*/
+ }
void Worker::stopDaemon() {
qDebug("Performing daemon stop...");
- m_Daemon.stop();
- qDebug("Daemon stopped.");
- emit resultReady();
- }
+ //try{
+ m_Daemon.stop();
+ qDebug("Daemon stopped.");
+ emit resultReady(false, "");
+ /*}catch(std::exception ex){
+ emit resultReady(true, ex.what());
+ }catch(...){
+ emit resultReady(true, QObject::tr("Error: unknown exception"));
+ }*/
+ }
Controller::Controller(DaemonQTImpl& daemon):
m_Daemon (daemon)
diff --git a/qt/i2pd_qt/DaemonQT.h b/qt/i2pd_qt/DaemonQT.h
index 98e8b4e6..fc874f34 100644
--- a/qt/i2pd_qt/DaemonQT.h
+++ b/qt/i2pd_qt/DaemonQT.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
namespace i2p
{
@@ -32,6 +33,7 @@ namespace qt
bool isRunning();
private:
void setRunning(bool running);
+ void showError(std::string errorMsg);
private:
QMutex* mutex;
bool m_IsRunning;
@@ -55,7 +57,7 @@ namespace qt
void stopDaemon();
signals:
- void resultReady();
+ void resultReady(bool failed, QString failureMessage);
};
class Controller : public QObject
@@ -69,7 +71,11 @@ namespace qt
DaemonQTImpl& m_Daemon;
public slots:
- void handleResults(){}
+ void handleResults(bool failed, QString failureMessage){
+ if(failed){
+ QMessageBox::critical(0, QObject::tr("Error"), failureMessage);
+ }
+ }
signals:
void startDaemon();
void stopDaemon();
diff --git a/qt/i2pd_qt/MainWindowItems.cpp b/qt/i2pd_qt/MainWindowItems.cpp
new file mode 100644
index 00000000..c1e1ab0a
--- /dev/null
+++ b/qt/i2pd_qt/MainWindowItems.cpp
@@ -0,0 +1,2 @@
+#include "MainWindowItems.h"
+
diff --git a/qt/i2pd_qt/MainWindowItems.h b/qt/i2pd_qt/MainWindowItems.h
new file mode 100644
index 00000000..a4be5fe0
--- /dev/null
+++ b/qt/i2pd_qt/MainWindowItems.h
@@ -0,0 +1,17 @@
+#ifndef MAINWINDOWITEMS_H
+#define MAINWINDOWITEMS_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "mainwindow.h"
+
+class MainWindow;
+
+#endif // MAINWINDOWITEMS_H
diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp
new file mode 100644
index 00000000..d185be28
--- /dev/null
+++ b/qt/i2pd_qt/ServerTunnelPane.cpp
@@ -0,0 +1,275 @@
+#include "ServerTunnelPane.h"
+#include "ClientContext.h"
+#include "SignatureTypeComboboxFactory.h"
+
+ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf):
+ TunnelPane(tunnelsPageUpdateListener, tunconf) {}
+
+void ServerTunnelPane::setGroupBoxTitle(const QString & title) {
+ serverTunnelNameGroupBox->setTitle(title);
+}
+
+int ServerTunnelPane::appendServerTunnelForm(
+ ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
+
+ ServerTunnelPane& ui = *this;
+
+ serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
+ serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox"));
+
+ //tunnel
+ gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox);
+
+ QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
+ tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
+ tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER);
+ tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP);
+ tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC);
+ tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER);
+
+ int h=19*60;
+ gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
+ serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
+
+ {
+ const QString& type = tunnelConfig->getType();
+ int index=0;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index);
+ ++index;
+ }
+
+ setupTunnelPane(tunnelConfig,
+ serverTunnelNameGroupBox,
+ gridLayoutWidget_2, tunnelTypeComboBox,
+ tunnelsFormGridLayoutWidget, tunnelsRow, height, h);
+ //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10));
+
+ //host
+ ui.horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.hostLabel = new QLabel(gridLayoutWidget_2);
+ hostLabel->setObjectName(QStringLiteral("hostLabel"));
+ horizontalLayout_2->addWidget(hostLabel);
+ ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2);
+ hostLineEdit->setObjectName(QStringLiteral("hostLineEdit"));
+ hostLineEdit->setText(tunnelConfig->gethost().c_str());
+ QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(hostLineEdit);
+ ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(hostHorizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+
+ int gridIndex = 2;
+ {
+ int port = tunnelConfig->getport();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.portLabel = new QLabel(gridLayoutWidget_2);
+ portLabel->setObjectName(QStringLiteral("portLabel"));
+ horizontalLayout_2->addWidget(portLabel);
+ ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
+ portLineEdit->setObjectName(QStringLiteral("portLineEdit"));
+ portLineEdit->setText(QString::number(port));
+ portLineEdit->setMaximumWidth(80);
+ QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(portLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ std::string keys = tunnelConfig->getkeys();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.keysLabel = new QLabel(gridLayoutWidget_2);
+ keysLabel->setObjectName(QStringLiteral("keysLabel"));
+ horizontalLayout_2->addWidget(keysLabel);
+ ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2);
+ keysLineEdit->setObjectName(QStringLiteral("keysLineEdit"));
+ keysLineEdit->setText(keys.c_str());
+ QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(keysLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ int inPort = tunnelConfig->getinPort();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.inPortLabel = new QLabel(gridLayoutWidget_2);
+ inPortLabel->setObjectName(QStringLiteral("inPortLabel"));
+ horizontalLayout_2->addWidget(inPortLabel);
+ ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2);
+ inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit"));
+ inPortLineEdit->setText(QString::number(inPort));
+ inPortLineEdit->setMaximumWidth(80);
+ QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(inPortLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ std::string accessList = tunnelConfig->getaccessList();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.accessListLabel = new QLabel(gridLayoutWidget_2);
+ accessListLabel->setObjectName(QStringLiteral("accessListLabel"));
+ horizontalLayout_2->addWidget(accessListLabel);
+ ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2);
+ accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit"));
+ accessListLineEdit->setText(accessList.c_str());
+ QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(accessListLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ std::string hostOverride = tunnelConfig->gethostOverride();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2);
+ hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel"));
+ horizontalLayout_2->addWidget(hostOverrideLabel);
+ ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2);
+ hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit"));
+ hostOverrideLineEdit->setText(hostOverride.c_str());
+ QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(hostOverrideLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ std::string webIRCPass = tunnelConfig->getwebircpass();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2);
+ webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel"));
+ horizontalLayout_2->addWidget(webIRCPassLabel);
+ ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2);
+ webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit"));
+ webIRCPassLineEdit->setText(webIRCPass.c_str());
+ QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(webIRCPassLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ bool gzip = tunnelConfig->getgzip();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2);
+ gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox"));
+ gzipCheckBox->setChecked(gzip);
+ QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(gzipCheckBox);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
+ sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
+ horizontalLayout_2->addWidget(sigTypeLabel);
+ ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType);
+ sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox"));
+ QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(sigTypeComboBox);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ uint32_t maxConns = tunnelConfig->getmaxConns();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.maxConnsLabel = new QLabel(gridLayoutWidget_2);
+ maxConnsLabel->setObjectName(QStringLiteral("maxConnsLabel"));
+ horizontalLayout_2->addWidget(maxConnsLabel);
+ ui.maxConnsLineEdit = new QLineEdit(gridLayoutWidget_2);
+ maxConnsLineEdit->setObjectName(QStringLiteral("maxConnsLineEdit"));
+ maxConnsLineEdit->setText(QString::number(maxConns));
+ maxConnsLineEdit->setMaximumWidth(80);
+ QObject::connect(maxConnsLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(maxConnsLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ std::string address = tunnelConfig->getaddress();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.addressLabel = new QLabel(gridLayoutWidget_2);
+ addressLabel->setObjectName(QStringLiteral("addressLabel"));
+ horizontalLayout_2->addWidget(addressLabel);
+ ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2);
+ addressLineEdit->setObjectName(QStringLiteral("addressLineEdit"));
+ addressLineEdit->setText(address.c_str());
+ QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(addressLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ bool isUniqueLocal = tunnelConfig->getisUniqueLocal();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2);
+ isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox"));
+ isUniqueLocalCheckBox->setChecked(isUniqueLocal);
+ QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(isUniqueLocalCheckBox);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
+ appendControlsForI2CPParameters(i2cpParameters, gridIndex);
+ }
+
+ retranslateServerTunnelForm(ui);
+
+ tunnelGridLayout->invalidate();
+
+ return h;
+}
+
+void ServerTunnelPane::deleteServerTunnelForm() {
+ delete serverTunnelNameGroupBox;//->deleteLater();
+ serverTunnelNameGroupBox=nullptr;
+
+ //gridLayoutWidget_2->deleteLater();
+ //gridLayoutWidget_2=nullptr;
+}
+
+
+ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;}
+ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;}
diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h
new file mode 100644
index 00000000..a6994841
--- /dev/null
+++ b/qt/i2pd_qt/ServerTunnelPane.h
@@ -0,0 +1,161 @@
+#ifndef SERVERTUNNELPANE_H
+#define SERVERTUNNELPANE_H
+
+#include "TunnelPane.h"
+#include "TunnelsPageUpdateListener.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "QVBoxLayout"
+#include "QCheckBox"
+
+#include "assert.h"
+
+class ServerTunnelConfig;
+
+class ClientTunnelPane;
+
+class ServerTunnelPane : public TunnelPane {
+ Q_OBJECT
+
+public:
+ ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf);
+ virtual ~ServerTunnelPane(){}
+
+ virtual ServerTunnelPane* asServerTunnelPane();
+ virtual ClientTunnelPane* asClientTunnelPane();
+
+ int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
+ int tunnelsRow, int height);
+ void deleteServerTunnelForm();
+
+private:
+ QGroupBox *serverTunnelNameGroupBox;
+
+ //tunnel
+ QWidget *gridLayoutWidget_2;
+
+ //host
+ QHBoxLayout *horizontalLayout_2;
+ QLabel *hostLabel;
+ QLineEdit *hostLineEdit;
+ QSpacerItem *hostHorizontalSpacer;
+
+ //port
+ QLabel * portLabel;
+ QLineEdit * portLineEdit;
+
+ //keys
+ QLabel * keysLabel;
+ QLineEdit * keysLineEdit;
+
+ //inPort
+ QLabel * inPortLabel;
+ QLineEdit * inPortLineEdit;
+
+ //accessList
+ QLabel * accessListLabel;
+ QLineEdit * accessListLineEdit;
+
+ //hostOverride
+ QLabel * hostOverrideLabel;
+ QLineEdit * hostOverrideLineEdit;
+
+ //webIRCPass
+ QLabel * webIRCPassLabel;
+ QLineEdit * webIRCPassLineEdit;
+
+ //address
+ QLabel * addressLabel;
+ QLineEdit * addressLineEdit;
+
+ //maxConns
+ QLabel * maxConnsLabel;
+ QLineEdit * maxConnsLineEdit;
+
+ //gzip
+ QCheckBox * gzipCheckBox;
+
+ //isUniqueLocal
+ QCheckBox * isUniqueLocalCheckBox;
+
+ //sigType
+ QLabel * sigTypeLabel;
+ QComboBox * sigTypeComboBox;
+
+protected slots:
+ virtual void setGroupBoxTitle(const QString & title);
+
+private:
+ void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) {
+ typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0));
+ hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0));
+ portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0));
+ keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0));
+ inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0));
+ accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0));
+ hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
+ webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
+ addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0));
+ maxConnsLabel->setText(QApplication::translate("srvTunForm", "Max connections:", 0));
+
+ gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0));
+ isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0));
+
+ sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
+ }
+
+protected:
+ virtual bool applyDataFromUIToTunnelConfig() {
+ bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
+ if(!ok)return false;
+ ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig();
+ assert(stc!=nullptr);
+ stc->sethost(hostLineEdit->text().toStdString());
+
+ auto portStr=portLineEdit->text();
+ int portInt=portStr.toInt(&ok);
+ if(!ok)return false;
+ stc->setport(portInt);
+
+ stc->setkeys(keysLineEdit->text().toStdString());
+
+ auto str=inPortLineEdit->text();
+ int inPortInt=str.toInt(&ok);
+ if(!ok)return false;
+ stc->setinPort(inPortInt);
+
+ stc->setaccessList(accessListLineEdit->text().toStdString());
+
+ stc->sethostOverride(hostOverrideLineEdit->text().toStdString());
+
+ stc->setwebircpass(webIRCPassLineEdit->text().toStdString());
+
+ stc->setaddress(addressLineEdit->text().toStdString());
+
+ auto mcStr=maxConnsLineEdit->text();
+ uint32_t mcInt=(uint32_t)mcStr.toInt(&ok);
+ if(!ok)return false;
+ stc->setmaxConns(mcInt);
+
+ stc->setgzip(gzipCheckBox->isChecked());
+
+ stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked());
+
+ stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
+ }
+};
+
+#endif // SERVERTUNNELPANE_H
diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp b/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp
new file mode 100644
index 00000000..9313741a
--- /dev/null
+++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp
@@ -0,0 +1,2 @@
+#include "SignatureTypeComboboxFactory.h"
+
diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.h b/qt/i2pd_qt/SignatureTypeComboboxFactory.h
new file mode 100644
index 00000000..4d2289e1
--- /dev/null
+++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.h
@@ -0,0 +1,86 @@
+#ifndef SIGNATURETYPECOMBOBOXFACTORY_H
+#define SIGNATURETYPECOMBOBOXFACTORY_H
+
+#include
+#include
+#include
+#include "Identity.h"
+
+class SignatureTypeComboBoxFactory
+{
+ static const QVariant createUserData(const uint16_t sigType) {
+ return QVariant::fromValue((uint)sigType);
+ }
+
+ static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) {
+ const QVariant userData = createUserData(sigType);
+ signatureTypeCombobox->addItem(text, userData);
+ }
+
+public:
+ static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) {
+ QComboBox* signatureTypeCombobox = new QComboBox(parent);
+ /*
+ https://geti2p.net/spec/common-structures#certificate
+ все коды перечислены
+ это таблица "The defined Signing Public Key types are:" ?
+ да
+
+ see also: Identity.h line 55
+ */
+ int index=0;
+ bool foundSelected=false;
+
+ using namespace i2p::data;
+
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0
+ if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1
+ if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2
+ if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3
+ if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4
+ if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5
+ if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6
+ if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7
+ if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8
+ if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ // the following signature type should never appear in netid=2
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9
+ if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
+ if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ // TODO: remove later
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST); //65281
+ if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST); //65282
+ if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
+ ++index;
+ if(!foundSelected){
+ addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
+ signatureTypeCombobox->setCurrentIndex(index);
+ }
+
+ return signatureTypeCombobox;
+ }
+};
+
+#endif // SIGNATURETYPECOMBOBOXFACTORY_H
diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp
new file mode 100644
index 00000000..0de17486
--- /dev/null
+++ b/qt/i2pd_qt/TunnelConfig.cpp
@@ -0,0 +1,41 @@
+#include "TunnelConfig.h"
+
+void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) {
+ out << "[" << name << "]\n"
+ << "type=" << type.toStdString() << "\n";
+}
+
+void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) {
+ out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n"
+ << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n"
+ << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n"
+ << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n"
+ << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"
+ << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n\n";
+}
+
+void ClientTunnelConfig::saveToStringStream(std::stringstream& out) {
+ out << "address=" << address << "\n"
+ << "port=" << port << "\n"
+ << "destination=" << dest << "\n"
+ << "keys=" << keys << "\n"
+ << "destinationport=" << destinationPort << "\n"
+ << "signaturetype=" << sigType << "\n";
+}
+
+
+void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
+ out << "host=" << host << "\n"
+ << "port=" << port << "\n"
+ << "keys=" << keys << "\n"
+ << "signaturetype=" << sigType << "\n"
+ << "inport=" << inPort << "\n"
+ << "accesslist=" << accessList << "\n"
+ << "gzip=" << (gzip?"true":"false") << "\n"
+ << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
+ << "address=" << address << "\n"
+ << "hostoverride=" << hostOverride << "\n"
+ << "webircpassword=" << webircpass << "\n"
+ << "maxconns=" << maxConns << "\n";
+}
+
diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h
new file mode 100644
index 00000000..b91a318c
--- /dev/null
+++ b/qt/i2pd_qt/TunnelConfig.h
@@ -0,0 +1,230 @@
+#ifndef TUNNELCONFIG_H
+#define TUNNELCONFIG_H
+
+#include "QString"
+#include
+
+#include "../../libi2pd_client/ClientContext.h"
+#include "TunnelsPageUpdateListener.h"
+
+
+class I2CPParameters{
+ QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous
+ QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous
+ QString inbound_quantity; //number of inbound tunnels. 5 by default
+ QString outbound_quantity; //number of outbound tunnels. 5 by default
+ QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building
+ QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset
+public:
+ I2CPParameters(): inbound_length(),
+ outbound_length(),
+ inbound_quantity(),
+ outbound_quantity(),
+ crypto_tagsToSend(),
+ explicitPeers() {}
+ const QString& getInbound_length(){return inbound_length;}
+ const QString& getOutbound_length(){return outbound_length;}
+ const QString& getInbound_quantity(){return inbound_quantity;}
+ const QString& getOutbound_quantity(){return outbound_quantity;}
+ const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;}
+ const QString& getExplicitPeers(){return explicitPeers;}
+ void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;}
+ void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;}
+ void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;}
+ void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;}
+ void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;}
+ void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;}
+};
+
+
+class ClientTunnelConfig;
+class ServerTunnelConfig;
+class TunnelConfig {
+ /*
+ const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
+ const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
+ const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
+ const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
+ const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
+ const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
+ const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
+ const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
+ const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
+ */
+ QString type;
+ std::string name;
+public:
+ TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_):
+ type(type_), name(name_), i2cpParameters(i2cpParameters_) {}
+ virtual ~TunnelConfig(){}
+ const QString& getType(){return type;}
+ const std::string& getName(){return name;}
+ void setType(const QString& type_){type=type_;}
+ void setName(const std::string& name_){name=name_;}
+ I2CPParameters& getI2cpParameters(){return i2cpParameters;}
+ void saveHeaderToStringStream(std::stringstream& out);
+ void saveI2CPParametersToStringStream(std::stringstream& out);
+ virtual void saveToStringStream(std::stringstream& out)=0;
+ virtual ClientTunnelConfig* asClientTunnelConfig()=0;
+ virtual ServerTunnelConfig* asServerTunnelConfig()=0;
+
+private:
+ I2CPParameters i2cpParameters;
+};
+
+/*
+# mandatory parameters:
+ std::string dest;
+ if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
+ dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION);
+ int port = section.second.get (I2P_CLIENT_TUNNEL_PORT);
+# optional parameters (may be omitted)
+ std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
+ std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
+ int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
+ i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
+# * keys -- our identity, if unset, will be generated on every startup,
+# if set and file missing, keys will be generated and placed to this file
+# * address -- local interface to bind
+# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512)
+[somelabel]
+type = client
+address = 127.0.0.1
+port = 6668
+destination = irc.postman.i2p
+keys = irc-keys.dat
+*/
+class ClientTunnelConfig : public TunnelConfig {
+ std::string dest;
+ int port;
+ std::string keys;
+ std::string address;
+ int destinationPort;
+ i2p::data::SigningKeyType sigType;
+public:
+ ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
+ std::string dest_,
+ int port_,
+ std::string keys_,
+ std::string address_,
+ int destinationPort_,
+ i2p::data::SigningKeyType sigType_): TunnelConfig(name_, type_, i2cpParameters_),
+ dest(dest_),
+ port(port_),
+ keys(keys_),
+ address(address_),
+ destinationPort(destinationPort_),
+ sigType(sigType_){}
+ std::string& getdest(){return dest;}
+ int getport(){return port;}
+ std::string & getkeys(){return keys;}
+ std::string & getaddress(){return address;}
+ int getdestinationPort(){return destinationPort;}
+ i2p::data::SigningKeyType getsigType(){return sigType;}
+ void setdest(const std::string& dest_){dest=dest_;}
+ void setport(int port_){port=port_;}
+ void setkeys(const std::string & keys_){keys=keys_;}
+ void setaddress(const std::string & address_){address=address_;}
+ void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;}
+ void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
+ virtual void saveToStringStream(std::stringstream& out);
+ virtual ClientTunnelConfig* asClientTunnelConfig(){return this;}
+ virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;}
+};
+
+/*
+# mandatory parameters:
+# * host -- ip address of our service
+# * port -- port of our service
+# * keys -- file with LeaseSet of address in i2p
+ std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST);
+ int port = section.second.get (I2P_SERVER_TUNNEL_PORT);
+ std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS);
+# optional parameters (may be omitted)
+ int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
+ std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
+ std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
+ std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
+ bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
+ i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
+ uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
+ std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
+ bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
+# * inport -- optional, i2p service port, if unset - the same as 'port'
+# * accesslist -- comma-separated list of i2p addresses, allowed to connect
+# every address is b32 without '.b32.i2p' part
+[somelabel]
+type = server
+host = 127.0.0.1
+port = 6667
+keys = irc.dat
+*/
+class ServerTunnelConfig : public TunnelConfig {
+ std::string host;
+ int port;
+ std::string keys;
+ int inPort;
+ std::string accessList;
+ std::string hostOverride;
+ std::string webircpass;
+ bool gzip;
+ i2p::data::SigningKeyType sigType;
+ uint32_t maxConns;
+ std::string address;
+ bool isUniqueLocal;
+public:
+ ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
+ std::string host_,
+ int port_,
+ std::string keys_,
+ int inPort_,
+ std::string accessList_,
+ std::string hostOverride_,
+ std::string webircpass_,
+ bool gzip_,
+ i2p::data::SigningKeyType sigType_,
+ uint32_t maxConns_,
+ std::string address_,
+ bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_),
+ host(host_),
+ port(port_),
+ keys(keys_),
+ inPort(inPort_),
+ accessList(accessList_),
+ hostOverride(hostOverride_),
+ webircpass(webircpass_),
+ gzip(gzip_),
+ sigType(sigType_),
+ maxConns(maxConns_),
+ address(address_) {}
+ std::string& gethost(){return host;}
+ int getport(){return port;}
+ std::string& getkeys(){return keys;}
+ int getinPort(){return inPort;}
+ std::string& getaccessList(){return accessList;}
+ std::string& gethostOverride(){return hostOverride;}
+ std::string& getwebircpass(){return webircpass;}
+ bool getgzip(){return gzip;}
+ i2p::data::SigningKeyType getsigType(){return sigType;}
+ uint32_t getmaxConns(){return maxConns;}
+ std::string& getaddress(){return address;}
+ bool getisUniqueLocal(){return isUniqueLocal;}
+ void sethost(const std::string& host_){host=host_;}
+ void setport(int port_){port=port_;}
+ void setkeys(const std::string& keys_){keys=keys_;}
+ void setinPort(int inPort_){inPort=inPort_;}
+ void setaccessList(const std::string& accessList_){accessList=accessList_;}
+ void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;}
+ void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;}
+ void setgzip(bool gzip_){gzip=gzip_;}
+ void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
+ void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;}
+ void setaddress(const std::string& address_){address=address_;}
+ void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;}
+ virtual void saveToStringStream(std::stringstream& out);
+ virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;}
+ virtual ServerTunnelConfig* asServerTunnelConfig(){return this;}
+};
+
+
+#endif // TUNNELCONFIG_H
diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp
new file mode 100644
index 00000000..0dda5185
--- /dev/null
+++ b/qt/i2pd_qt/TunnelPane.cpp
@@ -0,0 +1,217 @@
+#include "TunnelPane.h"
+#include "QMessageBox"
+
+TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_):
+ QObject(),
+ tunnelConfig(tunnelConfig_),
+ tunnelsPageUpdateListener(tunnelsPageUpdateListener_),
+ gridLayoutWidget_2(nullptr) {}
+
+void TunnelPane::setupTunnelPane(
+ TunnelConfig* tunnelConfig,
+ QGroupBox *tunnelGroupBox,
+ QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
+ QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) {
+ tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h);
+ tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h);
+
+ QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(updated()));
+
+
+ this->tunnelGroupBox=tunnelGroupBox;
+
+ gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2"));
+ this->gridLayoutWidget_2=gridLayoutWidget_2;
+ tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2);
+ tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout"));
+ tunnelGridLayout->setContentsMargins(5, 5, 5, 5);
+ tunnelGridLayout->setSpacing(5);
+
+ //header
+ QHBoxLayout *headerHorizontalLayout = new QHBoxLayout();
+ headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout"));
+
+ nameLabel = new QLabel(gridLayoutWidget_2);
+ nameLabel->setObjectName(QStringLiteral("nameLabel"));
+ headerHorizontalLayout->addWidget(nameLabel);
+ nameLineEdit = new QLineEdit(gridLayoutWidget_2);
+ nameLineEdit->setObjectName(QStringLiteral("nameLineEdit"));
+ const QString& tunnelName=tunnelConfig->getName().c_str();
+ nameLineEdit->setText(tunnelName);
+ setGroupBoxTitle(tunnelName);
+
+ QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(setGroupBoxTitle(const QString &)));
+ QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+
+ headerHorizontalLayout->addWidget(nameLineEdit);
+ headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ headerHorizontalLayout->addItem(headerHorizontalSpacer);
+ deletePushButton = new QPushButton(gridLayoutWidget_2);
+ deletePushButton->setObjectName(QStringLiteral("deletePushButton"));
+ QObject::connect(deletePushButton, SIGNAL(released()),
+ this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) {
+ headerHorizontalLayout->addWidget(deletePushButton);
+ tunnelGridLayout->addLayout(headerHorizontalLayout);
+
+ //type
+ {
+ const QString& type = tunnelConfig->getType();
+ QHBoxLayout * horizontalLayout_ = new QHBoxLayout();
+ horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_"));
+ typeLabel = new QLabel(gridLayoutWidget_2);
+ typeLabel->setObjectName(QStringLiteral("typeLabel"));
+ horizontalLayout_->addWidget(typeLabel);
+ horizontalLayout_->addWidget(tunnelTypeComboBox);
+ this->tunnelTypeComboBox=tunnelTypeComboBox;
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_);
+ }
+
+ retranslateTunnelForm(*this);
+}
+
+void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) {
+ {
+ //number of hops of an inbound tunnel
+ const QString& inbound_length=i2cpParameters.getInbound_length();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ inbound_lengthLabel = new QLabel(gridLayoutWidget_2);
+ inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel"));
+ horizontalLayout_2->addWidget(inbound_lengthLabel);
+ inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
+ inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit"));
+ inbound_lengthLineEdit->setText(inbound_length);
+ inbound_lengthLineEdit->setMaximumWidth(80);
+ QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(inbound_lengthLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ //number of hops of an outbound tunnel
+ const QString& outbound_length=i2cpParameters.getOutbound_length();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ outbound_lengthLabel = new QLabel(gridLayoutWidget_2);
+ outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel"));
+ horizontalLayout_2->addWidget(outbound_lengthLabel);
+ outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
+ outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit"));
+ outbound_lengthLineEdit->setText(outbound_length);
+ outbound_lengthLineEdit->setMaximumWidth(80);
+ QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(outbound_lengthLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ //number of inbound tunnels
+ const QString& inbound_quantity=i2cpParameters.getInbound_quantity();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ inbound_quantityLabel = new QLabel(gridLayoutWidget_2);
+ inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel"));
+ horizontalLayout_2->addWidget(inbound_quantityLabel);
+ inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
+ inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit"));
+ inbound_quantityLineEdit->setText(inbound_quantity);
+ inbound_quantityLineEdit->setMaximumWidth(80);
+ QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(inbound_quantityLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ //number of outbound tunnels
+ const QString& outbound_quantity=i2cpParameters.getOutbound_quantity();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ outbound_quantityLabel = new QLabel(gridLayoutWidget_2);
+ outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel"));
+ horizontalLayout_2->addWidget(outbound_quantityLabel);
+ outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
+ outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit"));
+ outbound_quantityLineEdit->setText(outbound_quantity);
+ outbound_quantityLineEdit->setMaximumWidth(80);
+ QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(outbound_quantityLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+ {
+ //number of ElGamal/AES tags to send
+ const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend();
+ QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2);
+ crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel"));
+ horizontalLayout_2->addWidget(crypto_tagsToSendLabel);
+ crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2);
+ crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit"));
+ crypto_tagsToSendLineEdit->setText(crypto_tagsToSend);
+ crypto_tagsToSendLineEdit->setMaximumWidth(80);
+ QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(updated()));
+ horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit);
+ QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout_2->addItem(horizontalSpacer);
+ tunnelGridLayout->addLayout(horizontalLayout_2);
+ }
+
+ retranslateI2CPParameters();
+}
+
+void TunnelPane::updated() {
+ std::string oldName=tunnelConfig->getName();
+ if(!applyDataFromUIToTunnelConfig())return;//TODO visualise bad input
+ tunnelsPageUpdateListener->updated(oldName, tunnelConfig);
+}
+
+void TunnelPane::deleteButtonReleased() {
+ QMessageBox msgBox;
+ msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?"));
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ int ret = msgBox.exec();
+ switch (ret) {
+ case QMessageBox::Ok:
+ // OK was clicked
+ tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName());
+ break;
+ case QMessageBox::Cancel:
+ // Cancel was clicked
+ return;
+ }
+}
+
+/*
+const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
+const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
+const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
+const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
+const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
+const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
+const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
+const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
+const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
+*/
+QString TunnelPane::readTunnelTypeComboboxData() {
+ return tunnelTypeComboBox->currentData().toString();
+}
+
+i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) {
+ return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt();
+}
diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h
new file mode 100644
index 00000000..d0a3d6a8
--- /dev/null
+++ b/qt/i2pd_qt/TunnelPane.h
@@ -0,0 +1,121 @@
+#ifndef TUNNELPANE_H
+#define TUNNELPANE_H
+
+#include "QObject"
+#include "QWidget"
+#include "QComboBox"
+#include "QGridLayout"
+#include "QLabel"
+#include "QPushButton"
+#include "QApplication"
+#include "QLineEdit"
+#include "QGroupBox"
+#include "QVBoxLayout"
+
+#include "TunnelConfig.h"
+
+class ServerTunnelPane;
+class ClientTunnelPane;
+
+class TunnelConfig;
+class I2CPParameters;
+
+class TunnelPane : public QObject {
+
+ Q_OBJECT
+
+public:
+ TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf);
+ virtual ~TunnelPane(){}
+
+ virtual ServerTunnelPane* asServerTunnelPane()=0;
+ virtual ClientTunnelPane* asClientTunnelPane()=0;
+
+protected:
+ TunnelConfig* tunnelConfig;
+ TunnelsPageUpdateListener* tunnelsPageUpdateListener;
+ QVBoxLayout *tunnelGridLayout;
+ QGroupBox *tunnelGroupBox;
+ QWidget* gridLayoutWidget_2;
+
+ //header
+ QLabel *nameLabel;
+ QLineEdit *nameLineEdit;
+public:
+ QLineEdit * getNameLineEdit() { return nameLineEdit; }
+
+public slots:
+ void updated();
+ void deleteButtonReleased();
+
+protected:
+ QSpacerItem *headerHorizontalSpacer;
+ QPushButton *deletePushButton;
+
+ //type
+ QComboBox *tunnelTypeComboBox;
+ QLabel *typeLabel;
+
+ //i2cp
+
+ QLabel * inbound_lengthLabel;
+ QLineEdit * inbound_lengthLineEdit;
+
+ QLabel * outbound_lengthLabel;
+ QLineEdit * outbound_lengthLineEdit;
+
+ QLabel * inbound_quantityLabel;
+ QLineEdit * inbound_quantityLineEdit;
+
+ QLabel * outbound_quantityLabel;
+ QLineEdit * outbound_quantityLineEdit;
+
+ QLabel * crypto_tagsToSendLabel;
+ QLineEdit * crypto_tagsToSendLineEdit;
+
+ QString readTunnelTypeComboboxData();
+
+ //should be created by factory
+ i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox);
+
+ //returns false when invalid data at UI
+ virtual bool applyDataFromUIToTunnelConfig() {
+ tunnelConfig->setName(nameLineEdit->text().toStdString());
+ tunnelConfig->setType(readTunnelTypeComboboxData());
+ I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters();
+ i2cpParams.setInbound_length(inbound_lengthLineEdit->text());
+ i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text());
+ i2cpParams.setOutbound_length(outbound_lengthLineEdit->text());
+ i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text());
+ i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text());
+ }
+
+ void setupTunnelPane(
+ TunnelConfig* tunnelConfig,
+ QGroupBox *tunnelGroupBox,
+ QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
+ QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h);
+ void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex);
+public:
+ int height() {
+ return gridLayoutWidget_2?gridLayoutWidget_2->height():0;
+ }
+
+protected slots:
+ virtual void setGroupBoxTitle(const QString & title)=0;
+private:
+ void retranslateTunnelForm(TunnelPane& ui) {
+ ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0));
+ ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0));
+ }
+
+ void retranslateI2CPParameters() {
+ inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));;
+ outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));;
+ inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));;
+ outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));;
+ crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));;
+ }
+};
+
+#endif // TUNNELPANE_H
diff --git a/qt/i2pd_qt/TunnelsPageUpdateListener.h b/qt/i2pd_qt/TunnelsPageUpdateListener.h
new file mode 100644
index 00000000..83b4e9fe
--- /dev/null
+++ b/qt/i2pd_qt/TunnelsPageUpdateListener.h
@@ -0,0 +1,12 @@
+#ifndef TUNNELSPAGEUPDATELISTENER_H
+#define TUNNELSPAGEUPDATELISTENER_H
+
+class TunnelConfig;
+
+class TunnelsPageUpdateListener {
+public:
+ virtual void updated(std::string oldName, TunnelConfig* tunConf)=0;
+ virtual void needsDeleting(std::string oldName)=0;
+};
+
+#endif // TUNNELSPAGEUPDATELISTENER_H
diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro
index 229d3f2e..66839ff5 100644
--- a/qt/i2pd_qt/i2pd_qt.pro
+++ b/qt/i2pd_qt/i2pd_qt.pro
@@ -24,60 +24,170 @@ IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs
# 2) Check API 11
# Finally, click Install.
-SOURCES += DaemonQT.cpp mainwindow.cpp
-# ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \
-# ../../AddressBook.cpp ../../api.cpp ../../Base.cpp ../../BOB.cpp ../../ClientContext.cpp \
-# ../../Crypto.cpp ../../Datagram.cpp ../../Destination.cpp ../../Family.cpp ../../FS.cpp \
-# ../../Garlic.cpp ../../HTTP.cpp ../../HTTPProxy.cpp ../../I2CP.cpp ../../I2NPProtocol.cpp \
-# ../../I2PEndian.cpp ../../I2PService.cpp ../../I2PTunnel.cpp ../../Identity.cpp \
-# ../../LeaseSet.cpp ../../Log.cpp ../../NetDb.cpp ../../NetDbRequests.cpp \
-# ../../NTCPSession.cpp ../../Profiling.cpp ../../Reseed.cpp ../../RouterContext.cpp \
-# ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \
-# ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
-# ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
-# ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \
-# ../../Event.cpp ../../BloomFiler.cpp ../../Gost.cpp ../../MatchedDestination.cpp \
-# ../../i2pd.cpp
+SOURCES += DaemonQT.cpp mainwindow.cpp \
+ ../../libi2pd/api.cpp \
+ ../../libi2pd/Base.cpp \
+ ../../libi2pd/BloomFilter.cpp \
+ ../../libi2pd/Config.cpp \
+ ../../libi2pd/Crypto.cpp \
+ ../../libi2pd/Datagram.cpp \
+ ../../libi2pd/Destination.cpp \
+ ../../libi2pd/Event.cpp \
+ ../../libi2pd/Family.cpp \
+ ../../libi2pd/FS.cpp \
+ ../../libi2pd/Garlic.cpp \
+ ../../libi2pd/Gost.cpp \
+ ../../libi2pd/Gzip.cpp \
+ ../../libi2pd/HTTP.cpp \
+ ../../libi2pd/I2NPProtocol.cpp \
+ ../../libi2pd/I2PEndian.cpp \
+ ../../libi2pd/Identity.cpp \
+ ../../libi2pd/LeaseSet.cpp \
+ ../../libi2pd/Log.cpp \
+ ../../libi2pd/NetDb.cpp \
+ ../../libi2pd/NetDbRequests.cpp \
+ ../../libi2pd/NTCPSession.cpp \
+ ../../libi2pd/Profiling.cpp \
+ ../../libi2pd/Reseed.cpp \
+ ../../libi2pd/RouterContext.cpp \
+ ../../libi2pd/RouterInfo.cpp \
+ ../../libi2pd/Signature.cpp \
+ ../../libi2pd/SSU.cpp \
+ ../../libi2pd/SSUData.cpp \
+ ../../libi2pd/SSUSession.cpp \
+ ../../libi2pd/Streaming.cpp \
+ ../../libi2pd/Timestamp.cpp \
+ ../../libi2pd/TransitTunnel.cpp \
+ ../../libi2pd/Transports.cpp \
+ ../../libi2pd/Tunnel.cpp \
+ ../../libi2pd/TunnelEndpoint.cpp \
+ ../../libi2pd/TunnelGateway.cpp \
+ ../../libi2pd/TunnelPool.cpp \
+ ../../libi2pd/util.cpp \
+ ../../libi2pd_client/AddressBook.cpp \
+ ../../libi2pd_client/BOB.cpp \
+ ../../libi2pd_client/ClientContext.cpp \
+ ../../libi2pd_client/HTTPProxy.cpp \
+ ../../libi2pd_client/I2CP.cpp \
+ ../../libi2pd_client/I2PService.cpp \
+ ../../libi2pd_client/I2PTunnel.cpp \
+ ../../libi2pd_client/MatchedDestination.cpp \
+ ../../libi2pd_client/SAM.cpp \
+ ../../libi2pd_client/SOCKS.cpp \
+ ../../libi2pd_client/Websocket.cpp \
+ ../../libi2pd_client/WebSocks.cpp \
+ ClientTunnelPane.cpp \
+ MainWindowItems.cpp \
+ ServerTunnelPane.cpp \
+ SignatureTypeComboboxFactory.cpp \
+ TunnelConfig.cpp \
+ TunnelPane.cpp \
+ ../../daemon/Daemon.cpp \
+ ../../daemon/HTTPServer.cpp \
+ ../../daemon/i2pd.cpp \
+ ../../daemon/I2PControl.cpp \
+ ../../daemon/UnixDaemon.cpp \
+ ../../daemon/UPnP.cpp
-SOURCES += $$files(../../libi2pd/*.cpp)
-SOURCES += $$files(../../libi2pd_client/*.cpp)
-SOURCES += $$files(../../daemon/*.cpp)
+#qt creator does not handle this well
+#SOURCES += $$files(../../libi2pd/*.cpp)
+#SOURCES += $$files(../../libi2pd_client/*.cpp)
+#SOURCES += $$files(../../daemon/*.cpp)
+#SOURCES += $$files(./*.cpp)
SOURCES -= ../../daemon/UnixDaemon.cpp
-HEADERS += DaemonQT.h mainwindow.h
-# ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
-# ../../AddressBook.h ../../api.h ../../Base.h ../../BOB.h ../../ClientContext.h \
-# ../../Crypto.h ../../Datagram.h ../../Destination.h ../../Family.h ../../FS.h \
-# ../../Garlic.h ../../HTTP.h ../../HTTPProxy.h ../../I2CP.h ../../I2NPProtocol.h \
-# ../../I2PEndian.h ../../I2PService.h ../../I2PTunnel.h ../../Identity.h ../../LeaseSet.h \
-# ../../LittleBigEndian.h ../../Log.h ../../NetDb.h ../../NetDbRequests.h ../../NTCPSession.h \
-# ../../Profiling.h ../../Queue.h ../../Reseed.h ../../RouterContext.h ../../RouterInfo.h \
-# ../../SAM.h ../../Signature.h ../../SOCKS.h ../../SSU.h ../../SSUData.h ../../SSUSession.h \
-# ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
-# ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
-# ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
-# ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \
-# ../../BloomFiler.h ../../Event.h ../../Gost.h ../../MatchedDestination.h
+HEADERS += DaemonQT.h mainwindow.h \
+ ../../libi2pd/api.h \
+ ../../libi2pd/Base.h \
+ ../../libi2pd/BloomFilter.h \
+ ../../libi2pd/Config.h \
+ ../../libi2pd/Crypto.h \
+ ../../libi2pd/Datagram.h \
+ ../../libi2pd/Destination.h \
+ ../../libi2pd/Event.h \
+ ../../libi2pd/Family.h \
+ ../../libi2pd/FS.h \
+ ../../libi2pd/Garlic.h \
+ ../../libi2pd/Gost.h \
+ ../../libi2pd/Gzip.h \
+ ../../libi2pd/HTTP.h \
+ ../../libi2pd/I2NPProtocol.h \
+ ../../libi2pd/I2PEndian.h \
+ ../../libi2pd/Identity.h \
+ ../../libi2pd/LeaseSet.h \
+ ../../libi2pd/LittleBigEndian.h \
+ ../../libi2pd/Log.h \
+ ../../libi2pd/NetDb.hpp \
+ ../../libi2pd/NetDbRequests.h \
+ ../../libi2pd/NTCPSession.h \
+ ../../libi2pd/Profiling.h \
+ ../../libi2pd/Queue.h \
+ ../../libi2pd/Reseed.h \
+ ../../libi2pd/RouterContext.h \
+ ../../libi2pd/RouterInfo.h \
+ ../../libi2pd/Signature.h \
+ ../../libi2pd/SSU.h \
+ ../../libi2pd/SSUData.h \
+ ../../libi2pd/SSUSession.h \
+ ../../libi2pd/Streaming.h \
+ ../../libi2pd/Tag.h \
+ ../../libi2pd/Timestamp.h \
+ ../../libi2pd/TransitTunnel.h \
+ ../../libi2pd/Transports.h \
+ ../../libi2pd/TransportSession.h \
+ ../../libi2pd/Tunnel.h \
+ ../../libi2pd/TunnelBase.h \
+ ../../libi2pd/TunnelConfig.h \
+ ../../libi2pd/TunnelEndpoint.h \
+ ../../libi2pd/TunnelGateway.h \
+ ../../libi2pd/TunnelPool.h \
+ ../../libi2pd/util.h \
+ ../../libi2pd/version.h \
+ ../../libi2pd_client/AddressBook.h \
+ ../../libi2pd_client/BOB.h \
+ ../../libi2pd_client/ClientContext.h \
+ ../../libi2pd_client/HTTPProxy.h \
+ ../../libi2pd_client/I2CP.h \
+ ../../libi2pd_client/I2PService.h \
+ ../../libi2pd_client/I2PTunnel.h \
+ ../../libi2pd_client/MatchedDestination.h \
+ ../../libi2pd_client/SAM.h \
+ ../../libi2pd_client/SOCKS.h \
+ ../../libi2pd_client/Websocket.h \
+ ../../libi2pd_client/WebSocks.h \
+ ClientTunnelPane.h \
+ MainWindowItems.h \
+ ServerTunnelPane.h \
+ SignatureTypeComboboxFactory.h \
+ TunnelConfig.h \
+ TunnelPane.h \
+ TunnelsPageUpdateListener.h \
+ ../../daemon/Daemon.h \
+ ../../daemon/HTTPServer.h \
+ ../../daemon/I2PControl.h \
+ ../../daemon/UPnP.h
INCLUDEPATH += ../../libi2pd
INCLUDEPATH += ../../libi2pd_client
INCLUDEPATH += ../../daemon
+INCLUDEPATH += .
-FORMS += mainwindow.ui
-
-CONFIG += mobility
-
-MOBILITY =
+FORMS += mainwindow.ui \
+ tunnelform.ui
LIBS += -lz
android {
message("Using Android settings")
- DEFINES += ANDROID=1
+ DEFINES += ANDROID=1
DEFINES += __ANDROID__
- INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
+ CONFIG += mobility
+
+ MOBILITY =
+
+ INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
$$OPENSSL_PATH/openssl-1.0.2/include \
$$MINIUPNP_PATH/miniupnp-2.0/include \
$$IFADDRS_PATH
@@ -138,3 +248,4 @@ linux:!android {
QT += xml
#INSTALLS += sources
}
+
diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp
index 4b749473..304a3758 100644
--- a/qt/i2pd_qt/mainwindow.cpp
+++ b/qt/i2pd_qt/mainwindow.cpp
@@ -1,63 +1,214 @@
#include "mainwindow.h"
-//#include "ui_mainwindow.h"
+#include "ui_mainwindow.h"
#include
#include
+#include
+#include
#include "RouterContext.h"
+#include "Config.h"
+#include "FS.h"
+#include "Log.h"
+
#ifndef ANDROID
-#include
+# include
#endif
+#include
+
+#include
+
+std::string programOptionsWriterCurrentSection;
+
MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent)/*,
- ui(new Ui::MainWindow)*/
+ QMainWindow(parent)
#ifndef ANDROID
,quitting(false)
#endif
+ ,ui(new Ui::MainWindow)
+ ,configItems()
+ ,datadir()
+ ,confpath()
+ ,tunconfpath()
+ ,tunnelsPageUpdateListener(this)
+
{
- //ui->setupUi(this);
- if (objectName().isEmpty())
- setObjectName(QStringLiteral("MainWindow"));
- resize(800, 480);
- centralWidget = new QWidget(this);
- centralWidget->setObjectName(QStringLiteral("centralWidget"));
- verticalLayoutWidget = new QWidget(centralWidget);
- verticalLayoutWidget->setObjectName(QStringLiteral("verticalLayoutWidget"));
- //verticalLayoutWidget->setGeometry(QRect(10, 20, 771, 441));
- verticalLayout1 = new QVBoxLayout(verticalLayoutWidget);
- verticalLayout1->setSpacing(6);
- verticalLayout1->setContentsMargins(11, 11, 11, 11);
- verticalLayout1->setObjectName(QStringLiteral("verticalLayout1"));
- verticalLayout1->setContentsMargins(0, 0, 0, 0);
- quitButton = new QPushButton(verticalLayoutWidget);
- quitButton->setObjectName(QStringLiteral("quitButton"));
- QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
- sizePolicy.setHorizontalStretch(1);
- //sizePolicy.setVerticalStretch(1);
- sizePolicy.setHeightForWidth(quitButton->sizePolicy().hasHeightForWidth());
- quitButton->setSizePolicy(sizePolicy);
- verticalLayout1->addWidget(quitButton);
- gracefulQuitButton = new QPushButton(verticalLayoutWidget);
- gracefulQuitButton->setObjectName(QStringLiteral("gracefulQuitButton"));
- QSizePolicy sizePolicy2(QSizePolicy::Maximum, QSizePolicy::Maximum);
- sizePolicy2.setHorizontalStretch(1);
- //sizePolicy2.setVerticalStretch(1);
- sizePolicy2.setHeightForWidth(gracefulQuitButton->sizePolicy().hasHeightForWidth());
- gracefulQuitButton->setSizePolicy(sizePolicy2);
- verticalLayout1->addWidget(gracefulQuitButton);
+ ui->setupUi(this);
+ setWindowTitle(QApplication::translate("AppTitle","I2PD"));
- setCentralWidget(centralWidget);
+ //TODO handle resizes and change the below into resize() call
+ setFixedSize(width(), 480);
+ ui->centralWidget->setMinimumHeight(480);
+ ui->centralWidget->setMaximumHeight(480);
+ onResize();
- setWindowTitle(QApplication::translate("MainWindow", "i2pd", 0));
- quitButton->setText(QApplication::translate("MainWindow", "Quit", 0));
- gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful Quit", 0));
+ ui->stackedWidget->setCurrentIndex(0);
+ ui->settingsScrollArea->resize(ui->settingsContentsGridLayout->sizeHint().width()+10,380);
+ QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar();
+ //QSize szSettContents = ui->settingsContentsGridLayout->minimumSize();
+ int w = 683;
+ int h = 3060;
+ ui->settingsContents->setFixedSize(w, h);
+ //ui->settingsContents->resize(w, h);
+ //ui->settingsContents->adjustSize();
+
+ /*
+ QPalette pal(palette());
+ pal.setColor(QPalette::Background, Qt::red);
+ ui->settingsContents->setAutoFillBackground(true);
+ ui->settingsContents->setPalette(pal);
+ */
+
+ //ui->settingsScrollArea->adjustSize();
+ /*ui->tunnelsScrollAreaWidgetContents->setFixedSize(
+ ui->tunnelsScrollArea->width() - barSett->width(), 0);*/
#ifndef ANDROID
createActions();
createTrayIcon();
#endif
- QObject::connect(quitButton, SIGNAL(released()), this, SLOT(handleQuitButton()));
- QObject::connect(gracefulQuitButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton()));
+ QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusPage()));
+ QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage()));
+
+ QObject::connect(ui->tunnelsPagePushButton, SIGNAL(released()), this, SLOT(showTunnelsPage()));
+ QObject::connect(ui->restartPagePushButton, SIGNAL(released()), this, SLOT(showRestartPage()));
+ QObject::connect(ui->quitPagePushButton, SIGNAL(released()), this, SLOT(showQuitPage()));
+
+ QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton()));
+ QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton()));
+
+# define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option))
+
+ initFileChooser( OPTION("","conf",[](){return "";}), ui->configFileLineEdit, ui->configFileBrowsePushButton);
+ initFolderChooser( OPTION("","datadir",[]{return "";}), ui->dataFolderLineEdit, ui->dataFolderBrowsePushButton);
+ initFileChooser( OPTION("","tunconf",[](){return "";}), ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton);
+
+ initFileChooser( OPTION("","pidfile",[]{return "";}), ui->pidFileLineEdit, ui->pidFileBrowsePushButton);
+ logOption=initNonGUIOption( OPTION("","log",[]{return "";}));
+ daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";}));
+ serviceOption=initNonGUIOption( OPTION("","service",[]{return "";}));
+
+ logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), ui->logFileLineEdit, ui->logFileBrowsePushButton);
+ initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), ui->logLevelComboBox);
+
+ initIPAddressBox( OPTION("","host",[]{return "";}), ui->routerExternalHostLineEdit, tr("Router external address -> Host"));
+ initTCPPortBox( OPTION("","port",[]{return "";}), ui->routerExternalPortLineEdit, tr("Router external address -> Port"));
+
+ initCheckBox( OPTION("","ipv6",[]{return "false";}), ui->ipv6CheckBox);
+ initCheckBox( OPTION("","notransit",[]{return "false";}), ui->notransitCheckBox);
+ initCheckBox( OPTION("","floodfill",[]{return "false";}), ui->floodfillCheckBox);
+ initStringBox( OPTION("","bandwidth",[]{return "";}), ui->bandwidthLineEdit);
+ initStringBox( OPTION("","family",[]{return "";}), ui->familyLineEdit);
+ initIntegerBox( OPTION("","netid",[]{return "2";}), ui->netIdLineEdit, tr("NetID"));
+
+#ifdef Q_OS_WIN
+ initCheckBox( OPTION("","insomnia",[]{return "";}), ui->insomniaCheckBox);
+ initNonGUIOption( OPTION("","svcctl",[]{return "";}));
+ initNonGUIOption( OPTION("","close",[]{return "";}));
+#else
+ ui->insomniaCheckBox->setEnabled(false);
+#endif
+
+ initCheckBox( OPTION("http","enabled",[]{return "true";}), ui->webconsoleEnabledCheckBox);
+ initIPAddressBox( OPTION("http","address",[]{return "";}), ui->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address"));
+ initTCPPortBox( OPTION("http","port",[]{return "7070";}), ui->webconsolePortLineEdit, tr("HTTP webconsole -> Port"));
+ initCheckBox( OPTION("http","auth",[]{return "";}), ui->webconsoleBasicAuthCheckBox);
+ initStringBox( OPTION("http","user",[]{return "i2pd";}), ui->webconsoleUserNameLineEditBasicAuth);
+ initStringBox( OPTION("http","pass",[]{return "";}), ui->webconsolePasswordLineEditBasicAuth);
+
+ initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), ui->httpProxyEnabledCheckBox);
+ initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), ui->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address"));
+ initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), ui->httpProxyPortLineEdit, tr("HTTP proxy -> Port"));
+ initFileChooser( OPTION("httpproxy","keys",[]{return "";}), ui->httpProxyKeyFileLineEdit, ui->httpProxyKeyFilePushButton);
+ initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), ui->comboBox_httpPorxySignatureType);
+ initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), ui->httpProxyInboundTunnelsLenLineEdit);
+ initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), ui->httpProxyInboundTunnQuantityLineEdit);
+ initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), ui->httpProxyOutBoundTunnLenLineEdit);
+ initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), ui->httpProxyOutboundTunnQuantityLineEdit);
+
+ initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), ui->socksProxyEnabledCheckBox);
+ initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), ui->socksProxyAddressLineEdit, tr("Socks proxy -> IP address"));
+ initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), ui->socksProxyPortLineEdit, tr("Socks proxy -> Port"));
+ initFileChooser( OPTION("socksproxy","keys",[]{return "";}), ui->socksProxyKeyFileLineEdit, ui->socksProxyKeyFilePushButton);
+ initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), ui->comboBox_socksProxySignatureType);
+ initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), ui->socksProxyInboundTunnelsLenLineEdit);
+ initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), ui->socksProxyInboundTunnQuantityLineEdit);
+ initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), ui->socksProxyOutBoundTunnLenLineEdit);
+ initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), ui->socksProxyOutboundTunnQuantityLineEdit);
+ initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), ui->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address"));
+ initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), ui->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port"));
+
+ initCheckBox( OPTION("sam","enabled",[]{return "false";}), ui->samEnabledCheckBox);
+ initIPAddressBox( OPTION("sam","address",[]{return "";}), ui->samAddressLineEdit, tr("SAM -> IP address"));
+ initTCPPortBox( OPTION("sam","port",[]{return "7656";}), ui->samPortLineEdit, tr("SAM -> Port"));
+
+ initCheckBox( OPTION("bob","enabled",[]{return "false";}), ui->bobEnabledCheckBox);
+ initIPAddressBox( OPTION("bob","address",[]{return "";}), ui->bobAddressLineEdit, tr("BOB -> IP address"));
+ initTCPPortBox( OPTION("bob","port",[]{return "2827";}), ui->bobPortLineEdit, tr("BOB -> Port"));
+
+ initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), ui->i2cpEnabledCheckBox);
+ initIPAddressBox( OPTION("i2cp","address",[]{return "";}), ui->i2cpAddressLineEdit, tr("I2CP -> IP address"));
+ initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), ui->i2cpPortLineEdit, tr("I2CP -> Port"));
+
+ initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), ui->i2pControlEnabledCheckBox);
+ initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), ui->i2pControlAddressLineEdit, tr("I2PControl -> IP address"));
+ initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), ui->i2pControlPortLineEdit, tr("I2PControl -> Port"));
+ initStringBox( OPTION("i2pcontrol","password",[]{return "";}), ui->i2pControlPasswordLineEdit);
+ initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), ui->i2pControlCertFileLineEdit, ui->i2pControlCertFileBrowsePushButton);
+ initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), ui->i2pControlKeyFileLineEdit, ui->i2pControlKeyFileBrowsePushButton);
+
+ initCheckBox( OPTION("upnp","enabled",[]{return "true";}), ui->enableUPnPCheckBox);
+ initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), ui->upnpNameLineEdit);
+
+ initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), ui->useElGamalPrecomputedTablesCheckBox);
+
+ initCheckBox( OPTION("reseed","verify",[]{return "";}), ui->reseedVerifyCheckBox);
+ initFileChooser( OPTION("reseed","file",[]{return "";}), ui->reseedFileLineEdit, ui->reseedFileBrowsePushButton);
+ initStringBox( OPTION("reseed","urls",[]{return "";}), ui->reseedURLsLineEdit);
+
+ initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), ui->addressbookDefaultURLLineEdit);
+ initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), ui->addressbookSubscriptionsURLslineEdit);
+
+ initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), ui->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels"));
+ initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), ui->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles"));
+ initUInt32Box( OPTION("limits","coresize",[]{return "0";}), ui->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize"));
+
+ initCheckBox( OPTION("trust","enabled",[]{return "false";}), ui->checkBoxTrustEnable);
+ initStringBox( OPTION("trust","family",[]{return "";}), ui->lineEditTrustFamily);
+ initStringBox( OPTION("trust","routers",[]{return "";}), ui->lineEditTrustRouters);
+ initCheckBox( OPTION("trust","hidden",[]{return "false";}), ui->checkBoxTrustHidden);
+
+ initCheckBox( OPTION("websockets","enabled",[]{return "false";}), ui->checkBoxWebsocketsEnable);
+ initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), ui->lineEdit_webSock_addr, tr("Websocket server -> IP address"));
+ initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), ui->lineEdit_webSock_port, tr("Websocket server -> Port"));
+
+# undef OPTION
+
+ loadAllConfigs();
+
+ //tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents);
+ //tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget"));
+ //tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451));
+ ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451));
+
+ appendTunnelForms("");
+
+ ui->configFileLineEdit->setEnabled(false);
+ ui->configFileBrowsePushButton->setEnabled(false);
+ ui->configFileLineEdit->setText(confpath);
+ ui->tunnelsConfigFileLineEdit->setText(tunconfpath);
+
+ for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
+ MainWindowItem* item = *it;
+ item->installListeners(this);
+ }
+
+ QObject::connect(ui->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(reloadTunnelsConfigAndUI()));
+
+ QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased()));
+ QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased()));
+
#ifndef ANDROID
QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
@@ -70,6 +221,36 @@ MainWindow::MainWindow(QWidget *parent) :
//QMetaObject::connectSlotsByName(this);
}
+void MainWindow::showStatusPage(){ui->stackedWidget->setCurrentIndex(0);}
+void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);}
+void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);}
+void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);}
+void MainWindow::showQuitPage(){ui->stackedWidget->setCurrentIndex(4);}
+
+//TODO
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+ QMainWindow::resizeEvent(event);
+ onResize();
+}
+
+//TODO
+void MainWindow::onResize()
+{
+ if(isVisible()){
+ ui->horizontalLayoutWidget->resize(ui->horizontalLayoutWidget->width(), height());
+
+ //status
+ ui->statusPage->resize(ui->statusPage->width(), height());
+
+ //tunnels
+ ui->tunnelsPage->resize(ui->tunnelsPage->width(), height());
+ ui->verticalLayoutWidget_6->resize(ui->verticalLayoutWidget_6->width(), height()-20);
+ /*ui->tunnelsScrollArea->resize(ui->tunnelsScrollArea->width(),
+ ui->verticalLayoutWidget_6->height()-ui->label_5->height());*/
+ }
+}
+
#ifndef ANDROID
void MainWindow::createActions() {
toggleWindowVisibleAction = new QAction(tr("&Toggle the window"), this);
@@ -138,12 +319,13 @@ void MainWindow::handleQuitButton() {
void MainWindow::handleGracefulQuitButton() {
qDebug("Graceful Quit pressed.");
- gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0));
- gracefulQuitButton->setEnabled(false);
- gracefulQuitButton->adjustSize();
- verticalLayoutWidget->adjustSize();
+ ui->gracefulQuitPushButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0));
+ ui->gracefulQuitPushButton->setEnabled(false);
+ ui->gracefulQuitPushButton->adjustSize();
+ ui->quitPage->adjustSize();
i2p::context.SetAcceptsTunnels (false); // stop accpting tunnels
- QTimer::singleShot(10*60*1000/*millis*/, this, SLOT(handleGracefulQuitTimerEvent()));
+ QTimer::singleShot(10*60*1000//millis
+ , this, SLOT(handleGracefulQuitTimerEvent()));
}
void MainWindow::handleGracefulQuitTimerEvent() {
@@ -159,7 +341,278 @@ void MainWindow::handleGracefulQuitTimerEvent() {
MainWindow::~MainWindow()
{
qDebug("Destroying main window");
+ for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
+ MainWindowItem* item = *it;
+ item->deleteLater();
+ }
+ configItems.clear();
//QMessageBox::information(0, "Debug", "mw destructor 1");
//delete ui;
//QMessageBox::information(0, "Debug", "mw destructor 2");
}
+
+FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){
+ FileChooserItem* retVal;
+ retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton);
+ MainWindowItem* super=retVal;
+ configItems.append(super);
+ return retVal;
+}
+void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){
+ configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton));
+}
+/*void MainWindow::initCombobox(ConfigOption option, QComboBox* comboBox){
+ configItems.append(new ComboBoxItem(option, comboBox));
+ QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAllConfigs()));
+}*/
+void MainWindow::initLogLevelCombobox(ConfigOption option, QComboBox* comboBox){
+ configItems.append(new LogLevelComboBoxItem(option, comboBox));
+}
+void MainWindow::initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox){
+ configItems.append(new SignatureTypeComboBoxItem(option, comboBox));
+}
+void MainWindow::initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated){
+ configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated));
+}
+void MainWindow::initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated){
+ configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated));
+}
+void MainWindow::initCheckBox(ConfigOption option, QCheckBox* checkBox) {
+ configItems.append(new CheckBoxItem(option, checkBox));
+}
+void MainWindow::initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
+ configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated));
+}
+void MainWindow::initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
+ configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated));
+}
+void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
+ configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated));
+}
+void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){
+ configItems.append(new BaseStringItem(option, lineEdit));
+}
+NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) {
+ NonGUIOptionItem * retValue;
+ configItems.append(retValue=new NonGUIOptionItem(option));
+ return retValue;
+}
+
+void MainWindow::loadAllConfigs(){
+
+ //BORROWED FROM ??? //TODO move this code into single location
+ std::string config; i2p::config::GetOption("conf", config);
+ std::string datadir; i2p::config::GetOption("datadir", datadir);
+ bool service = false;
+#ifndef _WIN32
+ i2p::config::GetOption("service", service);
+#endif
+ i2p::fs::DetectDataDir(datadir, service);
+ i2p::fs::Init();
+
+ datadir = i2p::fs::GetDataDir();
+ // TODO: drop old name detection in v2.8.0
+ if (config == "")
+ {
+ config = i2p::fs::DataDirPath("i2p.conf");
+ if (i2p::fs::Exists (config)) {
+ LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config);
+ } else {
+ config = i2p::fs::DataDirPath("i2pd.conf");
+ if (!i2p::fs::Exists (config)) {
+ // use i2pd.conf only if exists
+ config = ""; /* reset */
+ }
+ }
+ }
+
+ //BORROWED FROM ClientContext.cpp //TODO move this code into single location
+ std::string tunConf; i2p::config::GetOption("tunconf", tunConf);
+ if (tunConf == "") {
+ // TODO: cleanup this in 2.8.0
+ tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
+ if (i2p::fs::Exists(tunConf)) {
+ LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
+ } else {
+ tunConf = i2p::fs::DataDirPath ("tunnels.conf");
+ }
+ }
+
+ this->confpath = config.c_str();
+ this->datadir = datadir.c_str();
+ this->tunconfpath = tunConf.c_str();
+
+ for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
+ MainWindowItem* item = *it;
+ item->loadFromConfigOption();
+ }
+
+ ReadTunnelsConfig();
+}
+/** returns false iff not valid items present and save was aborted */
+bool MainWindow::saveAllConfigs(){
+ programOptionsWriterCurrentSection="";
+ if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file"));
+ else logOption->optionValue=boost::any(std::string("stdout"));
+ daemonOption->optionValue=boost::any(false);
+ serviceOption->optionValue=boost::any(false);
+
+ std::stringstream out;
+ for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
+ MainWindowItem* item = *it;
+ if(!item->isValid()) return false;
+ }
+
+ for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
+ MainWindowItem* item = *it;
+ item->saveToStringStream(out);
+ }
+
+ using namespace std;
+
+ QString backup=confpath+"~";
+ if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
+ QFile::rename(confpath, backup);//TODO handle errors
+ ofstream outfile;
+ outfile.open(confpath.toStdString());//TODO handle errors
+ outfile << out.str().c_str();
+ outfile.close();
+
+ SaveTunnelsConfig();
+
+ return true;
+}
+
+void FileChooserItem::pushButtonReleased() {
+ QString fileName = lineEdit->text().trimmed();
+ fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)"));
+ if(fileName.length()>0)lineEdit->setText(fileName);
+}
+void FolderChooserItem::pushButtonReleased() {
+ QString fileName = lineEdit->text().trimmed();
+ fileName = QFileDialog::getExistingDirectory(nullptr, tr("Open Folder"), fileName);
+ if(fileName.length()>0)lineEdit->setText(fileName);
+}
+
+void BaseStringItem::installListeners(MainWindow *mainWindow) {
+ QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(saveAllConfigs()));
+}
+void ComboBoxItem::installListeners(MainWindow *mainWindow) {
+ QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(saveAllConfigs()));
+}
+void CheckBoxItem::installListeners(MainWindow *mainWindow) {
+ QObject::connect(checkBox, SIGNAL(stateChanged(int)), mainWindow, SLOT(saveAllConfigs()));
+}
+
+
+void MainWindowItem::installListeners(MainWindow *mainWindow) {}
+
+void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) {
+ int height=0;
+ ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0);
+ for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) {
+ const std::string& name=it->first;
+ TunnelConfig* tunconf = it->second;
+ ServerTunnelConfig* stc = tunconf->asServerTunnelConfig();
+ if(stc){
+ ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc);
+ int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
+ height+=h;
+ qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
+ tunnelPanes.push_back(tunnelPane);
+ if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus();
+ continue;
+ }
+ ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig();
+ if(ctc){
+ ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc);
+ int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
+ height+=h;
+ qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
+ tunnelPanes.push_back(tunnelPane);
+ if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus();
+ continue;
+ }
+ throw "unknown TunnelConfig subtype";
+ }
+ qDebug() << "tun.setting height:" << height;
+ ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height));
+ QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren();
+ foreach(QWidget* widget, childWidgets)
+ widget->show();
+}
+void MainWindow::deleteTunnelForms() {
+ for(std::list::iterator it = tunnelPanes.begin(); it != tunnelPanes.end(); ++it) {
+ TunnelPane* tp = *it;
+ ServerTunnelPane* stp = tp->asServerTunnelPane();
+ if(stp){
+ stp->deleteServerTunnelForm();
+ delete stp;
+ continue;
+ }
+ ClientTunnelPane* ctp = tp->asClientTunnelPane();
+ if(ctp){
+ ctp->deleteClientTunnelForm();
+ delete ctp;
+ continue;
+ }
+ throw "unknown TunnelPane subtype";
+ }
+ tunnelPanes.clear();
+}
+
+void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) {
+ deleteTunnelForms();
+ for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
+ TunnelConfig* tunconf = it->second;
+ delete tunconf;
+ }
+ tunnelConfigs.clear();
+ ReadTunnelsConfig();
+ appendTunnelForms(tunnelNameToFocus);
+}
+
+void MainWindow::SaveTunnelsConfig() {
+ std::stringstream out;
+
+ for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
+ const std::string& name = it->first;
+ TunnelConfig* tunconf = it->second;
+ tunconf->saveHeaderToStringStream(out);
+ tunconf->saveToStringStream(out);
+ tunconf->saveI2CPParametersToStringStream(out);
+ }
+
+ using namespace std;
+
+ QString backup=tunconfpath+"~";
+ if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
+ QFile::rename(tunconfpath, backup);//TODO handle errors
+ ofstream outfile;
+ outfile.open(tunconfpath.toStdString());//TODO handle errors
+ outfile << out.str().c_str();
+ outfile.close();
+
+}
+
+void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) {
+ if(oldName!=tunConf->getName()) {
+ //name has changed
+ std::map::const_iterator it=mainWindow->tunnelConfigs.find(oldName);
+ if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it);
+ mainWindow->tunnelConfigs[tunConf->getName()]=tunConf;
+ }
+ mainWindow->SaveTunnelsConfig();
+}
+
+void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){
+ mainWindow->DeleteTunnelNamed(oldName);
+}
+
+void MainWindow::addServerTunnelPushButtonReleased() {
+ CreateDefaultServerTunnel();
+}
+
+void MainWindow::addClientTunnelPushButtonReleased() {
+ CreateDefaultClientTunnel();
+}
diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h
index 349eadec..03057f2e 100644
--- a/qt/i2pd_qt/mainwindow.h
+++ b/qt/i2pd_qt/mainwindow.h
@@ -1,6 +1,7 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+#include
#include
#include
#include
@@ -9,27 +10,316 @@
#include
#include
#include
-#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "QVBoxLayout"
+
#ifndef ANDROID
-#include
-#include
-#include
+# include
+# include
+# include
#endif
+#include
+
+#include
+
+#include "MainWindowItems.h"
+#include "TunnelPane.h"
+#include "ServerTunnelPane.h"
+#include "ClientTunnelPane.h"
+#include "TunnelConfig.h"
+
+#include "Config.h"
+#include "FS.h"
+
+#include
+
+#include
+#include
+
+#include "TunnelsPageUpdateListener.h"
+
+template
+bool isType(boost::any& a) {
+ return
+#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
+ std::strcmp(a.type().name(), typeid(ValueType).name()) == 0
+#else
+ a.type() == typeid(ValueType)
+#endif
+ ;
+}
+
+class ConfigOption {
+public:
+ QString section;
+ QString option;
+ //MainWindow::DefaultValueGetter defaultValueGetter;
+ ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/):
+ section(section_)
+ , option(option_)
+ //, defaultValueGetter(defaultValueGetter_)
+ {}
+
+};
+
+extern std::string programOptionsWriterCurrentSection;
+
+class MainWindow;
+
+class MainWindowItem : public QObject {
+ Q_OBJECT
+ ConfigOption option;
+public:
+ MainWindowItem(ConfigOption option_) : option(option_) {}
+ boost::any optionValue;
+ virtual ~MainWindowItem(){}
+ virtual void installListeners(MainWindow *mainWindow);
+ virtual void loadFromConfigOption(){
+ std::string optName="";
+ if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
+ optName+=option.option.toStdString();
+ qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
+ boost::any programOption;
+ i2p::config::GetOptionAsAny(optName, programOption);
+ optionValue=programOption.empty()?boost::any(std::string(""))
+ :boost::any_cast(programOption).value();
+ }
+ virtual void saveToStringStream(std::stringstream& out){
+ if(isType(optionValue)) {
+ std::string v = boost::any_cast(optionValue);
+ if(v.empty())return;
+ }
+ if(optionValue.empty())return;
+ std::string rtti = optionValue.type().name();
+ std::string optName="";
+ if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
+ optName+=option.option.toStdString();
+ qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
+ std::string sectionAsStdStr = option.section.toStdString();
+ if(!option.section.isEmpty() &&
+ sectionAsStdStr!=programOptionsWriterCurrentSection) {
+ out << "[" << sectionAsStdStr << "]\n";
+ programOptionsWriterCurrentSection=sectionAsStdStr;
+ }
+ out << option.option.toStdString() << "=";
+ if(isType(optionValue)) {
+ out << boost::any_cast(optionValue);
+ }else if(isType(optionValue)) {
+ out << (boost::any_cast(optionValue) ? "true" : "false");
+ }else if(isType(optionValue)) {
+ out << boost::any_cast(optionValue);
+ }else if(isType(optionValue)) {
+ out << boost::any_cast(optionValue);
+ }else if(isType(optionValue)) {
+ out << boost::any_cast(optionValue);
+ }else if(isType(optionValue)) {
+ out << boost::any_cast(optionValue);
+ }else out << boost::any_cast(optionValue); //let it throw
+ out << "\n\n";
+ }
+ virtual bool isValid(){return true;}
+};
+class NonGUIOptionItem : public MainWindowItem {
+public:
+ NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_) {};
+ virtual ~NonGUIOptionItem(){}
+ virtual bool isValid() { return true; }
+};
+class BaseStringItem : public MainWindowItem {
+ Q_OBJECT
+public:
+ QLineEdit* lineEdit;
+ BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_) : MainWindowItem(option_), lineEdit(lineEdit_){};
+ virtual ~BaseStringItem(){}
+ virtual void installListeners(MainWindow *mainWindow);
+ virtual QString toString(){
+ return boost::any_cast(optionValue).c_str();
+ }
+ virtual boost::any fromString(QString s){return boost::any(s.toStdString());}
+ virtual void loadFromConfigOption(){
+ MainWindowItem::loadFromConfigOption();
+ lineEdit->setText(toString());
+ }
+
+ virtual void saveToStringStream(std::stringstream& out){
+ optionValue=fromString(lineEdit->text());
+ MainWindowItem::saveToStringStream(out);
+ }
+ virtual bool isValid() { return true; }
+};
+class FileOrFolderChooserItem : public BaseStringItem {
+public:
+ QPushButton* browsePushButton;
+ FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
+ BaseStringItem(option_, lineEdit_), browsePushButton(browsePushButton_) {}
+ virtual ~FileOrFolderChooserItem(){}
+};
+class FileChooserItem : public FileOrFolderChooserItem {
+ Q_OBJECT
+private slots:
+ void pushButtonReleased();
+public:
+ FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
+ FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
+ QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
+ }
+};
+class FolderChooserItem : public FileOrFolderChooserItem{
+ Q_OBJECT
+private slots:
+ void pushButtonReleased();
+public:
+ FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
+ FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
+ QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
+ }
+};
+class ComboBoxItem : public MainWindowItem {
+public:
+ QComboBox* comboBox;
+ ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_), comboBox(comboBox_){};
+ virtual ~ComboBoxItem(){}
+ virtual void installListeners(MainWindow *mainWindow);
+ virtual void loadFromConfigOption()=0;
+ virtual void saveToStringStream(std::stringstream& out)=0;
+ virtual bool isValid() { return true; }
+};
+class LogLevelComboBoxItem : public ComboBoxItem {
+public:
+ LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
+ virtual ~LogLevelComboBoxItem(){}
+ virtual void loadFromConfigOption(){
+ MainWindowItem::loadFromConfigOption();
+ const char * ll = boost::any_cast(optionValue).c_str();
+ comboBox->setCurrentText(QString(ll));
+ }
+ virtual void saveToStringStream(std::stringstream& out){
+ optionValue=comboBox->currentText().toStdString();
+ MainWindowItem::saveToStringStream(out);
+ }
+ virtual bool isValid() { return true; }
+};
+class SignatureTypeComboBoxItem : public ComboBoxItem {
+public:
+ SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
+ virtual ~SignatureTypeComboBoxItem(){}
+ virtual void loadFromConfigOption(){//TODO
+ MainWindowItem::loadFromConfigOption();
+ comboBox->setCurrentText(QString::number(boost::any_cast(optionValue)));
+ }
+ virtual void saveToStringStream(std::stringstream& out){//TODO
+ QString txt = comboBox->currentText();
+ if(txt.isEmpty())
+ optionValue=std::string();
+ else
+ optionValue=(unsigned short)std::stoi(txt.toStdString());
+ MainWindowItem::saveToStringStream(out);
+ }
+ virtual bool isValid() { return true; }
+};
+class CheckBoxItem : public MainWindowItem {
+public:
+ QCheckBox* checkBox;
+ CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_), checkBox(checkBox_){};
+ virtual ~CheckBoxItem(){}
+ virtual void installListeners(MainWindow *mainWindow);
+ virtual void loadFromConfigOption(){
+ MainWindowItem::loadFromConfigOption();
+ checkBox->setChecked(boost::any_cast(optionValue));
+ }
+ virtual void saveToStringStream(std::stringstream& out){
+ optionValue=checkBox->isChecked();
+ MainWindowItem::saveToStringStream(out);
+ }
+ virtual bool isValid() { return true; }
+};
+class BaseFormattedStringItem : public BaseStringItem {
+public:
+ QString fieldNameTranslated;
+ BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseStringItem(option_, lineEdit_), fieldNameTranslated(fieldNameTranslated_) {};
+ virtual ~BaseFormattedStringItem(){}
+ virtual bool isValid()=0;
+};
+class IntegerStringItem : public BaseFormattedStringItem {
+public:
+ IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual ~IntegerStringItem(){}
+ virtual bool isValid(){return true;}
+ virtual QString toString(){return QString::number(boost::any_cast(optionValue));}
+ virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));}
+};
+class UShortStringItem : public BaseFormattedStringItem {
+public:
+ UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual ~UShortStringItem(){}
+ virtual bool isValid(){return true;}
+ virtual QString toString(){return QString::number(boost::any_cast(optionValue));}
+ virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));}
+};
+class UInt32StringItem : public BaseFormattedStringItem {
+public:
+ UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual ~UInt32StringItem(){}
+ virtual bool isValid(){return true;}
+ virtual QString toString(){return QString::number(boost::any_cast(optionValue));}
+ virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));}
+};
+class UInt16StringItem : public BaseFormattedStringItem {
+public:
+ UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual ~UInt16StringItem(){}
+ virtual bool isValid(){return true;}
+ virtual QString toString(){return QString::number(boost::any_cast(optionValue));}
+ virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));}
+};
+class IPAddressStringItem : public BaseFormattedStringItem {
+public:
+ IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual bool isValid(){return true;}
+};
+class TCPPortStringItem : public UShortStringItem {
+public:
+ TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
+ UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ virtual bool isValid(){return true;}
+};
+
namespace Ui {
class MainWindow;
}
-class MainWindow : public QMainWindow
-{
+using namespace i2p::client;
+
+class TunnelPane;
+
+class MainWindow : public QMainWindow {
Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = 0);
+ explicit MainWindow(QWidget *parent=0);
~MainWindow();
+ //typedef std::function DefaultValueGetter;
+
//#ifndef ANDROID
// void setVisible(bool visible);
//#endif
@@ -43,30 +333,343 @@ private slots:
void iconActivated(QSystemTrayIcon::ActivationReason reason);
void toggleVisibilitySlot();
#endif
+ void showStatusPage();
+ void showSettingsPage();
+ void showTunnelsPage();
+ void showRestartPage();
+ void showQuitPage();
private:
#ifndef ANDROID
void createActions();
void createTrayIcon();
-#endif
-
- QWidget *centralWidget;
- QWidget *verticalLayoutWidget;
- QVBoxLayout *verticalLayout1;
- QPushButton *quitButton;
- QPushButton *gracefulQuitButton;
-
-#ifndef ANDROID
bool quitting;
QAction *toggleWindowVisibleAction;
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
#endif
+ Ui::MainWindow* ui;
+
protected:
#ifndef ANDROID
void closeEvent(QCloseEvent *event);
#endif
+ void resizeEvent(QResizeEvent* event);
+ void onResize();
+
+ QList configItems;
+ NonGUIOptionItem* logOption;
+ NonGUIOptionItem* daemonOption;
+ NonGUIOptionItem* serviceOption;
+ FileChooserItem* logFileNameOption;
+
+ FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton);
+ void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton);
+ //void initCombobox(ConfigOption option, QComboBox* comboBox);
+ void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox);
+ void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox);
+ void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated);
+ void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated);
+ void initCheckBox(ConfigOption option, QCheckBox* checkBox);
+ void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
+ void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
+ void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
+ void initStringBox(ConfigOption option, QLineEdit* lineEdit);
+ NonGUIOptionItem* initNonGUIOption(ConfigOption option);
+
+ void loadAllConfigs();
+
+public slots:
+ /** returns false iff not valid items present and save was aborted */
+ bool saveAllConfigs();
+ void SaveTunnelsConfig();
+ void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus);
+
+ //focus none
+ void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); }
+ void addServerTunnelPushButtonReleased();
+ void addClientTunnelPushButtonReleased();
+
+private:
+ QString datadir;
+ QString confpath;
+ QString tunconfpath;
+
+ std::map tunnelConfigs;
+ std::list tunnelPanes;
+
+ void appendTunnelForms(std::string tunnelNameToFocus);
+ void deleteTunnelForms();
+
+
+ /*
+
+ TODO signaturetype
+
+ */
+
+ template
+ std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
+ {
+ return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
+ }
+
+ template
+ void ReadI2CPOptions (const Section& section, std::map& options, I2CPParameters& param
+ /*TODO fill param*/) const
+ {
+ std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
+ param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str()));
+ std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
+ param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str()));
+ std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
+ param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str()));
+ std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
+ param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str()));
+ std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
+ param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str()));
+ options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
+ options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param
+ }
+
+ void CreateDefaultI2CPOptions (I2CPParameters& param
+ /*TODO fill param*/) const
+ {
+ const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH;
+ param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH));
+ const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
+ param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH));
+ const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY;
+ param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY));
+ const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
+ param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY));
+ const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND;
+ param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND));
+ }
+
+
+ void DeleteTunnelNamed(std::string name) {
+ std::map::const_iterator it=tunnelConfigs.find(name);
+ if(it!=tunnelConfigs.end()){
+ TunnelConfig* tc=it->second;
+ tunnelConfigs.erase(it);
+ delete tc;
+ SaveTunnelsConfig();
+ reloadTunnelsConfigAndUI("");
+ }
+ }
+
+ std::string GenerateNewTunnelName() {
+ int i=1;
+ while(true){
+ std::stringstream name;
+ name << "name" << i;
+ const std::string& str=name.str();
+ if(tunnelConfigs.find(str)==tunnelConfigs.end())return str;
+ ++i;
+ }
+ }
+
+ void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
+ std::string name=GenerateNewTunnelName();
+ std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT;
+ std::string dest = "127.0.0.1";
+ int port = 0;
+ std::string keys = "";
+ std::string address = "127.0.0.1";
+ int destinationPort = 0;
+ i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
+ // I2CP
+ I2CPParameters i2cpParameters;
+ CreateDefaultI2CPOptions (i2cpParameters);
+
+ tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
+ dest,
+ port,
+ keys,
+ address,
+ destinationPort,
+ sigType);
+
+ SaveTunnelsConfig();
+ reloadTunnelsConfigAndUI(name);
+ }
+
+ void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
+ std::string name=GenerateNewTunnelName();
+ std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER;
+ std::string host = "127.0.0.1";
+ int port = 0;
+ std::string keys = "";
+ int inPort = 0;
+ std::string accessList = "";
+ std::string hostOverride = "";
+ std::string webircpass = "";
+ bool gzip = true;
+ i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
+ uint32_t maxConns = i2p::stream::DEFAULT_MAX_CONNS_PER_MIN;
+ std::string address = "127.0.0.1";
+ bool isUniqueLocal = true;
+
+ // I2CP
+ I2CPParameters i2cpParameters;
+ CreateDefaultI2CPOptions (i2cpParameters);
+
+ tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
+ host,
+ port,
+ keys,
+ inPort,
+ accessList,
+ hostOverride,
+ webircpass,
+ gzip,
+ sigType,
+ maxConns,
+ address,
+ isUniqueLocal);
+
+
+ SaveTunnelsConfig();
+ reloadTunnelsConfigAndUI(name);
+ }
+
+ void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
+ {
+ boost::property_tree::ptree pt;
+ std::string tunConf=tunconfpath.toStdString();
+ if (tunConf == "") {
+ // TODO: cleanup this in 2.8.0
+ tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
+ if (i2p::fs::Exists(tunConf)) {
+ LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
+ } else {
+ tunConf = i2p::fs::DataDirPath ("tunnels.conf");
+ }
+ }
+ LogPrint(eLogDebug, "tunnels config file: ", tunConf);
+ try
+ {
+ boost::property_tree::read_ini (tunConf, pt);
+ }
+ catch (std::exception& ex)
+ {
+ LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page
+ return;
+ }
+
+ for (auto& section: pt)
+ {
+ std::string name = section.first;
+ try
+ {
+ std::string type = section.second.get (I2P_TUNNELS_SECTION_TYPE);
+ if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
+ || type == I2P_TUNNELS_SECTION_TYPE_SOCKS
+ || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
+ || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
+ || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
+ {
+ // mandatory params
+ std::string dest;
+ if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
+ dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION);
+ int port = section.second.get (I2P_CLIENT_TUNNEL_PORT);
+ // optional params
+ std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
+ std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
+ int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
+ i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
+ // I2CP
+ std::map options;
+ I2CPParameters i2cpParameters;
+ ReadI2CPOptions (section, options, i2cpParameters);
+
+ tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
+ dest,
+ port,
+ keys,
+ address,
+ destinationPort,
+ sigType);
+ }
+ else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
+ || type == I2P_TUNNELS_SECTION_TYPE_HTTP
+ || type == I2P_TUNNELS_SECTION_TYPE_IRC
+ || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
+ {
+ // mandatory params
+ std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST);
+ int port = section.second.get (I2P_SERVER_TUNNEL_PORT);
+ std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS);
+ // optional params
+ int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
+ std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
+ std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
+ std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
+ bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
+ i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
+ uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
+ std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
+ bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
+
+ // I2CP
+ std::map options;
+ I2CPParameters i2cpParameters;
+ ReadI2CPOptions (section, options, i2cpParameters);
+
+ /*
+ std::set idents;
+ if (accessList.length () > 0)
+ {
+ size_t pos = 0, comma;
+ do
+ {
+ comma = accessList.find (',', pos);
+ i2p::data::IdentHash ident;
+ ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
+ idents.insert (ident);
+ pos = comma + 1;
+ }
+ while (comma != std::string::npos);
+ }
+ */
+ tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
+ host,
+ port,
+ keys,
+ inPort,
+ accessList,
+ hostOverride,
+ webircpass,
+ gzip,
+ sigType,
+ maxConns,
+ address,
+ isUniqueLocal);
+ }
+ else
+ LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui
+
+ }
+ catch (std::exception& ex)
+ {
+ LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui
+ }
+ }
+ }
+
+private:
+ class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener {
+ MainWindow* mainWindow;
+ public:
+ TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){}
+ virtual void updated(std::string oldName, TunnelConfig* tunConf);
+ virtual void needsDeleting(std::string oldName);
+ };
+
+ TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener;
};
#endif // MAINWINDOW_H
diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui
index d73e7743..ca07c036 100644
--- a/qt/i2pd_qt/mainwindow.ui
+++ b/qt/i2pd_qt/mainwindow.ui
@@ -6,42 +6,3185 @@
0
0
- 800
- 480
+ 816
+ 5000
MainWindow
-
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 516
+
+
+
+
+ 16777215
+ 516
+
+
+
10
- 20
- 771
- 441
+ 10
+ 801
+ 518
-
+
+
+ QLayout::SetDefaultConstraint
+
-
-
+
+
+ QLayout::SetMinimumSize
+
+
-
+
+
+ true
+
+
+ Status
+
+
+
+ -
+
+
+ true
+
+
+ Settings
+
+
+
+ -
+
+
+ true
+
+
+ Tunnels
+
+
+
+ -
+
+
+ true
+
+
+ Restart
+
+
+
+ -
+
+
+ true
+
+
+ Quit
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
-
+
0
0
-
- Quit
+
+
+ 0
+ 516
+
-
-
- -
-
-
- Graceful Quit
+
+
+ 16777215
+ 516
+
+
+ 1
+
+
+
+
+
+ 0
+ 0
+ 671
+ 5000
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+
+ 15
+
+
+
+ Status
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+ 0
+ 0
+ 701
+ 400
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+ -
+
+
+
+ 15
+
+
+
+ Settings
+
+
+
+ -
+
+
+ Qt::ScrollBarAlwaysOn
+
+
+ Qt::ScrollBarAsNeeded
+
+
+ QAbstractScrollArea::AdjustIgnored
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 679
+ 400
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+ 10
+ 11
+ 679
+ 2962
+
+
+
+
-
+
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ SAM interface
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Windows-specific options
+
+
+
+ -
+
+
+
+ 0
+ 44
+
+
+
+
+ 16777215
+ 44
+
+
+
+ Cryptography
+
+
+
+
+ 0
+ 20
+ 661
+ 22
+
+
+
+ Use ElGamal precomputed tables
+
+
+
+
+ -
+
+
+
+ 0
+ 107
+
+
+
+
+ 16777215
+ 107
+
+
+
+ Logging
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+
+
+
+ -1
+ 19
+ 661
+ 91
+
+
+
+
+ QLayout::SetMinimumSize
+
+
-
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ Log file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+ -
+
+
+ QLayout::SetMinimumSize
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Log level:
+
+
+
+ -
+
+
-
+
+ Error
+
+
+ -
+
+ Warn
+
+
+ -
+
+ Info
+
+
+ -
+
+ Debug
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 68
+
+
+
+
+ 16777215
+ 68
+
+
+
+ UPnP
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enable
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ Name i2pd appears in UPnP forwardings list:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ I2CP interface
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 48
+
+
+
+
+ 16777215
+ 48
+
+
+
+ Tunnels configuration file:
+
+
+
+
+ 0
+ 20
+ 661
+ 31
+
+
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ BOB interface
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ General options
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ Router external address (for incoming connections)
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+
+
+
+ 0
+ 20
+ 661
+ 81
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ Host:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ QLayout::SetMinAndMaxSize
+
+
-
+
+
+ Port (leave empty to auto-assign):
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 78
+
+
+
+
+ 16777215
+ 78
+
+
+
+ Addressbook settings
+
+
+
+
+ 0
+ 20
+ 661
+ 31
+
+
+
+
-
+
+
+ Addressbook default subscription URL for initial setup:
+
+
+
+ -
+
+
+
+
+
+
+
+ 0
+ 50
+ 661
+ 31
+
+
+
+ -
+
+
+ Addressbook subscriptions URLs, separated by comma:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 280
+
+
+
+
+ 16777215
+ 280
+
+
+
+ HTTP proxy
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 100
+ 661
+ 31
+
+
+
+ -
+
+
+ Keys file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+
+ 0
+ 160
+ 661
+ 31
+
+
+
+ -
+
+
+ Inbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 190
+ 661
+ 31
+
+
+
+ -
+
+
+ Inbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 220
+ 661
+ 31
+
+
+
+ -
+
+
+ Outbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 250
+ 661
+ 31
+
+
+
+ -
+
+
+ Outbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 130
+ 661
+ 31
+
+
+
+ -
+
+
+ Signature type:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Various options
+
+
+
+ -
+
+
+
+ 0
+ 48
+
+
+
+
+ 16777215
+ 48
+
+
+
+ Data folder (for storage of i2pd data — RI, keys, peer profiles, …):
+
+
+
+
+ 0
+ 20
+ 661
+ 31
+
+
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 215
+
+
+
+
+ 16777215
+ 215
+
+
+
+ Router options
+
+
+
+
+ 0
+ 20
+ 661
+ 188
+
+
+
+
-
+
+
+ Enable communication through ipv6
+
+
+
+ -
+
+
+ Router will not accept transit tunnels at startup
+
+
+
+ -
+
+
+ Router will be floodfill
+
+
+
+ -
+
+
-
+
+
+ Bandwidth limit (integer):
+
+
+
+ -
+
+
+ -
+
+
+ KBps
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Family (name of a family router belongs to):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ NetID (network ID router belongs to. The main I2P ID is 2):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 108
+
+
+
+
+ 16777215
+ 108
+
+
+
+ Limits
+
+
+
+
+ 0
+ 20
+ 661
+ 31
+
+
+
+
-
+
+
+ Maximum number of transit tunnels:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 50
+ 661
+ 31
+
+
+
+ -
+
+
+ Maximum number of open files (0 — use system limit):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 80
+ 661
+ 31
+
+
+
+ -
+
+
+ Maximum size of core file in Kb (0 — use system limit):
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 48
+
+
+
+
+ 16777215
+ 48
+
+
+
+ Pid file:
+
+
+
+
+ 0
+ 20
+ 661
+ 31
+
+
+
+
-
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 98
+
+
+
+
+ 16777215
+ 98
+
+
+
+ Reseeding
+
+
+
+
+ 0
+ 20
+ 661
+ 22
+
+
+
+ Request SU3 signature verification
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ SU3 file to reseed from:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Reseed URLs, separated by comma:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 180
+
+
+
+
+ 16777215
+ 180
+
+
+
+ Trust options
+
+
+
+
+ 0
+ 20
+ 661
+ 21
+
+
+
+ Enable explicit trust options
+
+
+
+
+
+ 390
+ 40
+ 271
+ 23
+
+
+
+
+
+
+ 0
+ 40
+ 391
+ 42
+
+
+
+ Make direct I2P connections only to
+routers in specified Family:
+
+
+
+
+
+ 0
+ 82
+ 661
+ 42
+
+
+
+ Make direct I2P connections only to routers specified here.
+Comma separated list of base64 identities:
+
+
+
+
+
+ 0
+ 124
+ 661
+ 23
+
+
+
+
+
+
+ 0
+ 147
+ 661
+ 21
+
+
+
+ Should we hide our router from other routers?
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+ 16777215
+ 60
+
+
+
+
+ 13
+
+
+
+ Ports
+
+
+
+ -
+
+
+
+ 0
+ 22
+
+
+
+
+ 16777215
+ 22
+
+
+
+ Insomnia (prevent system from sleeping)
+
+
+
+ -
+
+
+
+ 0
+ 189
+
+
+
+
+ 16777215
+ 189
+
+
+
+ I2PControl interface
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 100
+ 661
+ 31
+
+
+
+ -
+
+
+ Password:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 130
+ 661
+ 31
+
+
+
+ -
+
+
+ Certificate file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+
+ 0
+ 160
+ 661
+ 31
+
+
+
+ -
+
+
+ Key file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 46
+
+
+
+
+ 16777215
+ 46
+
+
+
+ Configuration file:
+
+
+
+
+ 0
+ 18
+ 661
+ 31
+
+
+
+
+ QLayout::SetMinimumSize
+
+
-
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 110
+
+
+
+
+ 16777215
+ 110
+
+
+
+ Websockets server
+
+
+
+
+ 0
+ 20
+ 85
+ 21
+
+
+
+ Enable
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ Address to bind websocket server on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to bind websocket server on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 179
+
+
+
+
+ 16777215
+ 179
+
+
+
+ HTTP webconsole
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 100
+ 321
+ 22
+
+
+
+ Enable basic HTTP auth
+
+
+
+
+
+ 60
+ 120
+ 601
+ 31
+
+
+
+ -
+
+
+ Username:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 60
+ 150
+ 601
+ 31
+
+
+
+ -
+
+
+ Password:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 370
+
+
+
+
+ 16777215
+ 370
+
+
+
+ Socks proxy
+
+
+
+
+ 0
+ 20
+ 97
+ 22
+
+
+
+ Enabled
+
+
+
+
+
+ 0
+ 40
+ 661
+ 31
+
+
+
+
-
+
+
+ IP address to listen on:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 70
+ 661
+ 31
+
+
+
+ -
+
+
+ Port to listen on:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 100
+ 661
+ 31
+
+
+
+ -
+
+
+ Keys file:
+
+
+
+ -
+
+
+ -
+
+
+ Browse…
+
+
+
+
+
+
+
+
+ 0
+ 160
+ 661
+ 31
+
+
+
+ -
+
+
+ Inbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 190
+ 661
+ 31
+
+
+
+ -
+
+
+ Inbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 220
+ 661
+ 31
+
+
+
+ -
+
+
+ Outbound tunnels length:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 250
+ 661
+ 31
+
+
+
+ -
+
+
+ Outbound tunnels quantity:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 280
+ 661
+ 31
+
+
+
+ -
+
+
+ Outproxy address:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 310
+ 661
+ 31
+
+
+
+ -
+
+
+ Outproxy port:
+
+
+
+ -
+
+
+
+ 80
+ 16777215
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 0
+ 130
+ 661
+ 31
+
+
+
+ -
+
+
+ SIgnature type:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 681
+ 460
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+ -
+
+
+
+ 15
+
+
+
+ Tunnels
+
+
+
+ -
+
+
-
+
+
+ Add Client Tunnel
+
+
+
+ -
+
+
+ Add Server Tunnel
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::ScrollBarAlwaysOn
+
+
+ false
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
+
+ 0
+ 0
+ 663
+ 395
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 681
+ 451
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+ -
+
+
+
+ 15
+
+
+
+ Restart
+
+
+
+ -
+
+
+ Restart i2pd
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+ 0
+ 0
+ 671
+ 480
+
+
+
+
+ QLayout::SetMinAndMaxSize
+
+ -
+
+
+
+ 15
+
+
+
+ Quit
+
+
+
+ -
+
+
+ Quit Now
+
+
+
+ -
+
+
+ Graceful Quit
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
@@ -50,40 +3193,7 @@
-
-
- quitButton
- released()
- MainWindow
- handleQuitButton()
-
-
- 384
- 244
-
-
- 373
- 419
-
-
-
-
- gracefulShutdownButton
- released()
- MainWindow
- handleGracefulQuitButton()
-
-
- 395
- 319
-
-
- 399
- 239
-
-
-
-
+
handleQuitButton()
handleGracefulQuitButton()
diff --git a/qt/i2pd_qt/tunnelform.ui b/qt/i2pd_qt/tunnelform.ui
new file mode 100644
index 00000000..61e54770
--- /dev/null
+++ b/qt/i2pd_qt/tunnelform.ui
@@ -0,0 +1,104 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 527
+ 452
+
+
+
+ Form
+
+
+
+
+ 0
+ 0
+ 521
+ 451
+
+
+
+ -
+
+
+ server_tunnel_name
+
+
+
+
+ 0
+ 20
+ 511
+ 421
+
+
+
+
-
+
+
-
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Delete
+
+
+
+
+
+ -
+
+
-
+
+
+ Host:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+