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 + + + + + + + + + + + + + + + +