Code changes:

* Port check to see if i2p is already running.
* All buttons in the menu should work now.
* Rewrote some C++ to Objective-C, which fits better with the integration.
* Misc cleanup.
* Made the launch of router repeatable.
This commit is contained in:
meeh
2018-07-24 16:26:40 +00:00
parent 2ee1a212c8
commit f9fbc76dd0
8 changed files with 214 additions and 199 deletions

View File

@@ -7,9 +7,9 @@
#include <Cocoa/Cocoa.h>
#include "RouterTask.h"
#include "StatusItemButton.h"
#include "JavaHelper.h"
#include "RouterTask.h"
#include "neither/maybe.hpp"
#include "optional.hpp"
#include "subprocess.hpp"
@@ -26,24 +26,33 @@
using namespace neither;
using maybeAnRouterRunner = std::experimental::optional<RouterTask*>;
@class ExtractMetaInfo;
using maybeAnRouterRunner = std::experimental::optional<I2PRouterTask*>;
std::vector<std::string> 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(RouterTask* newRouter);
void setGlobalRouterObject(I2PRouterTask* newRouter);
bool getGlobalRouterIsRunning();
void setGlobalRouterIsRunning(bool running);
@class ExtractMetaInfo;
@interface ExtractMetaInfo : NSObject
@property (strong) NSString* i2pBase;
@property (strong) NSString* javaBinary;
@property (strong) NSString* zipFile;
@property (strong) NSString* jarFile;
@property (copy) NSString* i2pBase;
@property (copy) NSString* javaBinary;
@property (copy) NSString* zipFile;
@property (copy) NSString* jarFile;
@end
@class I2PStatusMenu;
@interface I2PStatusMenu : NSMenu
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
@end
inline void sendUserNotification(NSString* title, NSString* informativeText, NSImage* contentImage = NULL, bool makeSound = false) {
@@ -68,10 +77,21 @@ inline std::vector<std::string> globVector(const std::string& pattern){
return files;
}
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;
}
@interface MenuBarCtrl : NSObject <StatusItemButtonDelegate, NSMenuDelegate>
@property BOOL enableLogging;
@property BOOL enableVerboseLogging;
@property (strong) NSMenu *menu;
@property (strong) I2PStatusMenu *menu;
@property (strong) StatusItemButton* statusBarButton;
@property (strong) NSUserDefaults *userPreferences;
@property (strong, nonatomic) NSImage * image;
@@ -81,7 +101,7 @@ inline std::vector<std::string> globVector(const std::string& pattern){
- (void) statusItemButtonRightClick: (StatusItemButton *) button;
- (void) statusBarImageBtnClicked;
- (void) btnPressedAction:(id)sender;
- (void) menuWillOpen:(NSMenu *)menu;
- (void) menuWillOpen:(I2PStatusMenu *)menu;
- (void) openRouterConsoleBtnHandler: (NSMenuItem *) menuItem;
- (void) startJavaRouterBtnHandler: (NSMenuItem *) menuItem;
@@ -91,7 +111,7 @@ inline std::vector<std::string> globVector(const std::string& pattern){
// Methods
- (MenuBarCtrl *) init;
- (void) dealloc;
- (NSMenu *) createStatusBarMenu;
- (I2PStatusMenu *) createStatusBarMenu;
@end
@protocol MenuBarCtrlDelegate
@@ -106,9 +126,10 @@ inline std::vector<std::string> globVector(const std::string& pattern){
@property (strong) NSUserDefaults *userPreferences;
@property BOOL enableLogging;
@property BOOL enableVerboseLogging;
@property ExtractMetaInfo *metaInfo;
@property (copy) NSImage *contentImage NS_AVAILABLE(10_9, NA);
- (void)extractI2PBaseDir:(ExtractMetaInfo *)metaInfo completion:(void(^)(BOOL success, NSError *error))completion;
- (void)startupI2PRouter:(ExtractMetaInfo *)metaInfo;
- (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion;
- (void)startupI2PRouter;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void)applicationWillTerminate:(NSNotification *)aNotification;
- (void)setApplicationDefaultPreferences;
@@ -120,57 +141,4 @@ inline std::vector<std::string> globVector(const std::string& pattern){
@end
/*
@implementation CNSStatusBarCtrl
-(id)initWithSysTray:(I2PCtrlSysIcon *)sys
{
self = [super init];
if (self) {
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
menu = 0;
systray = sys;
imageCell = [[NSImageView alloc] initWithParent:self];
[item setView: imageCell];
[item setHidden: NO];
CFShow(CFSTR("CNSStatusBarCtrl::initWithSysTray executed"));
}
return self;
}
-(NSStatusItem*)item {
return item;
}
-(void)dealloc {
[[NSStatusBar systemStatusBar] removeStatusItem:item];
[[NSNotificationCenter defaultCenter] removeObserver:imageCell];
[imageCell release];
[item release];
[super dealloc];
}
@end
class CSystemTrayIcon
{
public:
CSystemTrayIcon(I2PCtrlSysIcon *sys)
{
item = [[CNSStatusBarCtrl alloc] initWithSysTray:sys];
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item];
const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
printf("menuHeight: %d\n", menuHeight);
[[[item item] view] setHidden: NO];
}
~CSystemTrayIcon()
{
[[[item item] view] setHidden: YES];
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
[item release];
}
CNSStatusBarCtrl *item;
};
*/
#endif

View File

@@ -11,7 +11,7 @@
<key>CFBundleGetInfoString</key>
<string>0.9.35-experimental</string>
<key>CFBundleIconFile</key>
<string>i2p</string>
<string>images/AppIcon.icns</string>
<key>CFBundleIdentifier</key>
<string>net.i2p.launcher</string>
<key>CFBundleInfoDictionaryVersion</key>

View File

@@ -3,33 +3,12 @@
#include <CoreFoundation/CoreFoundation.h>
#include <unistd.h>
#include <sys/event.h>
#include <functional>
#include "neither/either.hpp"
#include "AppDelegate.h"
using callbackType = void (CFFileDescriptorRef, CFOptionFlags, void *);
using HandleFunction = std::function<void(int)>;
/*
class CallbackWrapper
{
CallbackWrapper(HandleFunction func) : mCallback(func);
void operator(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) {
struct kevent kev;
int fd = CFFileDescriptorGetNativeDescriptor(fdref);
kevent(fd, NULL, 0, &kev, 1, NULL);
// take action on death of process here
NSLog(@"process with pid '%u' died\n", (unsigned int)kev.ident);
mCallback(0);
CFFileDescriptorInvalidate(fdref);
CFRelease(fdref);
}
private:
HandleFunction mCallback;
};
*/
static void noteProcDeath(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) {
struct kevent kev;

View File

@@ -14,22 +14,21 @@
@class RTaskOptions;
@interface RTaskOptions : NSObject
@property (strong) NSString* binPath;
@property (strong) NSArray<NSString *>* arguments;
@property (strong) NSString* i2pBaseDir;
@end
@class RouterTask;
@interface RouterTask : NSObject
@class I2PRouterTask;
@interface I2PRouterTask : NSObject
@property (strong) NSTask* routerTask;
@property (strong) NSUserDefaults *userPreferences;
@property (strong) NSFileHandle *readLogHandle;
@property (strong) NSMutableData *totalLogData;
@property (strong) NSPipe *processPipe;
@property (strong) NSFileHandle *input;
@property (atomic) BOOL isRouterRunning;
@property (atomic) BOOL userRequestedRestart;
- (instancetype) initWithOptions : (RTaskOptions*) options;
- (int) execute;
@@ -37,6 +36,7 @@
- (void) requestRestart;
- (BOOL) isRunning;
- (int) getPID;
- (void)routerStdoutData:(NSNotification *)notification;
@end
@@ -48,6 +48,8 @@ class JavaRunner;
typedef std::function<void(void)> fp_t;
typedef std::function<void(JavaRunner *ptr)> fp_proc_t;
/**
*
* class JavaRunner

View File

@@ -13,12 +13,19 @@
@implementation RTaskOptions
@end
@implementation RouterTask
@implementation I2PRouterTask
- (void)routerStdoutData:(NSNotification *)notification
{
NSLog(@"%@", [[NSString alloc] initWithData:[notification.object availableData] encoding:NSUTF8StringEncoding]);
[notification.object waitForDataInBackgroundAndNotify];
}
- (instancetype) initWithOptions : (RTaskOptions*) options
{
self.userRequestedRestart = FALSE;
self.userRequestedRestart = NO;
self.isRouterRunning = NO;
self.input = [NSFileHandle fileHandleWithStandardInput];
self.routerTask = [NSTask new];
self.processPipe = [NSPipe new];
@@ -30,8 +37,22 @@
[self.routerTask setEnvironment: envDict];
[self.routerTask setStandardOutput:self.processPipe];
[self.routerTask setStandardError:self.processPipe];
NSFileHandle *stdoutFileHandle = [self.processPipe fileHandleForReading];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(routerStdoutData:)
name:NSFileHandleDataAvailableNotification
object:stdoutFileHandle];
[stdoutFileHandle waitForDataInBackgroundAndNotify];
[self.routerTask setTerminationHandler:^(NSTask* task) {
NSLog(@"termHandler triggered!");
NSBundle *launcherBundle = [NSBundle mainBundle];
auto iconImage = [launcherBundle pathForResource:@"ItoopieTransparent" ofType:@"png"];
sendUserNotification(APP_IDSTR, @"I2P Router has stopped", [NSImage imageNamed:iconImage]);
// Cleanup
self.isRouterRunning = NO;
}];
/*
self.readLogHandle = [self.processPipe fileHandleForReading];
@@ -53,7 +74,8 @@
- (void) requestRestart
{
self.userRequestedRestart = TRUE;
self.userRequestedRestart = YES;
kill([self.routerTask processIdentifier], SIGHUP);
}
- (BOOL) isRunning
@@ -63,35 +85,17 @@
- (int) execute
{
//@try {
@try {
[self.routerTask launch];
watchPid([self.routerTask processIdentifier]);
[self.input waitForDataInBackgroundAndNotify];
[[self.processPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:[self.processPipe fileHandleForReading] queue:nil
usingBlock:^(NSNotification *note)
{
// Read from shell output
NSData *outData = [[self.processPipe fileHandleForReading] availableData];
NSString *outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
if ([outStr length] > 1) {
NSLog(@"output: %@", outStr);
}
// Continue waiting for shell output.
[[self.processPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
}];
//[self.routerTask waitUntilExit];
//NSThread *thr = [[NSThread alloc] initWithTarget:self.routerTask selector:@selector(launch) object:nil];
//[self.routerTask waitUntilExit];
self.isRouterRunning = YES;
return 1;
/*}
}
@catch (NSException *e)
{
NSLog(@"Expection occurred %@", [e reason]);
return 0;
}*/
}
}
- (int) getPID

View File

@@ -2,6 +2,12 @@
#import <Cocoa/Cocoa.h>
/**
*
* This is a class representing the "image" in the systray.
*
*
* **/
@class StatusItemButton;
@protocol StatusItemButtonDelegate <NSObject>

View File

@@ -30,6 +30,7 @@
#include "JavaHelper.h"
#include "fn.h"
#include "optional.hpp"
#include "portcheck.h"
#define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
@@ -42,6 +43,10 @@ JvmListSharedPtr gRawJvmList = nullptr;
@interface AppDelegate () <NSUserNotificationCenterDelegate, NSApplicationDelegate>
@end
std::vector<std::string> buildClassPath(std::string basePath)
{
return globVector(basePath+std::string("/lib/*.jar"));
}
maybeAnRouterRunner getGlobalRouterObject()
{
@@ -49,44 +54,36 @@ maybeAnRouterRunner getGlobalRouterObject()
return globalRouterStatus;
}
void setGlobalRouterObject(RouterTask* newRouter)
void setGlobalRouterObject(I2PRouterTask* newRouter)
{
std::lock_guard<std::mutex> lock(globalRouterStatusMutex);
globalRouterStatus.emplace(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);
}
std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir) {
/*
NSLog(@"Arguments: %@", [NSString stringWithUTF8String:arguments.c_str()]);
auto launchLambda = [](JavaRunner *javaRun) {
javaRun->javaProcess->start_process();
auto pid = javaRun->javaProcess->pid();
std::cout << "I2P Router process id = " << pid << std::endl;
// Blocking
javaRun->javaProcess->wait();
};
auto callbackAfterExit = [](){
printf("Callback after exit\n");
};
NSLog(@"Still fine!");
setGlobalRouterObject(new JavaRunner{ javaBin, arguments, i2pBaseDir, std::move(launchLambda), std::move(callbackAfterExit) });
NSLog(@"Still fine!");
return std::async(std::launch::async, [&]{
getGlobalRouterObject().value()->execute();
return 0;
});
*/
//CFShow(arguments);
@try {
RTaskOptions* options = [RTaskOptions alloc];
options.binPath = javaBin;
options.arguments = arguments;
options.i2pBaseDir = i2pBaseDir;
auto instance = [[[RouterTask alloc] initWithOptions: options] autorelease];
auto instance = [[[I2PRouterTask alloc] initWithOptions: options] autorelease];
setGlobalRouterObject(instance);
//NSThread *thr = [[NSThread alloc] initWithTarget:instance selector:@selector(execute) object:nil];
[instance execute];
@@ -112,6 +109,15 @@ void openUrl(NSString* url)
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: url]];
}
@implementation I2PStatusMenu
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
NSLog(@"item is: %@",item);
return YES;
}
@end
@implementation MenuBarCtrl
@@ -148,6 +154,8 @@ void openUrl(NSString* url)
- (void) startJavaRouterBtnHandler: (NSMenuItem *) menuItem
{
NSLog(@"Clicked startJavaRouterBtnHandler");
AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
[appDelegate startupI2PRouter];
}
- (void) restartJavaRouterBtnHandler: (NSMenuItem *) menuItem
@@ -210,9 +218,9 @@ void openUrl(NSString* url)
[self.menu release];
}
- (NSMenu *)createStatusBarMenu
- (I2PStatusMenu *)createStatusBarMenu
{
NSMenu *menu = [[NSMenu alloc] init];
I2PStatusMenu *menu = [[I2PStatusMenu alloc] init];
[menu setAutoenablesItems:NO];
NSMenuItem *openConsoleI2Pbtn =
@@ -271,10 +279,10 @@ void openUrl(NSString* url)
@implementation AppDelegate
- (void)extractI2PBaseDir:(ExtractMetaInfo *)metaInfo completion:(void(^)(BOOL success, NSError *error))completion
- (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion
{
std::string basePath([metaInfo.i2pBase UTF8String]);
NSParameterAssert(metaInfo.i2pBase);
std::string basePath([self.metaInfo.i2pBase UTF8String]);
NSParameterAssert(self.metaInfo.i2pBase);
NSError *error = NULL;
BOOL success;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@@ -286,10 +294,10 @@ void openUrl(NSString* url)
basearg += basePath;
std::string zippath("-Di2p.base.zip=");
zippath += [metaInfo.zipFile UTF8String];
zippath += [self.metaInfo.zipFile UTF8String];
std::string jarfile("-cp ");
jarfile += [metaInfo.jarFile UTF8String];
jarfile += [self.metaInfo.jarFile UTF8String];
// Create directory
mkdir(basePath.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
@@ -305,7 +313,7 @@ void openUrl(NSString* url)
cli.push_back("net.i2p.launchers.BaseExtractor");
//auto charCli = map(cli, [](std::string str){ return str.c_str(); });
std::string execStr = [metaInfo.javaBinary UTF8String];
std::string execStr = [self.metaInfo.javaBinary UTF8String];
for_each(cli, [&execStr](std::string str){ execStr += std::string(" ") + str; });
NSLog(@"Trying cmd: %@", [NSString stringWithUTF8String:execStr.c_str()]);
@@ -337,16 +345,12 @@ void openUrl(NSString* url)
});
}
- (void)startupI2PRouter:(ExtractMetaInfo *)metaInfo
- (void)startupI2PRouter
{
std::string basePath([metaInfo.i2pBase UTF8String]);
auto buildClassPath = [](std::string basePath) -> std::vector<std::string> {
return globVector(basePath+std::string("/lib/*.jar"));
};
// Expect base to be extracted by now.
std::string basePath([self.metaInfo.i2pBase UTF8String]);
// Get paths
NSBundle *launcherBundle = [NSBundle mainBundle];
// Get paths
NSBundle *launcherBundle = [NSBundle mainBundle];
auto jarList = buildClassPath(basePath);
std::string classpathStrHead = "-classpath";
std::string classpathStr = "";
@@ -371,12 +375,12 @@ void openUrl(NSString* url)
argList.push_back([NSString stringWithUTF8String:classpathStrHead.c_str()]);
argList.push_back([NSString stringWithUTF8String:classpathStr.c_str()]);
argList.push_back(@"net.i2p.router.Router");
auto javaBin = std::string([metaInfo.javaBinary UTF8String]);
auto javaBin = std::string([self.metaInfo.javaBinary UTF8String]);
sendUserNotification(APP_IDSTR, @"I2P Router is starting up!", self.contentImage);
auto nsJavaBin = metaInfo.javaBinary;
auto nsBasePath = metaInfo.i2pBase;
auto nsJavaBin = self.metaInfo.javaBinary;
auto nsBasePath = self.metaInfo.i2pBase;
NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()];
startupRouter(nsJavaBin, arrArguments, nsBasePath);
//if (self.enableVerboseLogging) NSLog(@"Defaults: %@", [pref dictionaryRepresentation]);
@@ -434,7 +438,8 @@ void openUrl(NSString* url)
@"lastI2PVersion" : (NSString *)CFSTR(DEF_I2P_VERSION),
@"enableLogging": @true,
@"enableVerboseLogging": @true,
@"autoStartRouter": @true
@"autoStartRouter": @true,
@"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8)
}];
if (self.enableVerboseLogging) NSLog(@"Default JVM home preference set to: %@", (NSString *)cfDefaultHome);
@@ -468,12 +473,9 @@ void openUrl(NSString* url)
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
[NSApp activateIgnoringOtherApps:YES];
//auto prefArray = CFPreferencesCopyKeyList(CFAPPDOMAIN, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
//CFShow(prefArray);
auto javaHomePref = [self.userPreferences stringForKey:@"javaHome"];
if (self.enableVerboseLogging) NSLog(@"Java home from preferences: %@", javaHomePref);
// This is the only GUI the user experience on a regular basis.
self.menuBarCtrl = [[MenuBarCtrl alloc] init];
@@ -482,13 +484,8 @@ void openUrl(NSString* url)
NSLog(@"We should have started the statusbar object by now...");
// 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);
if (self.enableVerboseLogging) printf("Home directory is: %s\n", buffer);
std::string i2pBaseDir(getDefaultBaseDir());
//if (self.enableVerboseLogging) printf("Home directory is: %s\n", buffer);
//[statusBarButton setAction:@selector(itemClicked:)];
@@ -499,57 +496,57 @@ void openUrl(NSString* url)
self.menuBarCtrl.enableLogging = self.enableLogging;
self.menuBarCtrl.enableVerboseLogging = self.enableVerboseLogging;
if (port_check() != 0)
{
NSLog(@"Seems i2p is already running - I will not start the router (port 7657 is in use..)");
return;
}
if (self.enableVerboseLogging) NSLog(@"processinfo %@", [[NSProcessInfo processInfo] arguments]);
auto getJavaHomeLambda = [&pref,&self]() -> std::string {
NSString* val = @"";
val = [pref stringForKey:@"javaHome"];
if (val == NULL) val = @"";
if (self.enableVerboseLogging) NSLog(@"Javahome: %@", val);
return std::string([val UTF8String]);;
};
auto getJavaBin = [&getJavaHomeLambda]() -> std::string {
// Get Java home
auto javaHome = getJavaHomeLambda();
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;
};
auto buildClassPath = [](std::string basePath) -> std::vector<std::string> {
return globVector(basePath+std::string("/lib/*.jar"));
};
auto metaInfo = [ExtractMetaInfo alloc];
metaInfo.i2pBase = [NSString stringWithUTF8String:buffer];
metaInfo.javaBinary = [NSString stringWithUTF8String:getJavaBin().c_str()];
metaInfo.jarFile = [launcherBundle pathForResource:@"launcher" ofType:@"jar"];
metaInfo.zipFile = [launcherBundle pathForResource:@"base" ofType:@"zip"];
self.metaInfo = [[ExtractMetaInfo alloc] init];
self.metaInfo.i2pBase = [NSString stringWithUTF8String:i2pBaseDir.c_str()];
self.metaInfo.javaBinary = [NSString stringWithUTF8String:getJavaBin().c_str()];
self.metaInfo.jarFile = [launcherBundle pathForResource:@"launcher" ofType:@"jar"];
self.metaInfo.zipFile = [launcherBundle pathForResource:@"base" ofType:@"zip"];
std::string basearg("-Di2p.dir.base=");
basearg += i2pBaseDir;
std::string jarfile("-cp ");
jarfile += [metaInfo.zipFile UTF8String];
jarfile += [self.metaInfo.zipFile UTF8String];
struct stat sb;
if ( !(stat(buffer, &sb) == 0 && S_ISDIR(sb.st_mode)) )
if ( !(stat(i2pBaseDir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) )
{
// I2P is not extracted.
if (self.enableVerboseLogging) NSLog(@"I2P Directory don't exists!");
[self extractI2PBaseDir: metaInfo completion:^(BOOL success, NSError *error) {
[self extractI2PBaseDir:^(BOOL success, NSError *error) {
//__typeof__(self) strongSelf = weakSelf;
//if (strongSelf == nil) return;
[self startupI2PRouter:metaInfo];
[self startupI2PRouter];
}];
} else {
if (self.enableVerboseLogging) NSLog(@"I2P directory found!");
[self startupI2PRouter:metaInfo];
[self startupI2PRouter];
}
}

View File

@@ -0,0 +1,59 @@
#pragma once
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
typedef struct sockaddr *sad; /* A necesary dummy typedef */
int port_check(int portNum=7657)
{
int sock; /* Socket that will be bind */
struct sockaddr_in sin; /* Address Structure */
/* Create the socket */
/* PF_INET is the option for make a TCP socket.
You can try "man socket" for more info */
sock = socket( PF_INET, SOCK_STREAM, 0 );
/* The socket creation failed */
if ( 0 > sock ) {
perror( "socket" );
return ( -1 );
}
/* Address */
sin.sin_family = AF_INET;
sin.sin_port = htons( portNum ); /* htons() convert the number
to big endian */
sin.sin_addr.s_addr = INADDR_ANY;
/* We bind the socket to the port PORT to check if
the port is in use */
if ( 0 > bind( sock, (sad)&sin, sizeof( sin ) ) ) {
/* Bind failed, now we can check if the address is
in use */
if ( EADDRINUSE == errno ) {
/* We put the code necesary to manage this case */
printf( "The TCP port %d is in use.\n", portNum );
}
else
/* If the error were other than EADDRINUSE, we print it */
perror( "bind" );
return 1;
}
/* If we arrive to this point, the port weren't in use and
we have it attached to our program. We can close
the socket or use it */
close( sock ); /* Close the socket */
return 0;
}