forked from I2P_Developers/i2p.i2p
merge of '917225cb79561b9c536091f9c0790633ebbca610'
and 'c9243853a4211ebe92d964f7aa6ba57e624d6ab8'
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "version.h"
|
||||
|
||||
@class SwiftMainDelegate;
|
||||
@class I2PDeployer;
|
||||
|
||||
@protocol SwiftMainDelegateProto
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
|
||||
@@ -92,6 +93,7 @@ inline void sendUserNotification(NSString* title, NSString* informativeText, boo
|
||||
@property (assign) SwiftMainDelegate *swiftRuntime;
|
||||
@property (assign) NSUserDefaults *userPreferences;
|
||||
@property (assign) ExtractMetaInfo *metaInfo;
|
||||
@property (assign) I2PDeployer *deployer;
|
||||
@property (copy) NSImage *contentImage NS_AVAILABLE(10_9, NA);
|
||||
|
||||
- (void) extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion;
|
||||
|
||||
@@ -37,6 +37,5 @@
|
||||
</items>
|
||||
<point key="canvasLocation" x="17" y="167"/>
|
||||
</menu>
|
||||
<customObject id="xTS-ll-kWI" customClass="SUUpdater"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -90,16 +90,8 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button identifier="restartRouterButton" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C1m-1t-Xiq" userLabel="restart-button">
|
||||
<rect key="frame" x="10" y="150" width="128" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Restart Router" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="sih-uF-V06">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button identifier="openConsoleButton" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XZi-oz-5gy" userLabel="open-console-button">
|
||||
<rect key="frame" x="11" y="123" width="126" height="32"/>
|
||||
<rect key="frame" x="10" y="150" width="126" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Open Console" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Yh8-lj-JFi">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@@ -133,7 +125,7 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="E5l-WA-qOn">
|
||||
<rect key="frame" x="1" y="1" width="407" height="226"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView identifier="LoggerTextView" ambiguous="YES" importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="bgQ-8i-Xgb" userLabel="LoggerTextView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="407" height="226"/>
|
||||
|
||||
@@ -93,7 +93,8 @@ class Logger {
|
||||
}
|
||||
|
||||
@objc static func openLink(url: String) {
|
||||
SBridge.sharedInstance().openUrl(url)
|
||||
NSLog("Trying to open \(url)")
|
||||
NSWorkspace.shared().open(NSURL(string: url)! as URL)
|
||||
}
|
||||
|
||||
@objc func applicationWillTerminate() {
|
||||
|
||||
111
launchers/macosx/I2PLauncher/Utils/FolderContentMonitor.swift
Normal file
111
launchers/macosx/I2PLauncher/Utils/FolderContentMonitor.swift
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// FolderContentMonitor.swift
|
||||
// I2PLauncher
|
||||
//
|
||||
// Created by Mikal Villa on 28/09/2018.
|
||||
// Copyright © 2018 The I2P Project. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/*
|
||||
infix operator ~>
|
||||
|
||||
private let queue = DispatchQueue(label: "background")
|
||||
|
||||
func ~> <R> (
|
||||
backgroundClosure: @escaping () -> R,
|
||||
mainClosure: @escaping (_ result: R) -> ())
|
||||
{
|
||||
queue.async {
|
||||
let result = backgroundClosure()
|
||||
DispatchQueue.main.async(execute: {
|
||||
mainClosure(result)
|
||||
})
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public struct Event: CustomStringConvertible {
|
||||
|
||||
public let eventId: FSEventStreamEventId
|
||||
public let eventPath: String
|
||||
public let eventFlags: FSEventStreamEventFlags
|
||||
|
||||
public var description: String {
|
||||
return "\(eventId) - \(eventFlags) - \(eventPath)"
|
||||
}
|
||||
}
|
||||
|
||||
public class FolderContentMonitor {
|
||||
|
||||
let callback: (Event) -> Void
|
||||
|
||||
public init(pathsToWatch: [String], sinceWhen: FSEventStreamEventId = FSEventStreamEventId(kFSEventStreamEventIdSinceNow), callback: @escaping (Event) -> Void) {
|
||||
|
||||
self.lastEventId = sinceWhen
|
||||
self.pathsToWatch = pathsToWatch
|
||||
self.callback = callback
|
||||
}
|
||||
|
||||
deinit {
|
||||
stop()
|
||||
}
|
||||
|
||||
// MARK: - Private Properties
|
||||
private let eventCallback: FSEventStreamCallback = {
|
||||
(stream: ConstFSEventStreamRef,
|
||||
contextInfo: UnsafeMutableRawPointer?,
|
||||
numEvents: Int,
|
||||
eventPaths: UnsafeMutableRawPointer,
|
||||
eventFlags: UnsafePointer<FSEventStreamEventFlags>,
|
||||
eventIds: UnsafePointer<FSEventStreamEventId>) in
|
||||
|
||||
let fileSystemWatcher: FolderContentMonitor = unsafeBitCast(contextInfo, to: FolderContentMonitor.self)
|
||||
|
||||
guard let paths = unsafeBitCast(eventPaths, to: NSArray.self) as? [String] else { return }
|
||||
|
||||
for index in 0..<numEvents {
|
||||
fileSystemWatcher.processEvent(eventId: eventIds[index], eventPath: paths[index], eventFlags: eventFlags[index])
|
||||
}
|
||||
|
||||
fileSystemWatcher.lastEventId = eventIds[numEvents - 1]
|
||||
}
|
||||
|
||||
private let pathsToWatch: [String]
|
||||
private var started = false
|
||||
private var streamRef: FSEventStreamRef!
|
||||
|
||||
private func processEvent(eventId: FSEventStreamEventId, eventPath: String, eventFlags: FSEventStreamEventFlags) {
|
||||
|
||||
let event = Event(eventId: eventId, eventPath: eventPath, eventFlags: eventFlags)
|
||||
callback(event)
|
||||
}
|
||||
|
||||
public private(set) var lastEventId: FSEventStreamEventId
|
||||
|
||||
public func start() {
|
||||
guard started == false else { return }
|
||||
|
||||
var context = FSEventStreamContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
|
||||
context.info = Unmanaged.passUnretained(self).toOpaque()
|
||||
let flags = UInt32(kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagFileEvents)
|
||||
streamRef = FSEventStreamCreate(kCFAllocatorDefault, eventCallback, &context, pathsToWatch as CFArray, lastEventId, 0, flags)
|
||||
|
||||
FSEventStreamScheduleWithRunLoop(streamRef, CFRunLoopGetMain(), CFRunLoopMode.defaultMode.rawValue)
|
||||
FSEventStreamStart(streamRef)
|
||||
|
||||
started = true
|
||||
}
|
||||
|
||||
public func stop() {
|
||||
guard started == true else { return }
|
||||
|
||||
FSEventStreamStop(streamRef)
|
||||
FSEventStreamInvalidate(streamRef)
|
||||
FSEventStreamRelease(streamRef)
|
||||
streamRef = nil
|
||||
|
||||
started = false
|
||||
}
|
||||
}
|
||||
@@ -34,15 +34,15 @@ extension LaunchAgent {
|
||||
/// Run `launchctl start` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status()`
|
||||
public func start() {
|
||||
LaunchAgentManager.shared.start(self)
|
||||
public func start(_ callback: ((Process) -> Void)? = nil ) {
|
||||
LaunchAgentManager.shared.start(self, callback)
|
||||
}
|
||||
|
||||
/// Run `launchctl stop` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status()`
|
||||
public func stop() {
|
||||
LaunchAgentManager.shared.stop(self)
|
||||
public func stop(_ callback: ((Process) -> Void)? = nil ) {
|
||||
LaunchAgentManager.shared.stop(self, callback)
|
||||
}
|
||||
|
||||
/// Run `launchctl load` on the agent
|
||||
|
||||
@@ -88,41 +88,53 @@ extension LaunchAgentManager {
|
||||
/// Run `launchctl start` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status(_: LaunchAgent)`
|
||||
public func start(_ agent: LaunchAgent) {
|
||||
public func start(_ agent: LaunchAgent, _ termHandler: ((Process) -> Void)? = nil ) {
|
||||
let arguments = ["start", agent.label]
|
||||
Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
let proc = Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
if ((termHandler) != nil) {
|
||||
proc.terminationHandler = termHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Run `launchctl stop` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status(_: LaunchAgent)`
|
||||
public func stop(_ agent: LaunchAgent) {
|
||||
public func stop(_ agent: LaunchAgent, _ termHandler: ((Process) -> Void)? = nil ) {
|
||||
let arguments = ["stop", agent.label]
|
||||
Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
let proc = Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
if ((termHandler) != nil) {
|
||||
proc.terminationHandler = termHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Run `launchctl load` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status(_: LaunchAgent)`
|
||||
public func load(_ agent: LaunchAgent) throws {
|
||||
public func load(_ agent: LaunchAgent, _ termHandler: ((Process) -> Void)? = nil ) throws {
|
||||
guard let agentURL = agent.url else {
|
||||
throw LaunchAgentManagerError.urlNotSet(label: agent.label)
|
||||
}
|
||||
|
||||
let arguments = ["load", agentURL.path]
|
||||
Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
let proc = Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
if ((termHandler) != nil) {
|
||||
proc.terminationHandler = termHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Run `launchctl unload` on the agent
|
||||
///
|
||||
/// Check the status of the job with `.status(_: LaunchAgent)`
|
||||
public func unload(_ agent: LaunchAgent) throws {
|
||||
public func unload(_ agent: LaunchAgent, _ termHandler: ((Process) -> Void)? = nil ) throws {
|
||||
guard let agentURL = agent.url else {
|
||||
throw LaunchAgentManagerError.urlNotSet(label: agent.label)
|
||||
}
|
||||
|
||||
let arguments = ["unload", agentURL.path]
|
||||
Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
let proc = Process.launchedProcess(launchPath: LaunchAgentManager.launchctl, arguments: arguments)
|
||||
if ((termHandler) != nil) {
|
||||
proc.terminationHandler = termHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Retreives the status of the LaunchAgent from `launchctl`
|
||||
|
||||
@@ -82,4 +82,7 @@ inline void MLog(int loglevel, NSString* format, ...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MMLog(format_string,...) ((MLog(1, [NSString stringWithFormat:format_string,##__VA_ARGS__])))
|
||||
|
||||
#endif /* logger_c_h */
|
||||
|
||||
@@ -25,6 +25,7 @@ class RouterManager : NSObject {
|
||||
let routerRunner = RouterRunner()
|
||||
|
||||
var logViewStorage: NSTextStorage?
|
||||
var lastRouterPid : String? = nil
|
||||
|
||||
private static func handleRouterException(information:Any?) {
|
||||
Logger.MLog(level:1,"event! - handle router exception")
|
||||
@@ -94,6 +95,27 @@ class RouterManager : NSObject {
|
||||
routerManager.eventManager.listenTo(eventName: "router_already_running", action: handleRouterAlreadyStarted)
|
||||
routerManager.eventManager.listenTo(eventName: "router_can_start", action: routerManager.routerRunner.StartAgent)
|
||||
routerManager.eventManager.listenTo(eventName: "router_can_setup", action: routerManager.routerRunner.SetupAgent)
|
||||
|
||||
//routerManager.eventManager.listenTo(eventName: "launch_agent_running", action: routerManager.routerRunner.onLoadedAgent)
|
||||
|
||||
routerManager.eventManager.listenTo(eventName: "launch_agent_running", action: {
|
||||
let agent = RouterRunner.launchAgent!
|
||||
let agentStatus = agent.status()
|
||||
switch agentStatus {
|
||||
case .running(let pid):
|
||||
DispatchQueue.main.async {
|
||||
routerManager.eventManager.trigger(eventName: "router_start", information: String(pid))
|
||||
routerManager.routerRunner.routerStatus.setRouterStatus(true)
|
||||
routerManager.routerRunner.routerStatus.setRouterRanByUs(true)
|
||||
routerManager.eventManager.trigger(eventName: "router_pid", information: String(pid))
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
NSLog("wtf, agent status = \(agentStatus)")
|
||||
break
|
||||
}
|
||||
})
|
||||
return routerManager
|
||||
}()
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class RouterRunner: NSObject {
|
||||
|
||||
let domainLabel = "net.i2p.macosx.I2PRouter"
|
||||
|
||||
let plistName = "net.i2p.macosx.I2PRouterAgent.plist"
|
||||
let plistName = "net.i2p.macosx.I2PRouter.plist"
|
||||
|
||||
let defaultStartupCommand:String = "/usr/libexec/java_home"
|
||||
|
||||
@@ -35,6 +35,10 @@ class RouterRunner: NSObject {
|
||||
|
||||
let appSupportPath = FileManager.default.urls(for: FileManager.SearchPathDirectory.applicationSupportDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func SetupAgent() {
|
||||
let agent = SetupAndReturnAgent()
|
||||
RouterRunner.launchAgent = agent
|
||||
@@ -106,78 +110,70 @@ class RouterRunner: NSObject {
|
||||
let shouldStartupAtLogin = userPreferences.bool(forKey: "startRouterAtLogin")
|
||||
agent.runAtLoad = shouldStartupAtLogin
|
||||
agent.keepAlive = true
|
||||
|
||||
do {
|
||||
|
||||
try LaunchAgentManager.shared.write(agent, called: self.plistName)
|
||||
sleep(1)
|
||||
try LaunchAgentManager.shared.load(agent)
|
||||
sleep(1)
|
||||
|
||||
let agentStatus = LaunchAgentManager.shared.status(agent)
|
||||
switch agentStatus {
|
||||
case .running:
|
||||
break
|
||||
case .loaded:
|
||||
break
|
||||
case .unloaded:
|
||||
sleep(2)
|
||||
break
|
||||
DispatchQueue(label: "background_starter").async {
|
||||
do {
|
||||
try LaunchAgentManager.shared.write(agent, called: self.plistName)
|
||||
sleep(1)
|
||||
try LaunchAgentManager.shared.load(agent)
|
||||
sleep(1)
|
||||
|
||||
let agentStatus = LaunchAgentManager.shared.status(agent)
|
||||
switch agentStatus {
|
||||
case .running:
|
||||
break
|
||||
case .loaded:
|
||||
DispatchQueue.main.async {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: agent)
|
||||
}
|
||||
break
|
||||
case .unloaded:
|
||||
break
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_setup_error", information: "\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: agent)
|
||||
} catch {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_setup_error", information: "\(error)")
|
||||
}
|
||||
return agent
|
||||
}
|
||||
|
||||
func StartAgent(information:Any?) {
|
||||
let agent = RouterRunner.launchAgent!
|
||||
LaunchAgentManager.shared.start(agent)
|
||||
sleep(1)
|
||||
let agentStatus = agent.status()
|
||||
switch agentStatus {
|
||||
case .running(let pid):
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_start", information: String(pid))
|
||||
routerStatus.setRouterStatus(true)
|
||||
routerStatus.setRouterRanByUs(true)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
// Delayed message to ensure UI has been initialized.
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_pid", information: String(pid))
|
||||
}
|
||||
break
|
||||
|
||||
default: break
|
||||
|
||||
func StartAgent(_ information:Any? = nil) {
|
||||
let agent = RouterRunner.launchAgent ?? information as! LaunchAgent
|
||||
DispatchQueue(label: "background_block").async {
|
||||
LaunchAgentManager.shared.start(agent, { (proc) in
|
||||
NSLog("Will call onLaunchdStarted")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func StopAgent() {
|
||||
var agentStatus = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
|
||||
switch agentStatus {
|
||||
case .running:
|
||||
LaunchAgentManager.shared.stop(RouterRunner.launchAgent!)
|
||||
break
|
||||
case .loaded, .unloaded:
|
||||
try! LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
routerStatus.setRouterStatus(false)
|
||||
routerStatus.setRouterRanByUs(false)
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_stop", information: "ok")
|
||||
return;
|
||||
break
|
||||
default: break
|
||||
}
|
||||
sleep(1)
|
||||
agentStatus = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
|
||||
switch agentStatus {
|
||||
case .loaded, .unloaded:
|
||||
try! LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
routerStatus.setRouterStatus(false)
|
||||
routerStatus.setRouterRanByUs(false)
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_stop", information: "ok")
|
||||
break
|
||||
default: break
|
||||
func StopAgent(_ callback: @escaping () -> () = {}) {
|
||||
let agentStatus = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
|
||||
DispatchQueue(label: "background_block").async {
|
||||
do {
|
||||
switch agentStatus {
|
||||
case .running:
|
||||
// For now we need to use unload to stop it.
|
||||
try LaunchAgentManager.shared.unload(RouterRunner.launchAgent!, { (proc) in
|
||||
// Called when stop is actually executed
|
||||
proc.waitUntilExit()
|
||||
DispatchQueue.main.async {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_stop", information: "ok")
|
||||
callback()
|
||||
}
|
||||
})
|
||||
try LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
break
|
||||
case .unloaded:
|
||||
// Seems it sometimes get unloaded on stop, we load it again.
|
||||
try! LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
return
|
||||
default: break
|
||||
}
|
||||
} catch {
|
||||
NSLog("Error \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,63 +24,73 @@ import Cocoa
|
||||
@IBOutlet var routerUptimeLabel: NSTextField?
|
||||
@IBOutlet var routerPIDLabel: NSTextField?
|
||||
|
||||
|
||||
@IBOutlet var quickControlView: NSView?
|
||||
@IBOutlet var routerStartStopButton: NSButton?
|
||||
@IBOutlet var openConsoleButton: NSButton?
|
||||
|
||||
|
||||
@objc func actionBtnOpenConsole(_ sender: Any?) {
|
||||
SwiftMainDelegate.openLink(url: "http://localhost:7657")
|
||||
}
|
||||
|
||||
@objc func actionBtnStartRouter(_ sender: Any?) {
|
||||
NSLog("START ROUTER")
|
||||
NSLog("Router start clicked")
|
||||
/*if (RouterManager.shared().getRouterTask() == nil) {
|
||||
SBridge.sharedInstance().startupI2PRouter(RouterProcessStatus.i2pDirectoryPath)
|
||||
}*/
|
||||
(sender as! NSButton).isTransparent = true
|
||||
let routerStatus = RouterRunner.launchAgent?.status()
|
||||
switch routerStatus {
|
||||
case .loaded?:
|
||||
RouterManager.shared().routerRunner.StartAgent(information: RouterRunner.launchAgent)
|
||||
case .unloaded?:
|
||||
do {
|
||||
try LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
RouterManager.shared().routerRunner.StartAgent(information: RouterRunner.launchAgent)
|
||||
} catch {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_exception", information: error)
|
||||
DispatchQueue(label: "background_start").async {
|
||||
switch routerStatus {
|
||||
case .loaded?:
|
||||
RouterManager.shared().routerRunner.StartAgent(RouterRunner.launchAgent)
|
||||
case .unloaded?:
|
||||
do {
|
||||
try LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
|
||||
RouterManager.shared().routerRunner.StartAgent(RouterRunner.launchAgent)
|
||||
} catch {
|
||||
RouterManager.shared().eventManager.trigger(eventName: "router_exception", information: error)
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.reEnableButton()
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.reEnableButton()
|
||||
}
|
||||
|
||||
@objc func actionBtnStopRouter(_ sender: Any?) {
|
||||
NSLog("STOP ROUTER")
|
||||
let routerStatus = RouterRunner.launchAgent?.status()
|
||||
switch routerStatus {
|
||||
case .running?:
|
||||
NSLog("Found running router")
|
||||
RouterManager.shared().routerRunner.StopAgent()
|
||||
break
|
||||
default:
|
||||
break
|
||||
NSLog("Router stop clicked")
|
||||
DispatchQueue(label: "background_shutdown").async {
|
||||
RouterManager.shared().routerRunner.StopAgent({
|
||||
RouterProcessStatus.isRouterRunning = false
|
||||
RouterProcessStatus.isRouterChildProcess = false
|
||||
NSLog("Router should be stopped by now.")
|
||||
})
|
||||
// Wait for it to die.
|
||||
|
||||
}
|
||||
RouterManager.shared().eventManager.trigger(eventName: "toggle_popover")
|
||||
self.reEnableButton()
|
||||
}
|
||||
|
||||
@objc func actionBtnRestartRouter(sender: Any?) {
|
||||
if (RouterManager.shared().getRouterTask() != nil) {
|
||||
//RouterManager.shared().getRouterTask()?.requestRestart()
|
||||
} else {
|
||||
NSLog("Can't restart a non running router, start it however...")
|
||||
//SBridge.sharedInstance().startupI2PRouter(RouterProcessStatus.i2pDirectoryPath)
|
||||
}
|
||||
func restartFn() {
|
||||
RouterManager.shared().routerRunner.StopAgent({
|
||||
sleep(30)
|
||||
RouterManager.shared().routerRunner.StartAgent()
|
||||
})
|
||||
}
|
||||
|
||||
func handlerRouterStart(information:Any?) {
|
||||
print("Triggered handlerRouterStart")
|
||||
NSLog("Triggered handlerRouterStart")
|
||||
NSLog("PID2! %@", information as! String)
|
||||
routerPIDLabel?.cell?.stringValue = "Router PID: "+(information as! String)
|
||||
routerPIDLabel?.needsDisplay = true
|
||||
routerStatusLabel?.cell?.stringValue = "Router status: Running"
|
||||
RouterManager.shared().lastRouterPid = (information as? String)
|
||||
self.toggleSetButtonStop()
|
||||
self.reEnableButton()
|
||||
}
|
||||
@@ -112,10 +122,14 @@ import Cocoa
|
||||
RouterStatusView.instance = self
|
||||
}
|
||||
self.reEnableButton()
|
||||
openConsoleButton!.cell!.action = #selector(self.actionBtnOpenConsole(_:))
|
||||
openConsoleButton!.cell!.target = self
|
||||
|
||||
}
|
||||
|
||||
func handleRouterStop() {
|
||||
routerPIDLabel?.cell?.stringValue = "Router PID: Not running"
|
||||
RouterManager.shared().lastRouterPid = nil
|
||||
self.toggleSetButtonStart()
|
||||
reEnableButton()
|
||||
}
|
||||
@@ -133,41 +147,49 @@ import Cocoa
|
||||
}
|
||||
|
||||
func setRouterStatusLabelText() {
|
||||
routerStartStopButton?.needsDisplay = true
|
||||
routerStartStopButton?.target = self
|
||||
quickControlView?.needsDisplay = true
|
||||
let staticStartedByLabelText = "Router started by launcher? "
|
||||
let staticIsRunningLabelText = "Router status: "
|
||||
let staticRouterVersionLabelText = "Router version: "
|
||||
let staticRouterPidLabelText = "Router PID: "
|
||||
|
||||
do {
|
||||
let currentStatus : AgentStatus = RouterRunner.launchAgent!.status()
|
||||
if currentStatus == AgentStatus.loaded || currentStatus == AgentStatus.unloaded {
|
||||
routerStatusLabel?.cell?.stringValue = "Router status: Not running"
|
||||
} else {
|
||||
routerStatusLabel?.cell?.stringValue = "Router status: Running"
|
||||
}
|
||||
} catch {
|
||||
// Ensure it's set even AgentStatus is nil (uninitialized yet..)
|
||||
routerStatusLabel?.cell?.stringValue = "Router status: Not running"
|
||||
}
|
||||
|
||||
let staticStartedByLabelText = "Router started by launcher?"
|
||||
if RouterProcessStatus.isRouterChildProcess {
|
||||
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+" Yes"
|
||||
// Use default here to avoid any potential crashes with force unwrapping
|
||||
let currentStatus : AgentStatus = RouterRunner.launchAgent?.status() ?? AgentStatus.unloaded
|
||||
if currentStatus == AgentStatus.loaded || currentStatus == AgentStatus.unloaded {
|
||||
routerStatusLabel?.cell?.stringValue = staticIsRunningLabelText+"Not running"
|
||||
} else {
|
||||
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+" No"
|
||||
routerStatusLabel?.cell?.stringValue = staticIsRunningLabelText+"Running"
|
||||
}
|
||||
routerStartedByLabel?.needsDisplay = true
|
||||
|
||||
if RouterProcessStatus.isRouterChildProcess {
|
||||
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+"Yes"
|
||||
} else {
|
||||
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+"No"
|
||||
}
|
||||
|
||||
// Try to display PID - if not, the string behind ?? is used as "default"
|
||||
let tmpPidText = RouterManager.shared().lastRouterPid ?? "Not running"
|
||||
routerPIDLabel?.cell?.stringValue = staticRouterPidLabelText+tmpPidText
|
||||
|
||||
if let version = RouterProcessStatus.routerVersion {
|
||||
routerVersionLabel?.cell?.stringValue = "Router version: " + version
|
||||
routerVersionLabel?.cell?.stringValue = staticRouterVersionLabelText + version
|
||||
} else {
|
||||
routerVersionLabel?.cell?.stringValue = "Router version: Still unknown"
|
||||
routerVersionLabel?.cell?.stringValue = staticRouterVersionLabelText + "Still unknown"
|
||||
}
|
||||
|
||||
if let routerStartTime = RouterProcessStatus.routerStartedAt {
|
||||
routerUptimeLabel?.cell?.stringValue = "Uptime: Router started " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: routerStartTime), numericDates: false)
|
||||
} else {
|
||||
routerUptimeLabel?.cell?.stringValue = "Uptime: Router isn't running"
|
||||
}
|
||||
|
||||
// Needs display function alerts the rendrerer that the UI parts need to be re-drawed.
|
||||
routerStartStopButton?.needsDisplay = true
|
||||
quickControlView?.needsDisplay = true
|
||||
routerUptimeLabel?.needsDisplay = true
|
||||
routerVersionLabel?.needsDisplay = true
|
||||
routerStartedByLabel?.needsDisplay = true
|
||||
routerPIDLabel?.needsDisplay = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,19 +44,22 @@ import Cocoa
|
||||
let pidStr = information as! String
|
||||
NSLog("PID! %@", pidStr)
|
||||
showPopover(sender: nil)
|
||||
//self.ctrl?.getRouterStatusView()?.handlerRouterStart(information: pidStr)
|
||||
RouterManager.shared().lastRouterPid = pidStr
|
||||
self.ctrl?.getRouterStatusView()?.needsDisplay = true
|
||||
}
|
||||
|
||||
func event_toggle(information:Any?) {
|
||||
self.togglePopover(sender: self)
|
||||
}
|
||||
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
self.ctrl = PopoverViewController.freshController()
|
||||
popover.contentViewController = self.ctrl
|
||||
//updateObjectRef = SUUpdater.shared()
|
||||
//updateObjectRef?.checkForUpdatesInBackground()
|
||||
RouterManager.shared().eventManager.listenTo(eventName: "router_pid", action: pidReaction)
|
||||
RouterManager.shared().eventManager.listenTo(eventName: "router_pid", action: pidReaction)
|
||||
|
||||
RouterManager.shared().eventManager.listenTo(eventName: "toggle_popover", action: event_toggle)
|
||||
|
||||
if let button = statusItem.button {
|
||||
button.image = NSImage(named:"StatusBarButtonImage")
|
||||
|
||||
@@ -100,11 +100,11 @@ static inline std::string trim_copy(std::string s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
NSString* stdStringToNSString(std::string &stdstr) {
|
||||
inline NSString* stdStringToNSString(std::string &stdstr) {
|
||||
return [NSString stringWithUTF8String:stdstr.c_str()];
|
||||
}
|
||||
|
||||
std::string nsStringToStd(NSString* nsStr) {
|
||||
inline std::string nsStringToStd(NSString* nsStr) {
|
||||
const char *charlist = [nsStr UTF8String];
|
||||
return std::string(charlist);
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ using namespace subprocess;
|
||||
|
||||
- (void)extractI2PBaseDir:(void(^)(BOOL success, NSError *error))completion
|
||||
{
|
||||
auto deployer = [[I2PDeployer alloc] initWithMetaInfo:self.metaInfo];
|
||||
[deployer extractI2PBaseDir:completion];
|
||||
self.deployer = [[I2PDeployer alloc] initWithMetaInfo:self.metaInfo];
|
||||
[self.deployer extractI2PBaseDir:completion];
|
||||
}
|
||||
|
||||
- (void)setApplicationDefaultPreferences {
|
||||
@@ -77,6 +77,7 @@ using namespace subprocess;
|
||||
@"startRouterAtLogin": @NO,
|
||||
@"startRouterAtStartup": @NO,
|
||||
@"letRouterLiveEvenLauncherDied": @NO,
|
||||
@"consolePortCheckNum": @7657,
|
||||
@"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8)
|
||||
}];
|
||||
|
||||
@@ -119,10 +120,10 @@ using namespace subprocess;
|
||||
// Initialize the Swift environment (the UI components)
|
||||
[self.swiftRuntime applicationDidFinishLaunching];
|
||||
|
||||
// TODO: Make the port a setting which defaults to 7657
|
||||
if (port_check(7657) != 0)
|
||||
NSInteger portNum = [self.userPreferences integerForKey:@"consolePortCheckNum"];
|
||||
if (port_check((int)portNum) != 0)
|
||||
{
|
||||
NSLog(@"Seems i2p is already running - I will not start the router (port 7657 is in use..)");
|
||||
NSLog(@"Seems i2p is already running - I will not start the router (port %d is in use..)", (int)portNum);
|
||||
sendUserNotification(@"Found already running router", @"TCP port 7657 seem to be used by another i2p instance.");
|
||||
|
||||
[routerStatus setRouterStatus: true];
|
||||
@@ -131,6 +132,13 @@ using namespace subprocess;
|
||||
} else {
|
||||
shouldAutoStartRouter = true;
|
||||
}
|
||||
if (![self.userPreferences boolForKey:@"startRouterAtLogin"] && ![self.userPreferences boolForKey:@"startRouterAtStartup"])
|
||||
{
|
||||
// In this case we don't want to find a running service
|
||||
std::string launchdFile(RealHomeDirectory());
|
||||
launchdFile += "/Library/LaunchAgents/net.i2p.macosx.I2PRouter.plist";
|
||||
|
||||
}
|
||||
|
||||
NSBundle *launcherBundle = [NSBundle mainBundle];
|
||||
|
||||
@@ -148,13 +156,6 @@ using namespace subprocess;
|
||||
std::string jarfile("-cp ");
|
||||
jarfile += [self.metaInfo.zipFile UTF8String];
|
||||
|
||||
// Might be hard to read if you're not used to Objective-C
|
||||
// But this is a "function call" that contains a "callback function"
|
||||
/*[routerStatus listenForEventWithEventName:@"router_can_start" callbackActionFn:^(NSString* information) {
|
||||
NSLog(@"Got signal, router can be started");
|
||||
[[SBridge sharedInstance] startupI2PRouter:self.metaInfo.i2pBase];
|
||||
}];*/
|
||||
|
||||
// This will trigger the router start after an upgrade.
|
||||
[routerStatus listenForEventWithEventName:@"router_must_upgrade" callbackActionFn:^(NSString* information) {
|
||||
NSLog(@"Got signal, router must be deployed from base.zip");
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
. .sign-secrets
|
||||
source $DIR/.sign-secrets
|
||||
|
||||
APP_NAME="I2PLauncher"
|
||||
VERSION="0.9.36"
|
||||
DMG_BACKGROUND_IMG="${DIR}/Background.png"
|
||||
VERSION="0.9.37"
|
||||
DMG_BACKGROUND_IMG=${BACKGROUND_IMG:-"Background.png"}
|
||||
|
||||
APP_EXE="${APP_NAME}.app/Contents/MacOS/${APP_NAME}"
|
||||
VOL_NAME="${APP_NAME} ${VERSION}"
|
||||
VOL_NAME="${APP_NAME}-${VERSION}"
|
||||
DMG_TMP="${VOL_NAME}-temp.dmg"
|
||||
DMG_FINAL="${VOL_NAME}.dmg"
|
||||
STAGING_DIR="/tmp/mkdmg$$"
|
||||
@@ -23,14 +23,12 @@ if [ $(echo " $_BACKGROUND_IMAGE_DPI_H != 72.0 " | bc) -eq 1 -o $(echo " $_BACKG
|
||||
|
||||
_DMG_BACKGROUND_TMP="${DMG_BACKGROUND_IMG%.*}"_dpifix."${DMG_BACKGROUND_IMG##*.}"
|
||||
|
||||
sips -s dpiWidth 72 -s dpiHeight 72 ${DMG_BACKGROUND_IMG} --out ${_DMG_BACKGROUND_TMP}
|
||||
sips -s dpiWidth 72 -s dpiHeight 72 $DIR/${DMG_BACKGROUND_IMG} --out $DIR/${_DMG_BACKGROUND_TMP}
|
||||
|
||||
DMG_BACKGROUND_IMG="${_DMG_BACKGROUND_TMP}"
|
||||
|
||||
DMG_BACKGROUND_IMG="${_DMG_BACKGROUND_TMP}"
|
||||
fi
|
||||
|
||||
# clear out any old data
|
||||
rm -rf "${STAGING_DIR}" "${DMG_TMP}" "${DMG_FINAL}"
|
||||
|
||||
# copy over the stuff we want in the final disk image to our staging dir
|
||||
mkdir -p "${STAGING_DIR}"
|
||||
cp -rpf "${APP_NAME}.app" "${STAGING_DIR}"
|
||||
@@ -39,7 +37,7 @@ cp -rpf "${APP_NAME}.app" "${STAGING_DIR}"
|
||||
# figure out how big our DMG needs to be
|
||||
# assumes our contents are at least 1M!
|
||||
SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9\.]*\)M\(.*\)/\1/'`
|
||||
SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1+0.5)}'`
|
||||
SIZE=`echo "${SIZE} + 23.0" | bc | awk '{print int($1+0.5)}'`
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Cannot compute size of staging dir"
|
||||
@@ -48,24 +46,28 @@ fi
|
||||
|
||||
# create the temp DMG file
|
||||
hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+ \
|
||||
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "${DMG_TMP}"
|
||||
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "$RELEASE_DIR/${DMG_TMP}"
|
||||
|
||||
echo "Created DMG: ${DMG_TMP}"
|
||||
|
||||
# mount it and save the device
|
||||
DEVICE=$(hdiutil attach -readwrite -noverify "${DMG_TMP}" | \
|
||||
DEVICE=$(hdiutil attach -readwrite -noverify "$RELEASE_DIR/${DMG_TMP}" | \
|
||||
egrep '^/dev/' | sed 1q | awk '{print $1}')
|
||||
|
||||
sleep 2
|
||||
|
||||
|
||||
|
||||
# add a link to the Applications dir
|
||||
echo "Add link to /Applications"
|
||||
pushd /Volumes/"${VOL_NAME}"
|
||||
ln -s /Applications
|
||||
cd /Volumes/"${VOL_NAME}"
|
||||
ln -sf /Applications Applications
|
||||
|
||||
# add a background image
|
||||
mkdir /Volumes/"${VOL_NAME}"/.background
|
||||
cp "${DMG_BACKGROUND_IMG}" /Volumes/"${VOL_NAME}"/.background/
|
||||
mkdir -p /Volumes/"${VOL_NAME}"/.background
|
||||
cp "$DIR/`basename ${DMG_BACKGROUND_IMG}`" /Volumes/"${VOL_NAME}"/.background/`basename ${DMG_BACKGROUND_IMG}`
|
||||
|
||||
cd $RELEASE_DIR
|
||||
|
||||
# tell the Finder to resize the window, set the background,
|
||||
# change the icon size, place the icons in the right position, etc.
|
||||
@@ -98,14 +100,15 @@ hdiutil detach "${DEVICE}"
|
||||
|
||||
# now make the final image a compressed disk image
|
||||
echo "Creating compressed image"
|
||||
hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FINAL}"
|
||||
hdiutil convert "$RELEASE_DIR/${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "$RELEASE_DIR/${DMG_FINAL}"
|
||||
|
||||
codesign --force --sign "${APPLE_CODE_SIGNER_ID}" "${DMG_FINAL}"
|
||||
codesign --force --deep --sign "${APPLE_CODE_SIGNER_ID}" "$RELEASE_DIR/${DMG_FINAL}"
|
||||
|
||||
# clean up
|
||||
rm -rf "${DMG_TMP}"
|
||||
rm -rf "$RELEASE_DIR/${DMG_TMP}"
|
||||
rm -rf "${STAGING_DIR}"
|
||||
|
||||
|
||||
echo 'Done.'
|
||||
|
||||
exit
|
||||
|
||||
Reference in New Issue
Block a user