diff --git a/.mtn-ignore b/.mtn-ignore index 41aa1db6e..ade026859 100644 --- a/.mtn-ignore +++ b/.mtn-ignore @@ -73,3 +73,15 @@ sloccount.sc # IDEA \.iml$ + +# Meeh stuff +target/scala-2.12 +target/streams +project/target +launchers/macosx/project/project/target +launchers/macosx/I2PLauncher.xcodeproj/project.xcworkspace/xcuserdata +launchers/macosx/I2PLauncher.xcodeproj/xcuserdata +launchers/macosx/I2PLauncher.xcworkspace/xcuserdata +launchers/macosx/I2PLauncher.app +launchers/macosx/target + diff --git a/launchers/macosx/AppDelegate.h b/launchers/macosx/AppDelegate.h index cfb89bd66..33c2a0ade 100644 --- a/launchers/macosx/AppDelegate.h +++ b/launchers/macosx/AppDelegate.h @@ -5,11 +5,18 @@ #include #include +#ifdef __cplusplus +#include +#include +#include +#include +#endif + #include +#include "SBridge.h" #include "RouterTask.h" -#include "JavaHelper.h" #define DEF_I2P_VERSION "0.9.36" @@ -27,18 +34,34 @@ @class ExtractMetaInfo; - - @interface ExtractMetaInfo : NSObject @property (copy) NSString* i2pBase; @property (copy) NSString* javaBinary; @property (copy) NSString* zipFile; @property (copy) NSString* jarFile; @end -#ifdef __cplusplus -#include "JavaHelper.h" -inline void sendUserNotification(NSString* title, NSString* informativeText, NSImage* contentImage = NULL, bool makeSound = false) { + +#ifdef __cplusplus + +inline const char* RealHomeDirectory() { + struct passwd *pw = getpwuid(getuid()); + assert(pw); + return pw->pw_dir; +} + +inline std::string getDefaultBaseDir() +{ + // Figure out base directory + auto homeDir = RealHomeDirectory(); + const char* pathFromHome = "%s/Library/I2P"; + char buffer[strlen(homeDir)+strlen(pathFromHome)]; + sprintf(buffer, pathFromHome, homeDir); + std::string i2pBaseDir(buffer); + return i2pBaseDir; +} + +inline void sendUserNotification(NSString* title, NSString* informativeText, bool makeSound = false) { NSUserNotification *userNotification = [[NSUserNotification alloc] init]; userNotification.title = title; @@ -55,32 +78,9 @@ inline void sendUserNotification(NSString* title, NSString* informativeText, NSI [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification]; }; -using maybeAnRouterRunner = I2PRouterTask*; - -std::vector buildClassPath(std::string basePath); - -extern JvmListSharedPtr gRawJvmList; - -// DO NOT ACCESS THIS GLOBAL VARIABLE DIRECTLY. -static std::mutex globalRouterStatusMutex; -static maybeAnRouterRunner globalRouterStatus = maybeAnRouterRunner{}; -static bool isRuterRunning = false; - -maybeAnRouterRunner getGlobalRouterObject(); -void setGlobalRouterObject(I2PRouterTask* newRouter); -bool getGlobalRouterIsRunning(); -void setGlobalRouterIsRunning(bool running); - -#include "SBridge.h" - #endif -@class MenuBarCtrl; - -@interface AppDelegate : NSObject { -@public - //NSImageView *imageCell; -} +@interface AppDelegate : NSObject @property BOOL enableLogging; @property BOOL enableVerboseLogging; @property (assign) SwiftMainDelegate *swiftRuntime; @@ -93,12 +93,7 @@ void setGlobalRouterIsRunning(bool running); - (void) applicationDidFinishLaunching:(NSNotification *)aNotification; - (void) applicationWillTerminate:(NSNotification *)aNotification; - (void) setApplicationDefaultPreferences; -- (void) userChooseJavaHome; - (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv; -#ifdef __cplusplus -- (void) startupI2PRouter; -- (NSString *) userSelectJavaHome:(JvmListPtr)rawJvmList; -#endif - (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; @end diff --git a/launchers/macosx/Deployer.h b/launchers/macosx/Deployer.h new file mode 100644 index 000000000..13ffc5a74 --- /dev/null +++ b/launchers/macosx/Deployer.h @@ -0,0 +1,15 @@ +// +// Deployer.h +// I2PLauncher +// +// Created by Mikal Villa on 19/09/2018. +// Copyright © 2018 The I2P Project. All rights reserved. +// + +#import + + +@interface NSObject () + +@end + diff --git a/launchers/macosx/Deployer.m b/launchers/macosx/Deployer.m new file mode 100644 index 000000000..835237201 --- /dev/null +++ b/launchers/macosx/Deployer.m @@ -0,0 +1,13 @@ +// +// Deployer.m +// I2PLauncher +// +// Created by Mikal Villa on 19/09/2018. +// Copyright © 2018 The I2P Project. All rights reserved. +// + +#import +#import "Deployer.h" + + + diff --git a/launchers/macosx/I2PLauncher.xcodeproj/project.pbxproj b/launchers/macosx/I2PLauncher.xcodeproj/project.pbxproj index 3cd99bf9a..fd43e932e 100644 --- a/launchers/macosx/I2PLauncher.xcodeproj/project.pbxproj +++ b/launchers/macosx/I2PLauncher.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 47; objects = { /* Begin PBXBuildFile section */ @@ -14,7 +14,6 @@ BF1EFA41215141110014EB07 /* RouterTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF1EFA3E215141100014EB07 /* RouterTask.mm */; }; BF1EFA47215141640014EB07 /* base.zip in Resources */ = {isa = PBXBuildFile; fileRef = BF1EFA44215141630014EB07 /* base.zip */; }; BF1EFA48215141640014EB07 /* ItoopieTransparent.png in Resources */ = {isa = PBXBuildFile; fileRef = BF1EFA45215141640014EB07 /* ItoopieTransparent.png */; }; - BF1EFA4A215141CD0014EB07 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF5061932113C6ED0014EB07 /* NetworkExtension.framework */; }; BF5061702113C48E0014EB07 /* I2PLauncher.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BF50616E2113C48E0014EB07 /* I2PLauncher.xcdatamodeld */; }; BF5061722113C4900014EB07 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF5061712113C4900014EB07 /* Assets.xcassets */; }; BF5061752113C4900014EB07 /* UserInterfaces.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF5061732113C4900014EB07 /* UserInterfaces.xib */; }; @@ -25,7 +24,12 @@ BF53150D2150CE310014EB07 /* DateTimeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF53150C2150CE310014EB07 /* DateTimeUtils.swift */; }; BF5315132150EB510014EB07 /* RouterProcessStatus+ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5315122150EB510014EB07 /* RouterProcessStatus+ObjectiveC.swift */; }; BF531515215105B40014EB07 /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF531514215105B40014EB07 /* LogViewController.swift */; }; + BF650CA92152AC7D0014EB07 /* bumpInfoPlist.sh in Resources */ = {isa = PBXBuildFile; fileRef = BF650CA52152AC7D0014EB07 /* bumpInfoPlist.sh */; }; + BF650CAA2152AC7D0014EB07 /* dmgconfig.py in Resources */ = {isa = PBXBuildFile; fileRef = BF650CA62152AC7D0014EB07 /* dmgconfig.py */; }; + BF650CAB2152AC7D0014EB07 /* Deployer.m in Sources */ = {isa = PBXBuildFile; fileRef = BF650CA72152AC7D0014EB07 /* Deployer.m */; }; BF7506CB21509CFD0014EB07 /* RouterProcessStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7506CA21509CFD0014EB07 /* RouterProcessStatus.swift */; }; + BF86541321515CA00014EB07 /* launcher.jar in Resources */ = {isa = PBXBuildFile; fileRef = BF1EFA46215141640014EB07 /* launcher.jar */; }; + BF865417215182820014EB07 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF865416215182820014EB07 /* Foundation.framework */; }; BFBDCAE9215040670014EB07 /* Subprocess.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCAE8215040670014EB07 /* Subprocess.swift */; }; BFBDCAEB215041630014EB07 /* TaskPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCAEA215041630014EB07 /* TaskPipeline.swift */; }; BFBDCAED215041C10014EB07 /* Subprocess+CompactAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCAEC215041C10014EB07 /* Subprocess+CompactAPI.swift */; }; @@ -39,6 +43,7 @@ BFBDCB0021505BEE0014EB07 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFBDCAFF21505BED0014EB07 /* AppKit.framework */; }; BFBDCB02215060190014EB07 /* DetectJava.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB01215060190014EB07 /* DetectJava.swift */; }; BFBDCB04215060970014EB07 /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB03215060970014EB07 /* StatusBarController.swift */; }; + BFE1CBAD2151908F0014EB07 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */; }; BFF4581C213C48EA0014EB07 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF4581B213C48EA0014EB07 /* EventMonitor.swift */; }; /* End PBXBuildFile section */ @@ -48,7 +53,6 @@ BF1EFA38215140E60014EB07 /* SBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBridge.h; sourceTree = SOURCE_ROOT; }; BF1EFA39215140E60014EB07 /* SBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SBridge.mm; sourceTree = SOURCE_ROOT; }; BF1EFA3B215141100014EB07 /* RouterTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RouterTask.h; sourceTree = SOURCE_ROOT; }; - BF1EFA3C215141100014EB07 /* JavaHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaHelper.h; sourceTree = SOURCE_ROOT; }; BF1EFA3D215141100014EB07 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; }; BF1EFA3E215141100014EB07 /* RouterTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RouterTask.mm; sourceTree = SOURCE_ROOT; }; BF1EFA3F215141110014EB07 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; @@ -62,7 +66,6 @@ BF5061742113C4900014EB07 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UserInterfaces.xib; sourceTree = ""; }; BF5061762113C4900014EB07 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; BF5061792113C4900014EB07 /* I2PLauncher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = I2PLauncher.entitlements; sourceTree = ""; }; - BF5061932113C6ED0014EB07 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; BF5061952113C84E0014EB07 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; BF5315062150C55B0014EB07 /* RouterRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterRunner.swift; sourceTree = ""; }; BF5315082150C6760014EB07 /* RouterDeployer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterDeployer.swift; sourceTree = ""; }; @@ -70,7 +73,13 @@ BF53150C2150CE310014EB07 /* DateTimeUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeUtils.swift; sourceTree = ""; }; BF5315122150EB510014EB07 /* RouterProcessStatus+ObjectiveC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RouterProcessStatus+ObjectiveC.swift"; sourceTree = ""; }; BF531514215105B40014EB07 /* LogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = ""; }; + BF650CA52152AC7D0014EB07 /* bumpInfoPlist.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = bumpInfoPlist.sh; sourceTree = SOURCE_ROOT; }; + BF650CA62152AC7D0014EB07 /* dmgconfig.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = dmgconfig.py; sourceTree = SOURCE_ROOT; }; + BF650CA72152AC7D0014EB07 /* Deployer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Deployer.m; sourceTree = SOURCE_ROOT; }; + BF650CA82152AC7D0014EB07 /* Deployer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deployer.h; sourceTree = SOURCE_ROOT; }; BF7506CA21509CFD0014EB07 /* RouterProcessStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterProcessStatus.swift; sourceTree = ""; }; + BF865414215180F60014EB07 /* libswiftDarwin.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libswiftDarwin.tbd; path = System/Library/PrivateFrameworks/Swift/libswiftDarwin.tbd; sourceTree = SDKROOT; }; + BF865416215182820014EB07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; BFBDCAE8215040670014EB07 /* Subprocess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Subprocess.swift; sourceTree = ""; }; BFBDCAEA215041630014EB07 /* TaskPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskPipeline.swift; sourceTree = ""; }; BFBDCAEC215041C10014EB07 /* Subprocess+CompactAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Subprocess+CompactAPI.swift"; sourceTree = ""; }; @@ -85,6 +94,7 @@ BFBDCAFF21505BED0014EB07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; BFBDCB01215060190014EB07 /* DetectJava.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectJava.swift; sourceTree = ""; }; BFBDCB03215060970014EB07 /* StatusBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarController.swift; sourceTree = ""; }; + BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; BFF45818213C428E0014EB07 /* I2PLauncher-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "I2PLauncher-Bridging-Header.h"; sourceTree = ""; }; BFF4581B213C48EA0014EB07 /* EventMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMonitor.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -94,7 +104,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BF1EFA4A215141CD0014EB07 /* NetworkExtension.framework in Frameworks */, + BFE1CBAD2151908F0014EB07 /* CoreFoundation.framework in Frameworks */, + BF865417215182820014EB07 /* Foundation.framework in Frameworks */, BFBDCB0021505BEE0014EB07 /* AppKit.framework in Frameworks */, BF5061962113C84E0014EB07 /* Cocoa.framework in Frameworks */, ); @@ -150,9 +161,12 @@ BF50616A2113C48E0014EB07 /* I2PLauncher */ = { isa = PBXGroup; children = ( + BF650CA52152AC7D0014EB07 /* bumpInfoPlist.sh */, + BF650CA82152AC7D0014EB07 /* Deployer.h */, + BF650CA72152AC7D0014EB07 /* Deployer.m */, + BF650CA62152AC7D0014EB07 /* dmgconfig.py */, BF1EFA42215141220014EB07 /* include */, BF1EFA3F215141110014EB07 /* AppDelegate.h */, - BF1EFA3C215141100014EB07 /* JavaHelper.h */, BF1EFA3D215141100014EB07 /* main.mm */, BF1EFA3B215141100014EB07 /* RouterTask.h */, BF1EFA3E215141100014EB07 /* RouterTask.mm */, @@ -177,9 +191,11 @@ BF5061922113C6ED0014EB07 /* Frameworks */ = { isa = PBXGroup; children = ( + BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */, + BF865416215182820014EB07 /* Foundation.framework */, + BF865414215180F60014EB07 /* libswiftDarwin.tbd */, BFBDCAFF21505BED0014EB07 /* AppKit.framework */, BF5061952113C84E0014EB07 /* Cocoa.framework */, - BF5061932113C6ED0014EB07 /* NetworkExtension.framework */, ); name = Frameworks; sourceTree = ""; @@ -236,15 +252,20 @@ BF5061602113C48E0014EB07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = "The I2P Project"; TargetAttributes = { BF5061672113C48E0014EB07 = { CreatedOnToolsVersion = 9.4.1; + DevelopmentTeam = W3C42P2LA8; LastSwiftMigration = 0940; + ProvisioningStyle = Automatic; SystemCapabilities = { + com.apple.ApplicationGroups.Mac = { + enabled = 0; + }; com.apple.NetworkExtensions = { - enabled = 1; + enabled = 0; }; com.apple.Sandbox = { enabled = 0; @@ -254,7 +275,7 @@ }; }; buildConfigurationList = BF5061632113C48E0014EB07 /* Build configuration list for PBXProject "I2PLauncher" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 6.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -276,6 +297,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BF86541321515CA00014EB07 /* launcher.jar in Resources */, + BF650CAA2152AC7D0014EB07 /* dmgconfig.py in Resources */, + BF650CA92152AC7D0014EB07 /* bumpInfoPlist.sh in Resources */, BF07789721506C810014EB07 /* Storyboard.storyboard in Resources */, BF5061722113C4900014EB07 /* Assets.xcassets in Resources */, BF5061752113C4900014EB07 /* UserInterfaces.xib in Resources */, @@ -298,7 +322,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Run from launchers/macosx\nexport BUILDDIR=$(pwd)\ncd ../..\nant preppkg-osx\ncd pkg-temp\nrm -f ../base.zip\nzip -r7 ../base.zip *\ncp ../base.zip $BUILDDIR\ncd $BUILDDIR\n\n\n\n"; + shellScript = "# Run from launchers/macosx\nexport BUILDDIR=$(pwd)\ncd ..\nsbt macosx:assembly\ncd ..\nant preppkg-osx\ncd pkg-temp\nrm -f ../base.zip\nzip -r -v -9 ../base.zip *\ncp ../base.zip $BUILDDIR/base.zip\ncd $BUILDDIR\ncp $BUILDDIR/target/scala-2.11/routerLauncher-assembly-0.1.0-SNAPSHOT.jar $BUILDDIR/launcher.jar\n\n\n\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -320,6 +344,7 @@ BFBDCAED215041C10014EB07 /* Subprocess+CompactAPI.swift in Sources */, BFBDCB02215060190014EB07 /* DetectJava.swift in Sources */, BF07789E21506D2B0014EB07 /* PopoverViewController.swift in Sources */, + BF650CAB2152AC7D0014EB07 /* Deployer.m in Sources */, BF1EFA40215141110014EB07 /* main.mm in Sources */, BFBDCAF4215042670014EB07 /* AppleStuffExceptionHandler.m in Sources */, BF531515215105B40014EB07 /* LogViewController.swift in Sources */, @@ -358,7 +383,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -400,10 +425,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; + SDKROOT = macosx10.13; }; name = Debug; }; @@ -416,7 +441,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -452,80 +477,80 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; + SDKROOT = macosx10.13; + SWIFT_COMPILATION_MODE = wholemodule; }; name = Release; }; BF50617D2113C4900014EB07 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_ENTITLEMENTS = I2PLauncher/I2PLauncher.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = W3C42P2LA8; - GCC_C_LANGUAGE_STANDARD = gnu11; + FRAMEWORK_SEARCH_PATHS = ( + /Library/Frameworks, + /System/Library/Frameworks, + ); HEADER_SEARCH_PATHS = ( "$(SRCROOT)/include", "$(SRCROOT)/include/neither", ); INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = include; INFOPLIST_FILE = I2PLauncher/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = net.i2p.launcher.I2PLauncher; + LD_NO_PIE = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = net.i2p.bootstrap.macosx.I2PLauncher; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SWIFT_OBJC_BRIDGING_HEADER = "I2PLauncher/I2PLauncher-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; SYSTEM_HEADER_SEARCH_PATHS = "$(SRCROOT)/include/**"; - USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; }; BF50617E2113C4900014EB07 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_ENTITLEMENTS = I2PLauncher/I2PLauncher.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = W3C42P2LA8; - GCC_C_LANGUAGE_STANDARD = gnu11; + FRAMEWORK_SEARCH_PATHS = ( + /Library/Frameworks, + /System/Library/Frameworks, + ); HEADER_SEARCH_PATHS = ( "$(SRCROOT)/include", "$(SRCROOT)/include/neither", ); INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = include; INFOPLIST_FILE = I2PLauncher/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = net.i2p.launcher.I2PLauncher; + LD_NO_PIE = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = net.i2p.bootstrap.macosx.I2PLauncher; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SWIFT_OBJC_BRIDGING_HEADER = "I2PLauncher/I2PLauncher-Bridging-Header.h"; SWIFT_VERSION = 3.0; SYSTEM_HEADER_SEARCH_PATHS = "$(SRCROOT)/include/**"; - USER_HEADER_SEARCH_PATHS = ""; }; name = Release; }; diff --git a/launchers/macosx/I2PLauncher.xcworkspace/contents.xcworkspacedata b/launchers/macosx/I2PLauncher.xcworkspace/contents.xcworkspacedata index 89a270c19..64c7aa35b 100644 --- a/launchers/macosx/I2PLauncher.xcworkspace/contents.xcworkspacedata +++ b/launchers/macosx/I2PLauncher.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,9 @@ + + diff --git a/launchers/macosx/I2PLauncher/Info.plist b/launchers/macosx/I2PLauncher/Info.plist index 82121b3ab..912ffda85 100644 --- a/launchers/macosx/I2PLauncher/Info.plist +++ b/launchers/macosx/I2PLauncher/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 3 + 4 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion @@ -53,5 +53,7 @@ + SUFeedURL + http://i2browser.i2p/updates/v1/appcast.xml diff --git a/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift b/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift index 9415a698b..b5b60bf1c 100644 --- a/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift +++ b/launchers/macosx/I2PLauncher/SwiftMainDelegate.swift @@ -13,18 +13,19 @@ import Cocoa //let statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength ) let statusBarController = StatusBarController() - let javaDetector = DetectJava() + static let javaDetector = DetectJava() static let objCBridge = SBridge() override init() { super.init() - - self.javaDetector.findIt() - if (!javaDetector.isJavaFound()) { - print("Could not find java....") - terminate("No java..") + if (!SwiftMainDelegate.javaDetector.isJavaFound()) { + SwiftMainDelegate.javaDetector.findIt() + if (!SwiftMainDelegate.javaDetector.isJavaFound()) { + print("Could not find java....") + terminate("No java..") + } } - let javaBinPath = self.javaDetector.javaHome + let javaBinPath = SwiftMainDelegate.javaDetector.javaHome RouterProcessStatus.knownJavaBinPath = javaBinPath print("Found java home = ", javaBinPath) @@ -77,8 +78,6 @@ import Cocoa var i2pPath = NSHomeDirectory() i2pPath += "/Library/I2P" - //let javaBinPath = self.javaDetector.javaHome.replace(target: " ", withString: "\\ ") - let fileManager = FileManager() var ok = ObjCBool(true) let doesI2PDirExists = fileManager.fileExists(atPath: i2pPath, isDirectory: &ok) diff --git a/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift b/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift index f70d20f8d..186318e09 100644 --- a/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift +++ b/launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift @@ -10,9 +10,9 @@ import Foundation @objc class DetectJava : NSObject { - var hasJRE : Bool = false - var userWantJRE : Bool = false - var userAcceptOracleEULA : Bool = false + static var hasJRE : Bool = false + static var userWantJRE : Bool = false + static var userAcceptOracleEULA : Bool = false override init() { @@ -29,8 +29,9 @@ import Foundation //Called after the change didSet{ - hasJRE = true - print("DetectJava.javaHome did change from "+oldValue+" to "+self.javaHome) + DetectJava.hasJRE = true + self.javaHome = self.javaHome.replace(target: "\n", withString: "").replace(target: "Internet Plug-Ins", withString: "Internet\\ Plug-Ins") + print("DetectJava.javaHome did change to "+self.javaHome) } }; private var testedEnv : Bool = false @@ -50,25 +51,28 @@ import Foundation * **/ @objc func findIt() { + if (DetectJava.hasJRE) { + return + } print("Start with checking environment variable") self.checkJavaEnvironmentVariable() if !(self.javaHome.isEmpty) { RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome) - hasJRE = true + DetectJava.hasJRE = true return } print("Checking with the java_home util") self.runJavaHomeCmd() if !(self.javaHome.isEmpty) { RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome) - hasJRE = true + DetectJava.hasJRE = true return } print("Checking default JRE install path") self.checkDefaultJREPath() if !(self.javaHome.isEmpty) { RouterProcessStatus.knownJavaBinPath = Optional.some(self.javaHome) - hasJRE = true + DetectJava.hasJRE = true return } } diff --git a/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift b/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift index 7fe785bfc..3ff99f349 100644 --- a/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift +++ b/launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift @@ -26,29 +26,29 @@ import AppKit } @objc func getRouterIsRunning() -> Bool { - if (RouterProcessStatus.isRouterRunning == Optional.none) { - return false; - } else { - let running: Bool = RouterProcessStatus.isRouterRunning - return running - } + return RouterProcessStatus.isRouterRunning } @objc func getJavaHome() -> String { return RouterProcessStatus.knownJavaBinPath! } - - @objc func setJavaHome(_ home: String) { - NSLog("Setting known java to %s", home) - RouterProcessStatus.knownJavaBinPath = home - } } extension RouterProcessStatus { static var isRouterRunning : Bool = false static var isRouterChildProcess : Bool = false static var routerVersion : String? = Optional.none - static var routerUptime : String? = Optional.none + static var routerUptime : String? = Optional.none{ + //Called before the change + willSet(newValue){ + print("RouterProcessStatus.routerUptime will change from ", (self.routerUptime ?? "nil"), " to "+(newValue ?? "nil")) + } + + //Called after the change + didSet{ + print("RouterProcessStatus.routerUptime did change to "+self.routerUptime!) + } + } static var routerStartedAt : Date? = Optional.none static var knownJavaBinPath : String? = Optional.none static var i2pDirectoryPath : String = NSHomeDirectory() + "/Library/I2P" diff --git a/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift b/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift index f81651abf..4980326c3 100644 --- a/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift +++ b/launchers/macosx/I2PLauncher/userinterface/PopoverViewController.swift @@ -60,7 +60,7 @@ class PopoverViewController: NSViewController { override func viewWillDraw() { super.viewWillDraw() - if (RouterStatusView.instance == Optional.none) { + if (RouterStatusView.instance != nil) { RouterStatusView.instance = self } self.setRouterStatusLabelText() @@ -78,16 +78,13 @@ class PopoverViewController: NSViewController { routerStartStopButton?.target = self quickControlView?.needsDisplay = true - if (RouterProcessStatus.routerVersion == Optional.none) { - routerVersionLabel?.cell?.stringValue = "Router version: Still unknown" - // trigger a read to ensure values - let tmp = SwiftMainDelegate() - tmp.findInstalledI2PVersion() + if let version = RouterProcessStatus.routerVersion { + routerVersionLabel?.cell?.stringValue = "Router version: " + version } else { - routerVersionLabel?.cell?.stringValue = "Router version: " + RouterProcessStatus.routerVersion! + routerVersionLabel?.cell?.stringValue = "Router version: Still unknown" } - if (RouterProcessStatus.routerStartedAt != Optional.none) { - routerUptimeLabel?.cell?.stringValue = "Router has runned for " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: RouterProcessStatus.routerStartedAt!), numericDates: false) + if let routerStartTime = RouterProcessStatus.routerStartedAt { + routerUptimeLabel?.cell?.stringValue = "Router has runned for " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: routerStartTime), numericDates: false) } } diff --git a/launchers/macosx/Info.plist b/launchers/macosx/Info.plist index b63c2dbba..f07062c05 100644 --- a/launchers/macosx/Info.plist +++ b/launchers/macosx/Info.plist @@ -9,7 +9,7 @@ NSHumanReadableCopyright Public Domain CFBundleGetInfoString - 0.9.35-experimental + 0.9.36-experimental CFBundleIconFile images/AppIcon.icns CFBundleIdentifier diff --git a/launchers/macosx/JavaHelper.h b/launchers/macosx/JavaHelper.h deleted file mode 100644 index 8cae0dc83..000000000 --- a/launchers/macosx/JavaHelper.h +++ /dev/null @@ -1,167 +0,0 @@ -#pragma once - -#ifdef __cplusplus - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "RouterTask.h" - - -#define DEF_MIN_JVM_VER "1.7+" - -#include "include/strutil.hpp" - -#include -#include -#include - - -class JvmVersion -{ -public: - std::string JVMName; - std::string JVMHomePath; - std::string JVMPlatformVersion; - - inline const char * ToCString() - { - std::stringstream ss; - ss << "JvmVersion(name=" << JVMName.c_str() << ",version="; - ss << JVMPlatformVersion.c_str() << ",home=" << JVMHomePath.c_str() << ")"; - std::string s = ss.str(); - return s.c_str(); - } - - inline bool HasContent() - { - return ( - std::strlen(JVMName.c_str()) > 0 && - std::strlen(JVMHomePath.c_str()) > 0 && - std::strlen(JVMPlatformVersion.c_str()) > 0 - ); - } -}; - - -typedef std::shared_ptr JvmVersionPtr; -typedef std::shared_ptr > JvmListPtr; -typedef std::shared_ptr > > JvmListSharedPtr; -typedef void(^MenuBarControllerActionBlock)(BOOL active); - -extern JvmListSharedPtr gRawJvmList; - -class JvmHomeContext : public std::enable_shared_from_this -{ -public: - - inline void setJvm(JvmVersionPtr* current) - { - mCurrent = *current; - } - - inline JvmListPtr getJvmList() - { - return gRawJvmList; - } - - inline std::shared_ptr getContext() - { - return shared_from_this(); - } - - inline std::string getJavaHome() - { - if (mCurrent) - { - return mCurrent->JVMHomePath; - } - return gRawJvmList->back()->JVMHomePath; - } -private: - JvmVersionPtr mCurrent; -}; - -static void processJvmEntry (const void* key, const void* value, void* context) { - //CFShow(key); - //CFShow(value); - - // The reason for using strprintf is to "force" a copy of the values, - // since local variables gets deleted once this function returns. - auto currentJvm = reinterpret_cast(context); - if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) { - auto strVal = extractString((CFStringRef)value); - currentJvm->JVMName = strprintf("%s",strVal.c_str()); - } - if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) { - auto strVal = extractString((CFStringRef)value); - currentJvm->JVMHomePath = strprintf("%s",strVal.c_str()); - } - if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) { - auto strVal = extractString((CFStringRef)value); - currentJvm->JVMPlatformVersion = strprintf("%s",strVal.c_str()); - } -} - - - -static void processJvmPlistEntries (const void* item, void* context) { - CFDictionaryRef dict = CFDictionaryCreateCopy(kCFAllocatorDefault, (CFDictionaryRef)item); - - JvmVersionPtr currentJvmPtr = std::shared_ptr(new JvmVersion()); - struct CFunctional - { - static void applier(const void* key, const void* value, void* context){ - // The reason for using strprintf is to "force" a copy of the values, - // since local variables gets deleted once this function returns. - auto currentJvm = static_cast(context); - if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) { - auto d = extractString((CFStringRef)value); - currentJvm->JVMName = trim_copy(d); - } - if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) { - auto d = extractString((CFStringRef)value); - currentJvm->JVMHomePath = trim_copy(d); - } - if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) { - auto d = extractString((CFStringRef)value); - currentJvm->JVMPlatformVersion = trim_copy(d); - } - - } - }; - - CFDictionaryApplyFunction(dict, CFunctional::applier, (void*)currentJvmPtr.get()); - - if (currentJvmPtr->HasContent()) - { - printf("Found JVM: %s\n\n", currentJvmPtr->ToCString()); - gRawJvmList->push_back(currentJvmPtr); - } -} - -static void listAllJavaInstallsAvailable() -{ - auto javaHomeRes = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER,"-X"}); - CFDataRef javaHomes = CFDataCreate(NULL, (const UInt8 *)javaHomeRes.buf.data(), strlen(javaHomeRes.buf.data())); - - CFPropertyListRef propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, javaHomes, kCFPropertyListImmutable, NULL, NULL); - - - - auto jCount = CFArrayGetCount((CFArrayRef)propertyList); - - CFArrayApplyFunction((CFArrayRef)propertyList, CFRangeMake(0, jCount), processJvmPlistEntries, NULL); - //CFShow(propertyList); -} - -#endif diff --git a/launchers/macosx/README.md b/launchers/macosx/README.md index 800320bd1..e8aad2993 100644 --- a/launchers/macosx/README.md +++ b/launchers/macosx/README.md @@ -1,9 +1,18 @@ # The Mac OS X Launcher +## Misc + **Note** this project is WIP, cause Meeh has yet to merge in Obj-C/Swift code for GUI stuff in OSX. However, this is a thin wrapper launching both Mac OS X trayicon and the I2P router - and make them talk together. More code will be merged in, it's just a f* mess which Meeh needs to clean up and move into repo. -`./fullBuild.sh` triggers Ant jobs and prepare the base.zip, as well as starting the ninja build. +## Howto build + +You can both build the project from the Xcode UI or you can build it from command line. + +An example build command: +`xcodebuild -target I2PLauncher -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk` + + diff --git a/launchers/macosx/RouterTask.h b/launchers/macosx/RouterTask.h index e81cd924c..762a31853 100644 --- a/launchers/macosx/RouterTask.h +++ b/launchers/macosx/RouterTask.h @@ -2,48 +2,28 @@ #include #include -#include #include #import #ifdef __cplusplus -#include "include/subprocess.hpp" +#include +#include -using namespace subprocess; -class JavaRunner; +const std::vector defaultStartupFlags { + @"-Xmx512M", + @"-Xms128m", + @"-Djava.awt.headless=true", + @"-Dwrapper.logfile=/tmp/router.log", + @"-Dwrapper.logfile.loglevel=DEBUG", + @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid", + @"-Dwrapper.console.loglevel=DEBUG" +}; -typedef std::function fp_t; -typedef std::function fp_proc_t; - - - -/** - * - * class JavaRunner - * - **/ -class JavaRunner -{ -public: - // copy fn - JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& executingFn, const fp_t& cb); - ~JavaRunner() = default; - - static const std::vector defaultStartupFlags; - static const std::vector defaultFlagsForExtractorJob; - - void requestRouterShutdown(); - - std::future execute(); - std::shared_ptr javaProcess; - std::string javaBinaryPath; - std::string javaRouterArgs; - std::string execLine; - std::string _i2pBaseDir; -private: - const fp_proc_t& executingFn; - const fp_t& exitCallbackFn; +const std::vector defaultFlagsForExtractorJob { + "-Xmx512M", + "-Xms128m", + "-Djava.awt.headless=true" }; #endif diff --git a/launchers/macosx/RouterTask.mm b/launchers/macosx/RouterTask.mm index 202614011..8fc231780 100644 --- a/launchers/macosx/RouterTask.mm +++ b/launchers/macosx/RouterTask.mm @@ -9,6 +9,7 @@ #import "I2PLauncher-Swift.h" #include "AppDelegate.h" #endif + #include "include/PidWatcher.h" #import @@ -49,28 +50,16 @@ name:NSFileHandleDataAvailableNotification object:stdoutFileHandle]; - [stdoutFileHandle waitForDataInBackgroundAndNotify]; + [stdoutFileHandle waitForDataInBackgroundAndNotify]; - [self.routerTask setTerminationHandler:^(NSTask* task) { - NSLog(@"termHandler triggered!"); - auto swiftRouterStatus = [[RouterProcessStatus alloc] init]; - [swiftRouterStatus setRouterStatus: true]; - NSBundle *launcherBundle = [NSBundle mainBundle]; - auto iconImage = [launcherBundle pathForResource:@"AppIcon" ofType:@"png"]; - sendUserNotification(APP_IDSTR, @"I2P Router has stopped"); - // Cleanup - self.isRouterRunning = NO; - }]; -/* - self.readLogHandle = [self.processPipe fileHandleForReading]; - NSData *inData = nil; - self.totalLogData = [[[NSMutableData alloc] init] autorelease]; - - while ((inData = [self.readLogHandle availableData]) && - [inData length]) { - [self.totalLogData appendData:inData]; - } -*/ + [self.routerTask setTerminationHandler:^(NSTask* task) { + // Cleanup + NSLog(@"termHandler triggered!"); + auto swiftRouterStatus = [[RouterProcessStatus alloc] init]; + [swiftRouterStatus setRouterStatus: false]; + [swiftRouterStatus setRouterRanByUs: false]; + sendUserNotification(APP_IDSTR, @"I2P Router has stopped"); + }]; return self; } @@ -93,80 +82,25 @@ - (int) execute { @try { - [self.routerTask launch]; - watchPid([self.routerTask processIdentifier]); - self.isRouterRunning = YES; - return 1; + [self.routerTask launch]; + watchPid([self.routerTask processIdentifier]); + self.isRouterRunning = YES; + return 1; } @catch (NSException *e) { NSLog(@"Expection occurred %@", [e reason]); - return 0; + auto swiftRouterStatus = [[RouterProcessStatus alloc] init]; + [swiftRouterStatus setRouterStatus: false]; + [swiftRouterStatus setRouterRanByUs: false]; + sendUserNotification(@"An error occured, can't start the I2P Router", [e reason]); + return 0; } } - (int) getPID { - return [self.routerTask processIdentifier]; + return [self.routerTask processIdentifier]; } @end - -#ifdef __cplusplus - - -const std::vector JavaRunner::defaultStartupFlags { - @"-Xmx512M", - @"-Xms128m", - @"-Djava.awt.headless=true", - @"-Dwrapper.logfile=/tmp/router.log", - @"-Dwrapper.logfile.loglevel=DEBUG", - @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid", - @"-Dwrapper.console.loglevel=DEBUG" -}; - -const std::vector JavaRunner::defaultFlagsForExtractorJob { - "-Xmx512M", - "-Xms128m", - "-Djava.awt.headless=true" -}; - -JavaRunner::JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& execFn, const fp_t& cb) - : javaBinaryPath(javaBin), javaRouterArgs(arguments), _i2pBaseDir(i2pBaseDir), executingFn(execFn), exitCallbackFn(cb) -{ - execLine = javaBinaryPath; - execLine += " " + std::string(javaRouterArgs.c_str()); - printf("CLI: %s\n",execLine.c_str()); - javaProcess = std::shared_ptr(new Popen(execLine, environment{{ - {"I2PBASE", _i2pBaseDir}, - {"JAVA_OPTS", getenv("JAVA_OPTS")} - }}, defer_spawn{true})); -} - -void JavaRunner::requestRouterShutdown() -{ - // SIGHUP - javaProcess->kill(1); -} - -std::future JavaRunner::execute() -{ - try { - auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{ - this->executingFn(this); - }); - dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), executingFn); - dispatch_block_wait(executingFn, DISPATCH_TIME_FOREVER); - - // Here, the process is done executing. - - printf("Finished executingFn - Runs callbackFn\n"); - this->exitCallbackFn(); - return std::async(std::launch::async, []{ return 0; }); - } catch (std::exception* ex) { - printf("ERROR: %s\n", ex->what()); - return std::async(std::launch::async, []{ return 1; }); - } -} - -#endif diff --git a/launchers/macosx/SBridge.h b/launchers/macosx/SBridge.h new file mode 100644 index 000000000..1b52151ec --- /dev/null +++ b/launchers/macosx/SBridge.h @@ -0,0 +1,60 @@ +// +// SBridge.h +// I2PLauncher +// +// Created by Mikal Villa on 18/09/2018. +// Copyright © 2018 The I2P Project. All rights reserved. +// + +#import +#import + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include "include/fn.h" +std::future startupRouter(NSString* javaBin, NSArray* arguments, NSString* i2pBaseDir); + + +namespace osx { + inline void openUrl(NSString* url) + { + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: url]]; + } +} + +inline std::vector globVector(const std::string& pattern){ + glob_t glob_result; + glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result); + std::vector files; + for(unsigned int i=0;i +#include +#include +#include +#include +#include +#include +#include + +#import +#import "I2PLauncher-Swift.h" + +#include "AppDelegate.h" +#include "include/fn.h" + + + +std::future startupRouter(NSString* javaBin, NSArray* arguments, NSString* i2pBaseDir) { + @try { + RTaskOptions* options = [RTaskOptions alloc]; + options.binPath = javaBin; + options.arguments = arguments; + options.i2pBaseDir = i2pBaseDir; + auto instance = [[I2PRouterTask alloc] initWithOptions: options]; + [instance execute]; + sendUserNotification(APP_IDSTR, @"The I2P router is starting up."); + auto pid = [instance getPID]; + return std::async(std::launch::async, [&pid]{ + return pid; + }); + } + @catch (NSException *e) + { + auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]]; + NSLog(@"%@", errStr); + sendUserNotification(APP_IDSTR, errStr); + return std::async(std::launch::async, [&]{ + return 0; + }); + } +} + + + +@implementation SBridge + + +- (void) openUrl:(NSString*)url +{ + osx::openUrl(url); +} + +- (NSString*) buildClassPath:(NSString*)i2pPath +{ + const char * basePath = [i2pPath UTF8String]; + auto jarList = buildClassPathForObjC(basePath); + const char * classpath = jarList.c_str(); + NSLog(@"Classpath from ObjC = %s", classpath); + return [[NSString alloc] initWithUTF8String:classpath]; +} + + + +- (void)startupI2PRouter:(NSString*)i2pRootPath javaBinPath:(NSString*)javaBinPath +{ + std::string basePath([i2pRootPath UTF8String]); + + // Get paths + //NSBundle *launcherBundle = [NSBundle mainBundle]; + auto classPathStr = buildClassPathForObjC(basePath); + + RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init]; + try { + std::vector argList = { + @"-Xmx512M", + @"-Xms128m", + @"-Djava.awt.headless=true", + @"-Dwrapper.logfile=/tmp/router.log", + @"-Dwrapper.logfile.loglevel=DEBUG", + @"-Dwrapper.java.pidfile=/tmp/routerjvm.pid", + @"-Dwrapper.console.loglevel=DEBUG" + }; + + std::string baseDirArg("-Di2p.dir.base="); + baseDirArg += basePath; + std::string javaLibArg("-Djava.library.path="); + javaLibArg += basePath; + // TODO: pass this to JVM + //auto java_opts = getenv("JAVA_OPTS"); + + std::string cpString = std::string("-cp"); + + argList.push_back([NSString stringWithUTF8String:baseDirArg.c_str()]); + argList.push_back([NSString stringWithUTF8String:javaLibArg.c_str()]); + argList.push_back([NSString stringWithUTF8String:cpString.c_str()]); + argList.push_back([NSString stringWithUTF8String:classPathStr.c_str()]); + argList.push_back(@"net.i2p.router.Router"); + auto javaBin = std::string([javaBinPath UTF8String]); + + + sendUserNotification(APP_IDSTR, @"I2P Router is starting up!"); + auto nsJavaBin = javaBinPath; + auto nsBasePath = i2pRootPath; + NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()]; + // We don't really know yet, but per now a workaround + [routerStatus setRouterStatus: true]; + NSLog(@"Trying to run command: %@", javaBinPath); + NSLog(@"With I2P Base dir: %@", i2pRootPath); + NSLog(@"And Arguments: %@", arrArguments); + startupRouter(nsJavaBin, arrArguments, nsBasePath); + } catch (std::exception &err) { + auto errMsg = [NSString stringWithUTF8String:err.what()]; + NSLog(@"Exception: %@", errMsg); + sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]); + [routerStatus setRouterStatus: false]; + [routerStatus setRouterRanByUs: false]; + } +} +@end + + +#endif diff --git a/launchers/macosx/fullBuild.sh b/launchers/macosx/fullBuild.sh deleted file mode 100755 index f6c9a84e4..000000000 --- a/launchers/macosx/fullBuild.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd ../../.. -ant preppkg-osx-only -cd pkg-temp -zip -r7 $DIR/base.zip * -echo "[+] Done building base.zip from ant's pkg-temp." -ninja appbundle - diff --git a/launchers/macosx/include/strutil.hpp b/launchers/macosx/include/strutil.hpp index 270331543..ab52a1c01 100644 --- a/launchers/macosx/include/strutil.hpp +++ b/launchers/macosx/include/strutil.hpp @@ -53,16 +53,12 @@ inline std::string extractString(CFStringRef value) } } -using std::experimental::optional; - -// Use CFStringRef instead of NSString*, otherwise disable ARC -inline optional optionalString(bool val) { - optional myOptString; - if(val) { - // Cast to corresponding CoreFoundation object - myOptString = (CFStringRef)@"String"; - } - return myOptString; +inline bool replace(std::string& str, const std::string& from, const std::string& to) { + size_t start_pos = str.find(from); + if(start_pos == std::string::npos) + return false; + str.replace(start_pos, from.length(), to); + return true; } @@ -102,4 +98,22 @@ static inline std::string trim_copy(std::string s) { return s; } +#if __cplusplus > 201402L + + +using std::optional; + +// Use CFStringRef instead of NSString*, otherwise disable ARC +inline optional optionalString(bool val) { + optional myOptString; + if(val) { + // Cast to corresponding CoreFoundation object + myOptString = (CFStringRef)@"String"; + } + return myOptString; +} + +#endif + + #endif diff --git a/launchers/macosx/include/traits.hpp b/launchers/macosx/include/traits.hpp deleted file mode 100644 index e490de95f..000000000 --- a/launchers/macosx/include/traits.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef NEITHER_TRAITS_HPP -#define NEITHER_TRAITS_HPP - -namespace neither { - -template -struct Either; - -template -struct Maybe; - -template -auto isCopyable (L l, Xs...) -> L { - return l; -} - -template -auto ensureEither ( Either const& e) -> Either { - return e; -} - -template -auto ensureEither ( Either && e) -> Either { - return e; -} - -template -auto ensureEitherRight ( Either const& e, R) -> Either { - return e; -} - - -template -auto ensureEitherRight ( Either&& e, R&&) -> Either { - return e; -} - - -template -auto ensureEitherLeft ( Either const& e, L) -> Either { - return e; -} - -template -auto ensureEitherLeft ( Either&& e, L&& ) -> Either { - return e; -} - - -template -auto ensureMaybe ( Maybe const& e) -> Maybe { - return e; -} - -} - -#endif diff --git a/launchers/macosx/main.mm b/launchers/macosx/main.mm index 751f20e32..faf4cc8fd 100644 --- a/launchers/macosx/main.mm +++ b/launchers/macosx/main.mm @@ -11,14 +11,6 @@ #import #import - - -#include -#include -#include -#include -#include -#include #include #import @@ -30,94 +22,43 @@ #include "AppDelegate.h" #include "RouterTask.h" -#include "JavaHelper.h" #include "include/fn.h" #include "include/portcheck.h" +#import "SBridge.h" + +#ifdef __cplusplus +#include + +#include "include/subprocess.hpp" +#include "include/strutil.hpp" + +using namespace subprocess; + +#endif #define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]); @interface AppDelegate () @end -#ifdef __cplusplus -#import "SBridge.h" -JvmListSharedPtr gRawJvmList = nullptr; -#endif - - -@interface AppDelegate () -@end - -#ifdef __cplusplus -maybeAnRouterRunner getGlobalRouterObject() -{ - std::lock_guard lock(globalRouterStatusMutex); - return globalRouterStatus; // Remember this might be nullptr now. -} - -void setGlobalRouterObject(I2PRouterTask* newRouter) -{ - std::lock_guard lock(globalRouterStatusMutex); - globalRouterStatus = newRouter; -} - - -pthread_mutex_t mutex; - -bool getGlobalRouterIsRunning() -{ - pthread_mutex_lock(&mutex); - bool current = isRuterRunning; - pthread_mutex_unlock(&mutex); - return current; -} -void setGlobalRouterIsRunning(bool running) -{ - pthread_mutex_lock(&mutex); - isRuterRunning = running; - pthread_mutex_unlock(&mutex); -} - -#endif - @implementation ExtractMetaInfo : NSObject @end -#ifdef __cplusplus - -bool replace(std::string& str, const std::string& from, const std::string& to) { - size_t start_pos = str.find(from); - if(start_pos == std::string::npos) - return false; - str.replace(start_pos, from.length(), to); - return true; -} - -#endif @implementation AppDelegate - (void) awakeFromNib { } -#ifdef __cplusplus -#include -#include -#include -#include - -#include "include/subprocess.hpp" - -using namespace subprocess; - -const char* RealHomeDirectory() { - struct passwd *pw = getpwuid(getuid()); - assert(pw); - return pw->pw_dir; +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center + shouldPresentNotification:(NSUserNotification *)notification { + return YES; } +#ifdef __cplusplus + - (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion { @@ -151,7 +92,7 @@ const char* RealHomeDirectory() { // Create directory mkdir(basePath.c_str(), S_IRUSR | S_IWUSR | S_IXUSR); - auto cli = JavaRunner::defaultFlagsForExtractorJob; + auto cli = defaultFlagsForExtractorJob; setenv("I2PBASE", basePath.c_str(), true); setenv("ZIPPATH", zippath.c_str(), true); //setenv("DYLD_LIBRARY_PATH",".:/usr/lib:/lib:/usr/local/lib", true); @@ -161,27 +102,9 @@ const char* RealHomeDirectory() { cli.push_back(jarfile); cli.push_back("net.i2p.launchers.BaseExtractor"); auto rs = [[RouterProcessStatus alloc] init]; - NSString* jh = [rs getJavaHome]; - if (jh != nil) { - NSLog(@"jh er %@", jh); - } - NSString* newString = [NSString stringWithFormat:@"file://%@", rs.getJavaHome]; - NSURL *baseURL = [NSURL fileURLWithPath:newString]; - - NSLog(@"MEEH URL PATH: %s", [baseURL fileSystemRepresentation]); - - auto charCli = map(cli, [](std::string str){ return str.c_str(); }); std::string execStr = std::string([rs.getJavaHome UTF8String]); - // TODO: Cheap hack, make it better. - replace(execStr, "Internet Plug-Ins", "Internet\\ Plug-Ins"); - replace(execStr, "\n", ""); - NSLog(@"Java path1 = %s", execStr.c_str()); - [rs setJavaHome: [NSString stringWithFormat:@"%s", execStr.c_str()]]; for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; }); - - //execStr = replace(execStr, "\\\\ ", "\\ "); - //NSLog(@"Java path2 = %s", execStr.c_str()); NSLog(@"Trying cmd: %@", [NSString stringWithUTF8String:execStr.c_str()]); try { @@ -193,9 +116,7 @@ const char* RealHomeDirectory() { NSLog(@"Extraction exit code %@",[NSString stringWithUTF8String:(std::to_string(extractStatus)).c_str()]); if (extractStatus == 0) { - //success = YES; - NSLog(@"Time to detect I2P version in install directory"); - [self.swiftRuntime findInstalledI2PVersion]; + NSLog(@"Extraction complete!"); } } catch (subprocess::OSError &err) { @@ -207,7 +128,6 @@ const char* RealHomeDirectory() { // All done. Assume success and error are already set. dispatch_async(dispatch_get_main_queue(), ^{ - //sendUserNotification(APP_IDSTR, @"Extraction complete!", self.contentImage); if (completion) { completion(success, error); } @@ -219,79 +139,15 @@ const char* RealHomeDirectory() { NSLog(@"Exception: %@", errMsg); } }); - - } -#endif - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center - shouldPresentNotification:(NSUserNotification *)notification { - return YES; -} - - -#ifdef __cplusplus - -inline std::string getDefaultBaseDir() -{ - // Figure out base directory - const char* pathFromHome = "/Users/%s/Library/I2P"; - auto username = getenv("USER"); - char buffer[strlen(pathFromHome)+strlen(username)]; - sprintf(buffer, pathFromHome, username); - std::string i2pBaseDir(buffer); - return i2pBaseDir; -} - -- (NSString *)userSelectJavaHome:(JvmListPtr)rawJvmList -{ - NSString *appleScriptString = @"set jvmlist to {\"Newest\""; - for (auto item : *rawJvmList) { - auto str = strprintf(",\"%s\"", item->JVMName.c_str()).c_str(); - NSString* tmp = [NSString stringWithUTF8String:str]; - appleScriptString = [appleScriptString stringByAppendingString:tmp]; - } - appleScriptString = [appleScriptString stringByAppendingString:@"}\nchoose from list jvmlist\n"]; - NSAppleScript *theScript = [[NSAppleScript alloc] initWithSource:appleScriptString]; - NSDictionary *theError = nil; - NSString* userResult = [[theScript executeAndReturnError: &theError] stringValue]; - NSLog(@"User choosed %@.\n", userResult); - if (theError != nil) - { - NSLog(@"Error: %@.\n", theError); - } - return userResult; -} - - -- (void)userChooseJavaHome { - listAllJavaInstallsAvailable(); - std::shared_ptr appContext = std::shared_ptr( new JvmHomeContext() ); - for (auto item : *appContext->getJvmList()) { - printf("JVM %s (Version: %s, Directory: %s)\n", item->JVMName.c_str(), item->JVMPlatformVersion.c_str(), item->JVMHomePath.c_str()); - } - JvmListPtr rawJvmList = appContext->getJvmList(); - NSString * userJavaHome = [self userSelectJavaHome: rawJvmList]; - // TODO: Add logic so user can set preferred JVM -} - -#endif - - (void)setApplicationDefaultPreferences { - auto defaultJVMHome = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER}); - auto tmpStdStr = std::string(defaultJVMHome.buf.data()); - trim(tmpStdStr); - auto cfDefaultHome = CFStringCreateWithCString(NULL, const_cast(tmpStdStr.c_str()), kCFStringEncodingUTF8); - /*[self.userPreferences registerDefaults:@{ - @"javaHome" : (NSString *)cfDefaultHome, - @"lastI2PVersion" : (NSString *)CFSTR(DEF_I2P_VERSION), + [self.userPreferences registerDefaults:@{ @"enableLogging": @YES, @"enableVerboseLogging": @YES, @"autoStartRouter": @YES, @"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8) - }];*/ - if (self.enableVerboseLogging) NSLog(@"Default JVM home preference set to: %@", cfDefaultHome); + }]; auto dict = [self.userPreferences dictionaryRepresentation]; [self.userPreferences setPersistentDomain:dict forName:NSAPPDOMAIN]; @@ -302,51 +158,36 @@ inline std::string getDefaultBaseDir() if (self.enableVerboseLogging) NSLog(@"Default preferences stored!"); } +#endif + - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Init application here self.swiftRuntime = [[SwiftMainDelegate alloc] init]; + // This setup allows the application to send notifications [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self]; + + // Start with user preferences self.userPreferences = [NSUserDefaults standardUserDefaults]; [self setApplicationDefaultPreferences]; self.enableLogging = [self.userPreferences boolForKey:@"enableLogging"]; self.enableVerboseLogging = [self.userPreferences boolForKey:@"enableVerboseLogging"]; - - -#ifdef __cplusplus - gRawJvmList = std::make_shared >(std::list()); -#endif // In case we are unbundled, make us a proper UI application [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; [NSApp activateIgnoringOtherApps:YES]; - // TODO: Also check for new installations from time to time. - + #ifdef __cplusplus - auto javaHomePref = [self.userPreferences stringForKey:@"javaHome"]; - if (self.enableVerboseLogging) - { - NSLog(@"Java home from preferences: %@", javaHomePref); - } - if (self.enableVerboseLogging) - { - NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; - NSLog(@"Appdomain is: %@", appDomain); - } - - NSLog(@"We should have started the statusbar object by now..."); RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init]; - std::string i2pBaseDir(getDefaultBaseDir()); - - auto pref = self.userPreferences; - + NSLog(@"i2pBaseDir = %s", i2pBaseDir.c_str()); bool shouldAutoStartRouter = false; - + + // TODO: Make the port a setting which defaults to 7657 if (port_check(7657) != 0) { NSLog(@"Seems i2p is already running - I will not start the router (port 7657 is in use..)"); @@ -354,51 +195,32 @@ inline std::string getDefaultBaseDir() [routerStatus setRouterStatus: true]; [routerStatus setRouterRanByUs: false]; - return; + shouldAutoStartRouter = false; } else { shouldAutoStartRouter = true; } if (self.enableVerboseLogging) NSLog(@"processinfo %@", [[NSProcessInfo processInfo] arguments]); - auto getJavaBin = [&pref,&self]() -> std::string { - // Get Java home - /*NSString* val = @""; - val = [pref stringForKey:@"javaHome"]; - if (val == NULL) val = @""; - if (self.enableVerboseLogging) NSLog(@"Javahome: %@", val); - auto javaHome = std::string([val UTF8String]); - //trim(javaHome); // Trim to remove endline - auto javaBin = std::string(javaHome); - javaBin += "/bin/java"; // Append java binary to path. - return javaBin;*/ - DetectJava *dt = [[DetectJava alloc] init]; - [dt findIt]; - if ([dt isJavaFound]) { - return [dt.javaHome UTF8String]; - } else { - throw new std::runtime_error("Java home fatal error"); - } - }; - NSBundle *launcherBundle = [NSBundle mainBundle]; + auto sBridge = [[SBridge alloc] init]; - auto jarResPath = [launcherBundle pathForResource:@"launcher" ofType:@"jar"]; - NSLog(@"Trying to load launcher.jar from url = %@", jarResPath); - + // Helper object to hold statefull path information self.metaInfo = [[ExtractMetaInfo alloc] init]; - //self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()]; - self.metaInfo.javaBinary = [NSString stringWithUTF8String:getJavaBin().c_str()]; + self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()]; + self.metaInfo.javaBinary = [routerStatus getJavaHome]; self.metaInfo.jarFile = [launcherBundle pathForResource:@"launcher" ofType:@"jar"]; self.metaInfo.zipFile = [launcherBundle pathForResource:@"base" ofType:@"zip"]; std::string basearg("-Di2p.dir.base="); - //basearg += i2pBaseDir; + basearg += i2pBaseDir; std::string jarfile("-cp "); jarfile += [self.metaInfo.zipFile UTF8String]; + // Initialize the Swift environment (the UI components) + [self.swiftRuntime applicationDidFinishLaunching]; struct stat sb; if ( !(stat(i2pBaseDir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) ) @@ -406,17 +228,29 @@ inline std::string getDefaultBaseDir() // I2P is not extracted. if (self.enableVerboseLogging) NSLog(@"I2P Directory don't exists!"); + // Might be hard to read if you're not used to Objective-C + // But this is a "function call" that contains a "callback function" [self extractI2PBaseDir:^(BOOL success, NSError *error) { sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!"); - [self.swiftRuntime applicationDidFinishLaunching]; NSLog(@"Done extracting I2P"); - if (shouldAutoStartRouter) [self startupI2PRouter]; + + NSLog(@"Time to detect I2P version in install directory"); + [self.swiftRuntime findInstalledI2PVersion]; + if (shouldAutoStartRouter) { + [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary]; + [routerStatus setRouterRanByUs: true]; + } }]; } else { - if (self.enableVerboseLogging) NSLog(@"I2P directory found!"); - if (shouldAutoStartRouter) [self startupI2PRouter]; - [self.swiftRuntime applicationDidFinishLaunching]; + // I2P was already found extracted + NSLog(@"Time to detect I2P version in install directory"); + [self.swiftRuntime findInstalledI2PVersion]; + + if (shouldAutoStartRouter) { + [sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary]; + [routerStatus setRouterRanByUs: true]; + } } #endif @@ -448,15 +282,20 @@ inline std::string getDefaultBaseDir() int main(int argc, const char **argv) { NSApplication *app = [NSApplication sharedApplication]; - //NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; AppDelegate *appDelegate = [[AppDelegate alloc] initWithArgc:argc argv:argv]; app.delegate = appDelegate; + auto mainBundle = [NSBundle mainBundle]; + NSString* stringNameBundle = [mainBundle objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey]; + if ([[NSRunningApplication runningApplicationsWithBundleIdentifier:[mainBundle bundleIdentifier]] count] > 1) { + [[NSAlert alertWithMessageText:[NSString stringWithFormat:@"Another copy of %@ is already running.",stringNameBundle] + defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"This copy will now quit."] runModal]; + + [NSApp terminate:nil]; + } [NSBundle loadNibNamed:@"I2Launcher" owner:NSApp]; [NSApp run]; - // Handle any errors - //[pool drain]; return 0; } diff --git a/licenses/LICENSE-neither.txt b/licenses/LICENSE-neither.txt deleted file mode 100644 index 109f45da4..000000000 --- a/licenses/LICENSE-neither.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 LoopPerfect - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.