source: launchers/macosx/SBridge.mm @ 51cbd8e

Last change on this file since 51cbd8e was 410f9df, checked in by meeh <meeh@…>, 23 months ago

Mac OSX Launcher: The launcher will now write the pid of the router to a file like the old wrapper did.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1//
2//  SBridge.m
3//  I2PLauncher
4//
5//  Created by Mikal Villa on 18/09/2018.
6//  Copyright © 2018 The I2P Project. All rights reserved.
7//
8
9#import "SBridge.h"
10
11#ifdef __cplusplus
12#include <functional>
13#include <memory>
14#include <glob.h>
15#include <string>
16#include <list>
17#include <stdlib.h>
18#include <future>
19#include <vector>
20
21#import <AppKit/AppKit.h>
22#import "I2PLauncher-Swift.h"
23#include "LoggerWorker.hpp"
24#include "Logger.h"
25#include "logger_c.h"
26
27#include "AppDelegate.h"
28#include "include/fn.h"
29
30
31
32std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir, RouterProcessStatus* routerStatus) {
33  @try {
34    IIProcessInfo* processInfoObj = [[IIProcessInfo alloc] init];
35    [processInfoObj obtainFreshProcessList];
36    auto anyRouterLookingProcs = [processInfoObj findProcessWithStringInNameOrArguments:@"i2p.jar"];
37    if (anyRouterLookingProcs) {
38      auto errMessage = @"Seems i2p is already running - I've detected another process with i2p.jar in it's arguments.";
39      MLog(4, @"%@", errMessage);
40      sendUserNotification(APP_IDSTR, errMessage);
41      [routerStatus triggerEventWithEn:@"router_already_running" details:@"won't start - another router is running"];
42      return std::async(std::launch::async, []{
43        return -1;
44      });
45    } else {
46      RTaskOptions* options = [RTaskOptions alloc];
47      options.binPath = javaBin;
48      options.arguments = arguments;
49      options.i2pBaseDir = i2pBaseDir;
50      auto instance = [[I2PRouterTask alloc] initWithOptions: options];
51     
52      [[SBridge sharedInstance] setCurrentRouterInstance:instance];
53      [instance execute];
54      sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
55      auto pid = [instance getPID];
56      MLog(2, @"Got pid: %d", pid);
57      if (routerStatus != nil) {
58        // TODO: Merge events router_start and router_pid ?
59        [routerStatus triggerEventWithEn:@"router_start" details:@"normal start"];
60        [routerStatus triggerEventWithEn:@"router_pid" details:[NSString stringWithFormat:@"%d", pid]];
61      }
62      NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject];
63      auto pidFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/i2p/router.pid", applicationSupportDirectory]];
64      NSError *err;
65     
66      if (![[NSString stringWithFormat:@"%d", pid] writeToURL:pidFile atomically:YES encoding:NSUTF8StringEncoding error:&err]) {
67        MLog(4, @"Error; %@", err);
68      } else {
69        MLog(3, @"Wrote pid file to %@", pidFile);
70      }
71     
72      return std::async(std::launch::async, [&pid]{
73        return pid;
74      });
75    }
76  }
77  @catch (NSException *e)
78  {
79    auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]];
80    MLog(4, @"%@", errStr);
81    sendUserNotification(APP_IDSTR, errStr);
82    [[SBridge sharedInstance] setCurrentRouterInstance:nil];
83   
84    if (routerStatus != nil) {
85      [routerStatus triggerEventWithEn:@"router_exception" details:errStr];
86    }
87   
88    return std::async(std::launch::async, [&]{
89      return 0;
90    });
91  }
92}
93
94
95
96@implementation SBridge
97
98// this makes it a singleton
99+ (instancetype)sharedInstance {
100  static SBridge *sharedInstance = nil;
101  static dispatch_once_t onceToken;
102 
103  dispatch_once(&onceToken, ^{
104    sharedInstance = [[SBridge alloc] init];
105  });
106  return sharedInstance;
107}
108
109- (void) openUrl:(NSString*)url
110{
111  osx::openUrl(url);
112}
113
114- (NSString*) buildClassPath:(NSString*)i2pPath
115{
116  const char * basePath = [i2pPath UTF8String];
117  auto jarList = buildClassPathForObjC(basePath);
118  const char * classpath = jarList.c_str();
119  MLog(0, @"Classpath from ObjC = %s", classpath);
120  return [[NSString alloc] initWithUTF8String:classpath];
121}
122
123
124
125- (void)startupI2PRouter:(NSString*)i2pRootPath javaBinPath:(NSString*)javaBinPath
126{
127  std::string basePath([i2pRootPath UTF8String]);
128 
129  auto classPathStr = buildClassPathForObjC(basePath);
130 
131  RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init];
132 
133  NSString *confDir = [NSString stringWithFormat:@"%@/Library/Application\\ Support/i2p", NSHomeDirectory()];
134 
135  try {
136    std::vector<NSString*> argList = {
137      @"-Xmx512M",
138      @"-Xms128m",
139      @"-Djava.awt.headless=true",
140      [NSString stringWithFormat:@"-Dwrapper.logfile=%@/router.log", [NSString stringWithUTF8String:getDefaultLogDir().c_str()]],
141      @"-Dwrapper.logfile.loglevel=DEBUG",
142      [NSString stringWithFormat:@"-Dwrapper.java.pidfile=%@/router.pid", confDir],
143      @"-Dwrapper.console.loglevel=DEBUG"
144    };
145   
146    std::string baseDirArg("-Di2p.dir.base=");
147    baseDirArg += basePath;
148    std::string javaLibArg("-Djava.library.path=");
149    javaLibArg += basePath;
150    // TODO: pass this to JVM
151    //auto java_opts = getenv("JAVA_OPTS");
152   
153    std::string cpString = std::string("-cp");
154   
155    argList.push_back([NSString stringWithUTF8String:baseDirArg.c_str()]);
156    argList.push_back([NSString stringWithUTF8String:javaLibArg.c_str()]);
157    argList.push_back([NSString stringWithUTF8String:cpString.c_str()]);
158    argList.push_back([NSString stringWithUTF8String:classPathStr.c_str()]);
159    argList.push_back(@"net.i2p.router.Router");
160    auto javaBin = std::string([javaBinPath UTF8String]);
161   
162   
163    sendUserNotification(APP_IDSTR, @"I2P Router is starting up!");
164    auto nsJavaBin = javaBinPath;
165    auto nsBasePath = i2pRootPath;
166    NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()];
167   
168    MLog(0, @"Trying to run command: %@", javaBinPath);
169    MLog(0, @"With I2P Base dir: %@", i2pRootPath);
170    MLog(0, @"And Arguments: %@", arrArguments);
171    startupRouter(nsJavaBin, arrArguments, nsBasePath, routerStatus);
172  } catch (std::exception &err) {
173    auto errMsg = [NSString stringWithUTF8String:err.what()];
174    MLog(4, @"Exception: %@", errMsg);
175    sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
176    [routerStatus setRouterStatus: false];
177    [routerStatus setRouterRanByUs: false];
178    [routerStatus triggerEventWithEn:@"router_exception" details:[NSString stringWithFormat:@"Error: %@", errMsg]];
179  }
180}
181@end
182
183
184#endif
Note: See TracBrowser for help on using the repository browser.