Changeset f76874a
- Timestamp:
- Sep 18, 2018 3:39:32 PM (2 years ago)
- Branches:
- master
- Children:
- 01a05f7
- Parents:
- 7615b92
- Location:
- launchers/macosx
- Files:
-
- 10 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
launchers/macosx/AppDelegate.h
r7615b92 rf76874a 2 2 #define __APPDELEGATE_H__ 3 3 4 #include <algorithm> 5 #include <string >6 #include <memory >4 5 #include <string.h> 6 #include <memory.h> 7 7 8 8 #include <Cocoa/Cocoa.h> 9 9 10 10 11 #include "RouterTask.h" 11 #include "StatusItemButton.h"12 12 #include "JavaHelper.h" 13 #include "neither/maybe.hpp"14 #include "optional.hpp"15 #include "subprocess.hpp"16 #include <glob.h>17 #include <vector>18 13 19 14 20 #define DEF_I2P_VERSION "0.9.3 5"15 #define DEF_I2P_VERSION "0.9.36" 21 16 #define APPDOMAIN "net.i2p.launcher" 22 17 #define NSAPPDOMAIN @APPDOMAIN … … 24 19 #define APP_IDSTR @"I2P Launcher" 25 20 21 @class SwiftMainDelegate; 26 22 27 using namespace neither; 23 @protocol SwiftMainDelegateProto 24 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification; 25 @end 26 28 27 29 28 @class ExtractMetaInfo; 30 using maybeAnRouterRunner = std::experimental::optional<I2PRouterTask*>; 29 30 31 32 @interface ExtractMetaInfo : NSObject 33 @property (copy) NSString* i2pBase; 34 @property (copy) NSString* javaBinary; 35 @property (copy) NSString* zipFile; 36 @property (copy) NSString* jarFile; 37 @end 38 #ifdef __cplusplus 39 #include "JavaHelper.h" 40 41 inline void sendUserNotification(NSString* title, NSString* informativeText, NSImage* contentImage = NULL, bool makeSound = false) { 42 NSUserNotification *userNotification = [[[NSUserNotification alloc] init] autorelease]; 43 44 userNotification.title = title; 45 userNotification.informativeText = informativeText; 46 NSBundle *launcherBundle = [NSBundle mainBundle]; 47 auto resPath = [launcherBundle resourcePath]; 48 auto stdResPath = std::string([resPath UTF8String]); 49 stdResPath += "/AppImage.png"; 50 auto nsString = [[NSString alloc] initWithUTF8String:(const char*)stdResPath.c_str()]; 51 NSImage *appImage = [[NSImage alloc] initWithContentsOfFile:nsString]; 52 userNotification.contentImage = appImage; 53 if (makeSound) userNotification.soundName = NSUserNotificationDefaultSoundName; 54 55 [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification]; 56 }; 57 58 using maybeAnRouterRunner = I2PRouterTask*; 31 59 32 60 std::vector<std::string> buildClassPath(std::string basePath); … … 44 72 void setGlobalRouterIsRunning(bool running); 45 73 46 @interface ExtractMetaInfo : NSObject 47 @property (copy) NSString* i2pBase; 48 @property (copy) NSString* javaBinary; 49 @property (copy) NSString* zipFile; 50 @property (copy) NSString* jarFile; 51 @end 74 #include "SBridge.h" 52 75 53 @class I2PStatusMenu; 54 @interface I2PStatusMenu : NSMenu 55 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem; 56 @end 76 #endif 57 77 58 inline void sendUserNotification(NSString* title, NSString* informativeText, NSImage* contentImage = NULL, bool makeSound = false) { 59 NSUserNotification *userNotification = [[[NSUserNotification alloc] init] autorelease]; 60 61 userNotification.title = title; 62 userNotification.informativeText = informativeText; 63 if (contentImage != NULL) userNotification.contentImage = contentImage; 64 if (makeSound) userNotification.soundName = NSUserNotificationDefaultSoundName; 65 66 [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:userNotification]; 67 }; 68 69 inline std::vector<std::string> globVector(const std::string& pattern){ 70 glob_t glob_result; 71 glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result); 72 std::vector<std::string> files; 73 for(unsigned int i=0;i<glob_result.gl_pathc;++i){ 74 files.push_back(std::string(glob_result.gl_pathv[i])); 75 } 76 globfree(&glob_result); 77 return files; 78 } 79 80 inline std::string getDefaultBaseDir() 81 { 82 // Figure out base directory 83 const char* pathFromHome = "/Users/%s/Library/I2P"; 84 auto username = getenv("USER"); 85 char buffer[strlen(pathFromHome)+strlen(username)]; 86 sprintf(buffer, pathFromHome, username); 87 std::string i2pBaseDir(buffer); 88 return i2pBaseDir; 89 } 90 91 @interface MenuBarCtrl : NSObject <StatusItemButtonDelegate, NSMenuDelegate> 92 @property BOOL enableLogging; 93 @property BOOL enableVerboseLogging; 94 @property (strong) I2PStatusMenu *menu; 95 @property (strong) StatusItemButton* statusBarButton; 96 @property (strong) NSUserDefaults *userPreferences; 97 @property (strong, nonatomic) NSImage * image; 98 @property (strong, nonatomic) NSStatusItem *statusItem; 99 // Event handlers 100 - (void) statusItemButtonLeftClick: (StatusItemButton *) button; 101 - (void) statusItemButtonRightClick: (StatusItemButton *) button; 102 - (void) statusBarImageBtnClicked; 103 - (void) btnPressedAction:(id)sender; 104 - (void) menuWillOpen:(I2PStatusMenu *)menu; 105 106 - (void) openRouterConsoleBtnHandler: (NSMenuItem *) menuItem; 107 - (void) startJavaRouterBtnHandler: (NSMenuItem *) menuItem; 108 - (void) restartJavaRouterBtnHandler: (NSMenuItem *) menuItem; 109 - (void) stopJavaRouterBtnHandler: (NSMenuItem *) menuItem; 110 - (void) quitWrapperBtnHandler: (NSMenuItem *) menuItem; 111 // Methods 112 - (MenuBarCtrl *) init; 113 - (void) dealloc; 114 - (I2PStatusMenu *) createStatusBarMenu; 115 @end 116 117 @protocol MenuBarCtrlDelegate 118 - (void) menuBarCtrlStatusChanged: (BOOL) active; 119 @end 78 @class MenuBarCtrl; 120 79 121 80 @interface AppDelegate : NSObject <NSUserNotificationCenterDelegate, NSApplicationDelegate> { … … 123 82 //NSImageView *imageCell; 124 83 } 125 @property (strong) MenuBarCtrl *menuBarCtrl;126 @property (strong) NSUserDefaults *userPreferences;127 84 @property BOOL enableLogging; 128 85 @property BOOL enableVerboseLogging; 129 @property ExtractMetaInfo *metaInfo; 86 @property (assign) NSUserDefaults *userPreferences; 87 @property (assign) ExtractMetaInfo *metaInfo; 130 88 @property (copy) NSImage *contentImage NS_AVAILABLE(10_9, NA); 131 - (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion; 132 - (void)startupI2PRouter; 133 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification; 134 - (void)applicationWillTerminate:(NSNotification *)aNotification; 135 - (void)setApplicationDefaultPreferences; 136 - (void)userChooseJavaHome; 137 - (AppDelegate *)initWithArgc:(int)argc argv:(const char **)argv; 138 - (NSString *)userSelectJavaHome:(JvmListPtr)rawJvmList; 139 - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center 89 90 - (void) extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion; 91 - (void) awakeFromNib; 92 - (void) startupI2PRouter; 93 - (void) applicationDidFinishLaunching:(NSNotification *)aNotification; 94 - (void) applicationWillTerminate:(NSNotification *)aNotification; 95 - (void) setApplicationDefaultPreferences; 96 - (void) userChooseJavaHome; 97 - (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv; 98 #ifdef __cplusplus 99 - (NSString *) userSelectJavaHome:(JvmListPtr)rawJvmList; 100 #endif 101 - (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center 140 102 shouldPresentNotification:(NSUserNotification *)notification; 141 103 @end 142 104 143 105 106 107 144 108 #endif -
launchers/macosx/JavaHelper.h
r7615b92 rf76874a 1 1 #pragma once 2 2 3 #include <functional> 4 #include <memory> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <sstream> 9 #include <list> 3 #include <memory.h> 4 #include <string.h> 10 5 #include <stdlib.h> 11 6 … … 18 13 #include <CoreFoundation/CFString.h> 19 14 20 #include "optional.hpp"21 #include "strutil.hpp"22 #include "subprocess.hpp"23 #include "neither/maybe.hpp"24 15 #include "RouterTask.h" 25 16 26 using namespace subprocess;27 using namespace neither;28 17 29 18 #define DEF_MIN_JVM_VER "1.7+" 19 20 #ifdef __cplusplus 21 22 #include "include/strutil.hpp" 23 24 #include <functional> 25 #include <memory> 26 #include <list> 27 30 28 31 29 class JvmVersion … … 54 52 } 55 53 }; 54 56 55 57 56 typedef std::shared_ptr<JvmVersion> JvmVersionPtr; … … 114 113 } 115 114 115 116 116 117 static void processJvmPlistEntries (const void* item, void* context) { 117 118 CFDictionaryRef dict = CFDictionaryCreateCopy(kCFAllocatorDefault, (CFDictionaryRef)item); … … 154 155 CFDataRef javaHomes = CFDataCreate(NULL, (const UInt8 *)javaHomeRes.buf.data(), strlen(javaHomeRes.buf.data())); 155 156 156 //CFErrorRef err;157 CFErrorRef err; 157 158 CFPropertyListRef propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, javaHomes, kCFPropertyListImmutable, NULL, NULL); 158 /*if (err)159 if (err) 159 160 { 160 161 NSError *error = (__bridge NSError *)err; 161 162 NSLog(@"Failed to read property list: %@", error); 162 163 [NSApp presentError: error]; 163 return nullptr;164 } */164 return; 165 } 165 166 166 167 … … 171 172 // Count number of entries in the property array list. 172 173 // This is used to set max CRange for CFArrayApplyFunction. 174 173 175 auto jCount = CFArrayGetCount((CFArrayRef)propertyList); 174 176 … … 176 178 //CFShow(propertyList); 177 179 } 180 181 #endif -
launchers/macosx/RouterTask.h
r7615b92 rf76874a 2 2 3 3 #include <dispatch/dispatch.h> 4 #include <functional> 5 #include <memory> 6 #include <string> 7 #include <vector> 4 #include <memory.h> 5 #include <string.h> 8 6 9 7 #include <Cocoa/Cocoa.h> 10 8 #import <AppKit/AppKit.h> 11 9 12 #include "optional.hpp" 13 #include "subprocess.hpp" 10 #ifdef __cplusplus 11 #include "include/subprocess.hpp" 12 13 using namespace subprocess; 14 class JavaRunner; 15 16 typedef std::function<void(void)> fp_t; 17 typedef std::function<void(JavaRunner *ptr)> fp_proc_t; 18 19 20 21 /** 22 * 23 * class JavaRunner 24 * 25 **/ 26 class JavaRunner 27 { 28 public: 29 // copy fn 30 JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& executingFn, const fp_t& cb); 31 ~JavaRunner() = default; 32 33 static const std::vector<NSString*> defaultStartupFlags; 34 static const std::vector<std::string> defaultFlagsForExtractorJob; 35 36 void requestRouterShutdown(); 37 38 std::future<int> execute(); 39 std::shared_ptr<subprocess::Popen> javaProcess; 40 std::string javaBinaryPath; 41 std::string javaRouterArgs; 42 std::string execLine; 43 std::string _i2pBaseDir; 44 private: 45 const fp_proc_t& executingFn; 46 const fp_t& exitCallbackFn; 47 }; 48 49 #endif 14 50 15 51 … … 42 78 43 79 44 using namespace subprocess;45 46 class JavaRunner;47 48 typedef std::function<void(void)> fp_t;49 typedef std::function<void(JavaRunner *ptr)> fp_proc_t;50 80 51 81 52 82 53 /**54 *55 * class JavaRunner56 *57 **/58 class JavaRunner59 {60 public:61 // copy fn62 JavaRunner(std::string& javaBin, std::string& arguments, std::string& i2pBaseDir, const fp_proc_t& executingFn, const fp_t& cb);63 ~JavaRunner() = default;64 65 static const std::vector<NSString*> defaultStartupFlags;66 static const std::vector<std::string> defaultFlagsForExtractorJob;67 68 void requestRouterShutdown();69 70 std::experimental::optional<std::future<int> > execute();71 std::shared_ptr<Popen> javaProcess;72 std::string javaBinaryPath;73 std::string javaRouterArgs;74 std::string execLine;75 std::string _i2pBaseDir;76 private:77 const fp_proc_t& executingFn;78 const fp_t& exitCallbackFn;79 };80 81 -
launchers/macosx/RouterTask.mm
r7615b92 rf76874a 5 5 #include <stdlib.h> 6 6 7 #include "optional.hpp" 8 #include "subprocess.hpp" 9 #include "PidWatcher.h" 7 #ifdef __cplusplus 8 #include "include/subprocess.hpp" 9 #import "I2PLauncher-Swift.h" 10 #include "AppDelegate.h" 11 #endif 12 #include "include/PidWatcher.h" 10 13 11 14 #import <AppKit/AppKit.h> 15 #import <Foundation/Foundation.h> 12 16 13 17 @implementation RTaskOptions … … 25 29 - (instancetype) initWithOptions : (RTaskOptions*) options 26 30 { 27 self.userRequestedRestart = NO; 28 self.isRouterRunning = NO; 29 self.input = [NSFileHandle fileHandleWithStandardInput]; 30 self.routerTask = [NSTask new]; 31 self.processPipe = [NSPipe new]; 32 [self.routerTask setLaunchPath:options.binPath]; 33 [self.routerTask setArguments:options.arguments]; 34 NSDictionary *envDict = @{ 35 @"I2PBASE": options.i2pBaseDir 36 }; 37 [self.routerTask setEnvironment: envDict]; 38 [self.routerTask setStandardOutput:self.processPipe]; 31 self.userRequestedRestart = NO; 32 self.isRouterRunning = NO; 33 self.input = [NSFileHandle fileHandleWithStandardInput]; 34 self.routerTask = [NSTask new]; 35 self.processPipe = [NSPipe new]; 36 [self.routerTask setLaunchPath:options.binPath]; 37 [self.routerTask setArguments:options.arguments]; 38 NSDictionary *envDict = @{ 39 @"I2PBASE": options.i2pBaseDir 40 }; 41 [self.routerTask setEnvironment: envDict]; 42 NSLog(@"Using environment variables: %@", envDict); 43 [self.routerTask setStandardOutput:self.processPipe]; 39 44 [self.routerTask setStandardError:self.processPipe]; 40 45 … … 48 53 49 54 [self.routerTask setTerminationHandler:^(NSTask* task) { 50 NSLog(@"termHandler triggered!"); 51 NSBundle *launcherBundle = [NSBundle mainBundle]; 52 auto iconImage = [launcherBundle pathForResource:@"ItoopieTransparent" ofType:@"png"]; 53 sendUserNotification(APP_IDSTR, @"I2P Router has stopped", [NSImage imageNamed:iconImage]); 54 // Cleanup 55 self.isRouterRunning = NO; 55 NSLog(@"termHandler triggered!"); 56 auto swiftRouterStatus = [[RouterProcessStatus alloc] init]; 57 [swiftRouterStatus setRouterStatus: true]; 58 NSBundle *launcherBundle = [NSBundle mainBundle]; 59 auto iconImage = [launcherBundle pathForResource:@"AppIcon" ofType:@"png"]; 60 sendUserNotification(APP_IDSTR, @"I2P Router has stopped"); 61 // Cleanup 62 self.isRouterRunning = NO; 56 63 }]; 57 64 /* … … 106 113 @end 107 114 115 #ifdef __cplusplus 108 116 109 110 111 using namespace subprocess;112 117 113 118 const std::vector<NSString*> JavaRunner::defaultStartupFlags { … … 145 150 } 146 151 147 std:: experimental::optional<std::future<int>> JavaRunner::execute()152 std::future<int> JavaRunner::execute() 148 153 { 149 154 try { … … 161 166 } catch (std::exception* ex) { 162 167 printf("ERROR: %s\n", ex->what()); 163 return std:: experimental::nullopt;168 return std::async(std::launch::async, []{ return 1; }); 164 169 } 165 170 } 171 172 #endif -
launchers/macosx/include/PidWatcher.h
r7615b92 rf76874a 5 5 #include <sys/event.h> 6 6 7 #include "neither/either.hpp"8 #include "AppDelegate.h"9 7 10 8 using callbackType = void (CFFileDescriptorRef, CFOptionFlags, void *); … … 17 15 // take action on death of process here 18 16 NSLog(@"process with pid '%u' died\n", (unsigned int)kev.ident); 19 sendUserNotification(APP_IDSTR, @"The I2P router has stopped.");17 //sendUserNotification(APP_IDSTR, @"The I2P router has stopped."); 20 18 CFFileDescriptorInvalidate(fdref); 21 19 CFRelease(fdref); // the CFFileDescriptorRef is no longer of any use in this example -
launchers/macosx/include/portcheck.h
r7615b92 rf76874a 10 10 typedef struct sockaddr *sad; /* A necesary dummy typedef */ 11 11 12 13 int port_check(int portNum=7657) 12 int port_check(int portNum) 14 13 { 15 int sock; /* Socket that will be bind */ 16 struct sockaddr_in sin; /* Address Structure */ 17 18 /* Create the socket */ 19 /* PF_INET is the option for make a TCP socket. 20 You can try "man socket" for more info */ 21 sock = socket( PF_INET, SOCK_STREAM, 0 ); 22 23 /* The socket creation failed */ 24 if ( 0 > sock ) { 25 perror( "socket" ); 26 return ( -1 ); 14 int sock; /* Socket that will be bind */ 15 struct sockaddr_in sin; /* Address Structure */ 16 17 /* Create the socket */ 18 /* PF_INET is the option for make a TCP socket. 19 You can try "man socket" for more info */ 20 sock = socket( PF_INET, SOCK_STREAM, 0 ); 21 22 /* The socket creation failed */ 23 if ( 0 > sock ) { 24 perror( "socket" ); 25 return ( -1 ); 26 } 27 28 /* Address */ 29 sin.sin_family = AF_INET; 30 sin.sin_port = htons( portNum ); /* htons() convert the number 31 to big endian */ 32 sin.sin_addr.s_addr = INADDR_ANY; 33 34 /* We bind the socket to the port PORT to check if 35 the port is in use */ 36 if ( 0 > bind( sock, (sad)&sin, sizeof( sin ) ) ) { 37 /* Bind failed, now we can check if the address is 38 in use */ 39 40 if ( EADDRINUSE == errno ) { 41 /* We put the code necesary to manage this case */ 42 printf( "The TCP port %d is in use.\n", portNum ); 43 } 44 45 else 46 /* If the error were other than EADDRINUSE, we print it */ 47 perror( "bind" ); 48 49 return 1; 50 } 51 52 /* If we arrive to this point, the port weren't in use and 53 we have it attached to our program. We can close 54 the socket or use it */ 55 close( sock ); /* Close the socket */ 56 57 return 0; 27 58 } 28 59 29 /* Address */30 sin.sin_family = AF_INET;31 sin.sin_port = htons( portNum ); /* htons() convert the number32 to big endian */33 sin.sin_addr.s_addr = INADDR_ANY;34 60 35 /* We bind the socket to the port PORT to check if36 the port is in use */37 if ( 0 > bind( sock, (sad)&sin, sizeof( sin ) ) ) {38 /* Bind failed, now we can check if the address is39 in use */40 41 if ( EADDRINUSE == errno ) {42 /* We put the code necesary to manage this case */43 printf( "The TCP port %d is in use.\n", portNum );44 }45 46 else47 /* If the error were other than EADDRINUSE, we print it */48 perror( "bind" );49 50 return 1;51 }52 53 /* If we arrive to this point, the port weren't in use and54 we have it attached to our program. We can close55 the socket or use it */56 close( sock ); /* Close the socket */57 58 return 0;59 } -
launchers/macosx/include/strutil.hpp
r7615b92 rf76874a 9 9 #include <cctype> 10 10 #include <locale> 11 #include "optional.h pp"11 #include "optional.h" 12 12 13 13 #include <CoreFoundation/CoreFoundation.h> -
launchers/macosx/main.mm
r7615b92 rf76874a 12 12 #import <Foundation/Foundation.h> 13 13 14 14 15 #include <CoreFoundation/CoreFoundation.h> 15 16 #include <CoreFoundation/CFStream.h> … … 25 26 #import <AppKit/NSApplication.h> 26 27 28 #import "I2PLauncher-Swift.h" 29 27 30 #include "AppDelegate.h" 28 #include "StatusItemButton.h"29 31 #include "RouterTask.h" 30 32 #include "JavaHelper.h" 31 #include "fn.h" 32 #include "optional.hpp" 33 #include "portcheck.h" 33 #include "include/fn.h" 34 #include "include/portcheck.h" 34 35 35 36 #define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]); 36 37 JvmListSharedPtr gRawJvmList = nullptr;38 39 40 @interface MenuBarCtrl () <StatusItemButtonDelegate, NSMenuDelegate>41 @end42 37 43 38 @interface AppDelegate () <NSUserNotificationCenterDelegate, NSApplicationDelegate> 44 39 @end 45 40 46 std::vector<std::string> buildClassPath(std::string basePath) 47 { 48 return globVector(basePath+std::string("/lib/*.jar")); 49 } 50 41 #ifdef __cplusplus 42 #import "SBridge.h" 43 JvmListSharedPtr gRawJvmList = nullptr; 44 #endif 45 46 47 @interface AppDelegate () <NSUserNotificationCenterDelegate, NSApplicationDelegate> 48 @end 49 50 #ifdef __cplusplus 51 51 maybeAnRouterRunner getGlobalRouterObject() 52 52 { 53 53 std::lock_guard<std::mutex> lock(globalRouterStatusMutex); 54 return globalRouterStatus; 54 return globalRouterStatus; // Remember this might be nullptr now. 55 55 } 56 56 … … 58 58 { 59 59 std::lock_guard<std::mutex> lock(globalRouterStatusMutex); 60 globalRouterStatus .emplace(newRouter);60 globalRouterStatus = newRouter; 61 61 } 62 62 … … 78 78 } 79 79 80 std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir) { 81 @try { 82 RTaskOptions* options = [RTaskOptions alloc]; 83 options.binPath = javaBin; 84 options.arguments = arguments; 85 options.i2pBaseDir = i2pBaseDir; 86 auto instance = [[[I2PRouterTask alloc] initWithOptions: options] autorelease]; 87 setGlobalRouterObject(instance); 88 //NSThread *thr = [[NSThread alloc] initWithTarget:instance selector:@selector(execute) object:nil]; 89 [instance execute]; 90 sendUserNotification(APP_IDSTR, @"The I2P router is starting up."); 91 auto pid = [instance getPID]; 92 return std::async(std::launch::async, [&pid]{ 93 return pid; 94 }); 95 } 96 @catch (NSException *e) 97 { 98 auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]]; 99 NSLog(@"%@", errStr); 100 sendUserNotification(APP_IDSTR, errStr); 101 return std::async(std::launch::async, [&]{ 102 return 0; 103 }); 104 } 105 } 106 107 void openUrl(NSString* url) 108 { 109 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: url]]; 110 } 111 112 @implementation I2PStatusMenu 113 114 - (BOOL)validateMenuItem:(NSMenuItem *)item 115 { 116 NSLog(@"item is: %@",item); 117 return YES; 118 } 119 80 #endif 81 82 83 @implementation ExtractMetaInfo : NSObject 120 84 @end 121 85 122 @implementation MenuBarCtrl123 124 - (void) statusItemButtonLeftClick: (StatusItemButton *) button125 {126 CFShow(CFSTR("Left button clicked!"));127 NSEvent *event = [NSApp currentEvent];128 }129 130 - (void) statusItemButtonRightClick: (StatusItemButton *) button131 {132 CFShow(CFSTR("Right button clicked!"));133 NSEvent *event = [NSApp currentEvent];134 [self.statusItem popUpStatusItemMenu: self.menu];135 }136 137 - (void)statusBarImageBtnClicked138 {139 [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(btnPressedAction) userInfo:nil repeats:NO];140 }141 142 - (void)btnPressedAction:(id)sender143 {144 NSLog(@"Button presseeeeeeed");145 NSEvent *event = [NSApp currentEvent];146 }147 148 - (void) openRouterConsoleBtnHandler: (NSMenuItem *) menuItem149 {150 NSLog(@"Clicked openRouterConsoleBtnHandler");151 openUrl(@"http://127.0.0.1:7657");152 }153 154 - (void) startJavaRouterBtnHandler: (NSMenuItem *) menuItem155 {156 NSLog(@"Clicked startJavaRouterBtnHandler");157 AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];158 [appDelegate startupI2PRouter];159 }160 161 - (void) restartJavaRouterBtnHandler: (NSMenuItem *) menuItem162 {163 NSLog(@"Clicked restartJavaRouterBtnHandler");164 if (getGlobalRouterObject().has_value())165 {166 sendUserNotification(APP_IDSTR, @"Requesting the I2P router to restart.");167 [getGlobalRouterObject().value() requestRestart];168 NSLog(@"Requested restart");169 }170 }171 172 - (void) stopJavaRouterBtnHandler: (NSMenuItem *) menuItem173 {174 NSLog(@"Clicked stopJavaRouterBtnHandler");175 if (getGlobalRouterObject().has_value())176 {177 sendUserNotification(APP_IDSTR, @"Requesting the I2P router to shutdown.");178 [getGlobalRouterObject().value() requestShutdown];179 NSLog(@"Requested shutdown");180 }181 }182 183 - (void) quitWrapperBtnHandler: (NSMenuItem *) menuItem184 {185 NSLog(@"quitWrapper event handler called!");186 [[NSApplication sharedApplication] terminate:self];187 }188 189 - (MenuBarCtrl *) init190 {191 self.menu = [self createStatusBarMenu];192 self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];193 194 self.image = [NSImage imageNamed:@"ItoopieTransparent.png"];195 [self.image setTemplate:YES];196 self.statusItem.image = self.image;197 198 self.statusItem.highlightMode = NO;199 self.statusItem.toolTip = @"I2P Router Controller";200 201 self.statusBarButton = [[StatusItemButton alloc] initWithImage:self.image];202 self.statusBarButton.menu = self.menu;203 204 // Selecting action205 //[self.statusBarButton setAction:@selector(statusBarImageBtnClicked)];206 //[self.statusBarButton setTarget:self];207 self.statusBarButton.delegate = self;208 [self.statusItem popUpStatusItemMenu: self.menu];209 210 [self.statusItem setView: self.statusBarButton];211 NSLog(@"Initialized statusbar and such");212 return self;213 }214 215 -(void) dealloc216 {217 [self.image release];218 [self.menu release];219 }220 221 - (I2PStatusMenu *)createStatusBarMenu222 {223 I2PStatusMenu *menu = [[I2PStatusMenu alloc] init];224 [menu setAutoenablesItems:NO];225 226 NSMenuItem *openConsoleI2Pbtn =227 [[NSMenuItem alloc] initWithTitle:@"Open Console"228 action:@selector(openRouterConsoleBtnHandler:)229 keyEquivalent:@""];230 [openConsoleI2Pbtn setTarget:self];231 [openConsoleI2Pbtn setEnabled:YES];232 233 NSMenuItem *startI2Pbtn =234 [[NSMenuItem alloc] initWithTitle:@"Start I2P"235 action:@selector(startJavaRouterBtnHandler:)236 keyEquivalent:@""];237 [startI2Pbtn setTarget:self];238 if ([self.userPreferences boolForKey:@"autoStartRouter"])239 {240 [startI2Pbtn setEnabled:NO];241 } else {242 [startI2Pbtn setEnabled:YES];243 }244 245 NSMenuItem *restartI2Pbtn =246 [[NSMenuItem alloc] initWithTitle:@"Restart I2P"247 action:@selector(restartJavaRouterBtnHandler:)248 keyEquivalent:@""];249 [restartI2Pbtn setTarget:self];250 [restartI2Pbtn setEnabled:YES];251 252 NSMenuItem *stopI2Pbtn =253 [[NSMenuItem alloc] initWithTitle:@"Stop I2P"254 action:@selector(stopJavaRouterBtnHandler:)255 keyEquivalent:@""];256 [stopI2Pbtn setTarget:self];257 [stopI2Pbtn setEnabled:YES];258 259 NSMenuItem *quitWrapperBtn =260 [[NSMenuItem alloc] initWithTitle:@"Quit I2P Wrapper"261 action:@selector(quitWrapperBtnHandler:)262 keyEquivalent:@""];263 [quitWrapperBtn setTarget:self];264 [quitWrapperBtn setEnabled:YES];265 266 267 [menu addItem:openConsoleI2Pbtn];268 [menu addItem:startI2Pbtn];269 [menu addItem:stopI2Pbtn];270 [menu addItem:restartI2Pbtn];271 [menu addItem:quitWrapperBtn];272 return menu;273 }274 275 @end276 277 @implementation ExtractMetaInfo278 @end279 280 86 @implementation AppDelegate 87 88 - (void) awakeFromNib { 89 } 90 91 #ifdef __cplusplus 281 92 282 93 - (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion … … 285 96 NSParameterAssert(self.metaInfo.i2pBase); 286 97 NSError *error = NULL; 287 BOOL success ;98 BOOL success = NO; 288 99 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 289 100 … … 313 124 cli.push_back("net.i2p.launchers.BaseExtractor"); 314 125 315 //auto charCli = map(cli, [](std::string str){ return str.c_str(); });126 auto charCli = map(cli, [](std::string str){ return str.c_str(); }); 316 127 std::string execStr = [self.metaInfo.javaBinary UTF8String]; 317 128 for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; }); … … 338 149 // All done. Assume success and error are already set. 339 150 dispatch_async(dispatch_get_main_queue(), ^{ 340 sendUserNotification(APP_IDSTR, @"Extraction complete!", self.contentImage);151 //sendUserNotification(APP_IDSTR, @"Extraction complete!", self.contentImage); 341 152 if (completion) { 342 153 completion(success, error); … … 346 157 } 347 158 348 - (void)startupI2PRouter 349 { 350 std::string basePath([self.metaInfo.i2pBase UTF8String]); 351 352 // Get paths 353 NSBundle *launcherBundle = [NSBundle mainBundle]; 354 auto jarList = buildClassPath(basePath); 355 std::string classpathStrHead = "-classpath"; 356 std::string classpathStr = ""; 357 classpathStr += [[launcherBundle pathForResource:@"launcher" ofType:@"jar"] UTF8String]; 358 std::string prefix(basePath); 359 prefix += "/lib/"; 360 for_each(jarList, [&classpathStr](std::string str){ classpathStr += std::string(":") + str; }); 361 //if (self.enableVerboseLogging) NSLog(@"Classpath: %@\n",[NSString stringWithUTF8String:classpathStr.c_str()]); 362 363 try { 364 auto argList = JavaRunner::defaultStartupFlags; 365 366 std::string baseDirArg("-Di2p.dir.base="); 367 baseDirArg += basePath; 368 std::string javaLibArg("-Djava.library.path="); 369 javaLibArg += basePath; 370 // TODO: pass this to JVM 371 auto java_opts = getenv("JAVA_OPTS"); 372 373 argList.push_back([NSString stringWithUTF8String:baseDirArg.c_str()]); 374 argList.push_back([NSString stringWithUTF8String:javaLibArg.c_str()]); 375 argList.push_back([NSString stringWithUTF8String:classpathStrHead.c_str()]); 376 argList.push_back([NSString stringWithUTF8String:classpathStr.c_str()]); 377 argList.push_back(@"net.i2p.router.Router"); 378 auto javaBin = std::string([self.metaInfo.javaBinary UTF8String]); 379 380 381 sendUserNotification(APP_IDSTR, @"I2P Router is starting up!", self.contentImage); 382 auto nsJavaBin = self.metaInfo.javaBinary; 383 auto nsBasePath = self.metaInfo.i2pBase; 384 NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()]; 385 startupRouter(nsJavaBin, arrArguments, nsBasePath); 386 //if (self.enableVerboseLogging) NSLog(@"Defaults: %@", [pref dictionaryRepresentation]); 387 } catch (std::exception &err) { 388 auto errMsg = [NSString stringWithUTF8String:err.what()]; 389 NSLog(@"Exception: %@", errMsg); 390 sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg], self.contentImage); 391 } 392 } 159 #endif 393 160 394 161 - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center 395 162 shouldPresentNotification:(NSUserNotification *)notification { 396 163 return YES; 164 } 165 166 167 #ifdef __cplusplus 168 169 inline std::string getDefaultBaseDir() 170 { 171 // Figure out base directory 172 const char* pathFromHome = "/Users/%s/Library/I2P"; 173 auto username = getenv("USER"); 174 char buffer[strlen(pathFromHome)+strlen(username)]; 175 sprintf(buffer, pathFromHome, username); 176 std::string i2pBaseDir(buffer); 177 return i2pBaseDir; 397 178 } 398 179 … … 429 210 } 430 211 212 #endif 213 431 214 - (void)setApplicationDefaultPreferences { 432 215 auto defaultJVMHome = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER}); … … 434 217 trim(tmpStdStr); 435 218 auto cfDefaultHome = CFStringCreateWithCString(NULL, const_cast<const char *>(tmpStdStr.c_str()), kCFStringEncodingUTF8); 436 [self.userPreferences registerDefaults:@{219 /*[self.userPreferences registerDefaults:@{ 437 220 @"javaHome" : (NSString *)cfDefaultHome, 438 221 @"lastI2PVersion" : (NSString *)CFSTR(DEF_I2P_VERSION), 439 @"enableLogging": @ true,440 @"enableVerboseLogging": @ true,441 @"autoStartRouter": @ true,222 @"enableLogging": @YES, 223 @"enableVerboseLogging": @YES, 224 @"autoStartRouter": @YES, 442 225 @"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8) 443 }]; 226 }];*/ 444 227 if (self.enableVerboseLogging) NSLog(@"Default JVM home preference set to: %@", (NSString *)cfDefaultHome); 445 228 … … 457 240 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 458 241 // Init application here 242 243 SwiftMainDelegate *swiftRuntime = [[SwiftMainDelegate alloc] init]; 244 swiftRuntime.applicationDidFinishLaunching; 245 459 246 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self]; 460 247 // Start with user preferences … … 465 252 466 253 467 // Get paths 468 NSBundle *launcherBundle = [NSBundle mainBundle]; 469 auto iconImage = [launcherBundle pathForResource:@"ItoopieTransparent" ofType:@"png"]; 470 self.contentImage = [NSImage imageNamed:iconImage]; 471 254 // Get paths 255 NSBundle *launcherBundle = [NSBundle mainBundle]; 256 //auto iconImage = [launcherBundle pathForResource:@"ItoopieTransparent" ofType:@"png"]; 257 258 // This is the only GUI the user experience on a regular basis. 259 //self.menuBarCtrl = [[MenuBarCtrl alloc] init]; 260 261 #ifdef __cplusplus 472 262 gRawJvmList = std::make_shared<std::list<JvmVersionPtr> >(std::list<JvmVersionPtr>()); 263 #endif 473 264 // In case we are unbundled, make us a proper UI application 474 265 [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; 475 266 [NSApp activateIgnoringOtherApps:YES]; 267 268 // TODO: Also check for new installations from time to time. 269 270 #ifdef __cplusplus 476 271 auto javaHomePref = [self.userPreferences stringForKey:@"javaHome"]; 477 if (self.enableVerboseLogging) NSLog(@"Java home from preferences: %@", javaHomePref); 478 479 // This is the only GUI the user experience on a regular basis. 480 self.menuBarCtrl = [[MenuBarCtrl alloc] init]; 481 482 NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; 483 if (self.enableVerboseLogging) NSLog(@"Appdomain is: %@", appDomain); 272 if (self.enableVerboseLogging) 273 { 274 NSLog(@"Java home from preferences: %@", javaHomePref); 275 } 276 277 if (self.enableVerboseLogging) 278 { 279 NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; 280 NSLog(@"Appdomain is: %@", appDomain); 281 } 484 282 485 283 NSLog(@"We should have started the statusbar object by now..."); 284 RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init]; 486 285 487 286 std::string i2pBaseDir(getDefaultBaseDir()); 488 //if (self.enableVerboseLogging) printf("Home directory is: %s\n", buffer); 489 490 491 //[statusBarButton setAction:@selector(itemClicked:)]; 492 //dispatch_async(dispatch_get_main_queue(), ^{ 493 //}); 287 494 288 auto pref = self.userPreferences; 495 self.menuBarCtrl.userPreferences = self.userPreferences; 496 self.menuBarCtrl.enableLogging = self.enableLogging; 497 self.menuBarCtrl.enableVerboseLogging = self.enableVerboseLogging; 498 499 500 501 if (port_check() != 0) 289 290 bool shouldAutoStartRouter = false; 291 292 if (port_check(7657) != 0) 502 293 { 503 294 NSLog(@"Seems i2p is already running - I will not start the router (port 7657 is in use..)"); 295 sendUserNotification(@"Found already running router", @"TCP port 7657 seem to be used by another i2p instance."); 296 297 [routerStatus setRouterStatus: true]; 298 [routerStatus setRouterRanByUs: false]; 504 299 return; 300 } else { 301 shouldAutoStartRouter = true; 505 302 } 506 303 … … 514 311 if (self.enableVerboseLogging) NSLog(@"Javahome: %@", val); 515 312 auto javaHome = std::string([val UTF8String]); 516 trim(javaHome); // Trim to remove endline313 //trim(javaHome); // Trim to remove endline 517 314 auto javaBin = std::string(javaHome); 518 315 javaBin += "/bin/java"; // Append java binary to path. … … 521 318 522 319 320 //NSBundle *launcherBundle = [NSBundle mainBundle]; 321 523 322 self.metaInfo = [[ExtractMetaInfo alloc] init]; 524 self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()];323 //self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()]; 525 324 self.metaInfo.javaBinary = [NSString stringWithUTF8String:getJavaBin().c_str()]; 526 325 self.metaInfo.jarFile = [launcherBundle pathForResource:@"launcher" ofType:@"jar"]; … … 528 327 529 328 std::string basearg("-Di2p.dir.base="); 530 basearg += i2pBaseDir;329 //basearg += i2pBaseDir; 531 330 532 331 std::string jarfile("-cp "); … … 540 339 541 340 [self extractI2PBaseDir:^(BOOL success, NSError *error) { 542 //__typeof__(self) strongSelf = weakSelf;543 //if (strongSelf == nil) return;544 341 sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!"); 342 NSLog(@"Done extracting I2P"); 343 if (shouldAutoStartRouter) [self startupI2PRouter]; 545 344 }]; 546 345 547 346 } else { 548 549 550 } 551 347 if (self.enableVerboseLogging) NSLog(@"I2P directory found!"); 348 if (shouldAutoStartRouter) [self startupI2PRouter]; 349 } 350 #endif 552 351 } 553 352 … … 580 379 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 581 380 582 583 584 381 app.delegate = [[AppDelegate alloc] initWithArgc:argc argv:argv]; 585 382 [NSBundle loadNibNamed:@"I2Launcher" owner:NSApp]; … … 587 384 [NSApp run]; 588 385 // Handle any errors 589 //CFRelease(javaHomes);590 //CFRelease(err);591 386 [pool drain]; 592 387 return 0;
Note: See TracChangeset
for help on using the changeset viewer.