source: launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift @ 01a05f7

Last change on this file since 01a05f7 was 7615b92, checked in by meeh <meeh@…>, 2 years ago

Adding all new code, removed a lot obsolete code and fixed import paths etc.
Mac OS X launcher:

  • UI built on Swift
    • Why?
      • Apple seems to on purpose make it harder to get into Objective-C these days
      • Swift is compiled to native code, but has easiness of Javascript in programming
      • Perfect for the OS X UI, many guides & tutorials as well
  • "Backend" in Objective-C++ / C++14
    • Why?
      • Originally written in Objective-C / C++14 with C++17 backports
      • Only for backend because of the time the development takes *

Short summary of features:

  • Java
    • It can detect java from:
      • JAVA_HOME environment variable
      • "Internet Plug-Ins" Apple stuff
      • By the /usr/libexec/java_home binary helper
    • It can unpack a new version of I2P
      • Unpacks to ~/Library/I2P
      • Can check currently unpacked version in ~/Library/I2P via i2p.jar's "net.i2p.CoreVersion?"
  • User Interface (a popover, see https://youtu.be/k8L3lQ5rUq0 for example of this concept)
    • Router control tab view
      • It can start the router
      • It can stop the router
      • It can detect already running router, then avoid fireing up one
      • It can show basic information about the router state & version
    • Log view tab (not yet done)
  • While left-click triggers popover, right-click draws a minimal context menu
  • Property mode set to 100644
File size: 2.7 KB
Line 
1//
2//  RouterProcessStatus.swift
3//  I2PLauncher
4//
5//  Created by Mikal Villa on 18/09/2018.
6//  Copyright © 2018 The I2P Project. All rights reserved.
7//
8
9import Foundation
10import AppKit
11
12class RouterProcessStatus : NSObject {
13 
14  /**
15   *
16   * Why the functions bellow? Because the Objective-C bridge is limited, it can't do Swift "static's" over it.
17   *
18   **/
19 
20  func setRouterStatus(_ isRunning: Bool = false) {
21    RouterProcessStatus.isRouterRunning = isRunning
22  }
23 
24  func setRouterRanByUs(_ ranByUs: Bool = false) {
25    RouterProcessStatus.isRouterChildProcess = ranByUs
26  }
27 
28  func getRouterIsRunning() -> Bool? {
29    return RouterProcessStatus.isRouterRunning
30  }
31}
32
33extension RouterProcessStatus {
34  static var isRouterRunning : Bool = false
35  static var isRouterChildProcess : Bool = false
36  static var routerVersion : String? = Optional.none
37  static var routerUptime : String? = Optional.none
38  static var routerStartedAt : Date? = Optional.none
39  static var knownJavaBinPath : String? = Optional.none
40  static var i2pDirectoryPath : String = NSHomeDirectory() + "/Library/I2P"
41 
42  static var knownRouterSubTaskRef : I2PSubprocess? = Optional.none
43 
44}
45
46
47
48
49extension RouterProcessStatus {
50  static func checkTcpPortForListen(port: in_port_t) -> (Bool, descr: String){
51   
52    let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)
53    if socketFileDescriptor == -1 {
54      return (false, "SocketCreationFailed, \(descriptionOfLastError())")
55    }
56   
57    var addr = sockaddr_in()
58    let sizeOfSockkAddr = MemoryLayout<sockaddr_in>.size
59    addr.sin_len = __uint8_t(sizeOfSockkAddr)
60    addr.sin_family = sa_family_t(AF_INET)
61    addr.sin_port = Int(OSHostByteOrder()) == OSLittleEndian ? _OSSwapInt16(port) : port
62    addr.sin_addr = in_addr(s_addr: inet_addr("0.0.0.0"))
63    addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
64    var bind_addr = sockaddr()
65    memcpy(&bind_addr, &addr, Int(sizeOfSockkAddr))
66   
67    if Darwin.bind(socketFileDescriptor, &bind_addr, socklen_t(sizeOfSockkAddr)) == -1 {
68      let details = descriptionOfLastError()
69      release(socket: socketFileDescriptor)
70      return (false, "\(port), BindFailed, \(details)")
71    }
72    if listen(socketFileDescriptor, SOMAXCONN ) == -1 {
73      let details = descriptionOfLastError()
74      release(socket: socketFileDescriptor)
75      return (false, "\(port), ListenFailed, \(details)")
76    }
77    release(socket: socketFileDescriptor)
78    return (true, "\(port) is free for use")
79  }
80 
81  static func release(socket: Int32) {
82    Darwin.shutdown(socket, SHUT_RDWR)
83    close(socket)
84  }
85  static func descriptionOfLastError() -> String {
86    return String(cString: UnsafePointer(strerror(errno))) ?? "Error: \(errno)"
87  }
88}
89
Note: See TracBrowser for help on using the repository browser.