172 changed files with 31755 additions and 622 deletions
@ -0,0 +1,7 @@ |
|||
//
|
|||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#include "procInfo.h" |
|||
#include "procHelper.h" |
Binary file not shown.
@ -0,0 +1,19 @@ |
|||
//
|
|||
// procHelper.h
|
|||
// RSwitch
|
|||
//
|
|||
// Created by hrbrmstr on 8/25/19.
|
|||
// Copyright ยฉ 2019 Bob Rudis. All rights reserved.
|
|||
//
|
|||
|
|||
#ifndef procHelper_h |
|||
#define procHelper_h |
|||
|
|||
#include <stdio.h> |
|||
#include "procHelper.h" |
|||
#include "procInfo.h" |
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NSMutableArray *getArgs(pid_t pid); |
|||
|
|||
#endif /* procHelper_h */ |
@ -0,0 +1,18 @@ |
|||
// |
|||
// procHelper.c |
|||
// RSwitch |
|||
// |
|||
// Created by hrbrmstr on 8/25/19. |
|||
// Copyright ยฉ 2019 Bob Rudis. All rights reserved. |
|||
// |
|||
|
|||
#include "procHelper.h" |
|||
#include "procInfo.h" |
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NSMutableArray *getArgs(pid_t pid) { |
|||
|
|||
Process* process = [[Process alloc] init:pid]; |
|||
return(process.arguments); |
|||
|
|||
} |
@ -0,0 +1,205 @@ |
|||
//
|
|||
// File: procInfo.h
|
|||
// Project: Proc Info
|
|||
//
|
|||
// Created by: Patrick Wardle
|
|||
// Copyright: 2017 Objective-See
|
|||
// License: Creative Commons Attribution-NonCommercial 4.0 International License
|
|||
//
|
|||
|
|||
#ifndef procInfo_h |
|||
#define procInfo_h |
|||
|
|||
#import <libproc.h> |
|||
#import <sys/sysctl.h> |
|||
#import <Foundation/Foundation.h> |
|||
|
|||
/* CLASSES */#import <Foundation/Foundation.h> |
|||
|
|||
|
|||
@class Binary; |
|||
@class Process; |
|||
|
|||
/* DEFINES */ |
|||
|
|||
//from audit_kevents.h
|
|||
#define EVENT_EXIT 1 |
|||
#define EVENT_FORK 2 |
|||
#define EVENT_EXECVE 23 |
|||
#define EVENT_EXEC 27 |
|||
#define EVENT_SPAWN 43190 |
|||
|
|||
//signers
|
|||
enum Signer{None, Apple, AppStore, DevID, AdHoc}; |
|||
|
|||
//signature status
|
|||
#define KEY_SIGNATURE_STATUS @"signatureStatus" |
|||
|
|||
//signer
|
|||
#define KEY_SIGNATURE_SIGNER @"signatureSigner" |
|||
|
|||
//signing auths
|
|||
#define KEY_SIGNATURE_AUTHORITIES @"signatureAuthorities" |
|||
|
|||
//code signing id
|
|||
#define KEY_SIGNATURE_IDENTIFIER @"signatureIdentifier" |
|||
|
|||
//entitlements
|
|||
#define KEY_SIGNATURE_ENTITLEMENTS @"signatureEntitlements" |
|||
|
|||
/* TYPEDEFS */ |
|||
|
|||
//block for library
|
|||
typedef void (^ProcessCallbackBlock)(Process* _Nonnull); |
|||
|
|||
/* OBJECT: PROCESS INFO */ |
|||
|
|||
@interface ProcInfo : NSObject |
|||
|
|||
//init w/ flag
|
|||
// flag dictates if CPU-intensive logic (code signing, etc) should be preformed
|
|||
-(id _Nullable)init:(BOOL)goEasy; |
|||
|
|||
//start monitoring
|
|||
-(void)start:(ProcessCallbackBlock _Nonnull )callback; |
|||
|
|||
//stop monitoring
|
|||
-(void)stop; |
|||
|
|||
//get list of running processes
|
|||
-(NSMutableArray* _Nonnull)currentProcesses; |
|||
|
|||
@end |
|||
|
|||
/* OBJECT: PROCESS */ |
|||
|
|||
@interface Process : NSObject |
|||
|
|||
/* PROPERTIES */ |
|||
|
|||
//pid
|
|||
@property pid_t pid; |
|||
|
|||
//ppid
|
|||
@property pid_t ppid; |
|||
|
|||
//user id
|
|||
@property uid_t uid; |
|||
|
|||
//type
|
|||
// used by process mon
|
|||
@property u_int16_t type; |
|||
|
|||
//exit code
|
|||
@property u_int32_t exit; |
|||
|
|||
//path
|
|||
@property(nonatomic, retain)NSString* _Nullable path; |
|||
|
|||
//args
|
|||
@property(nonatomic, retain)NSMutableArray* _Nonnull arguments; |
|||
|
|||
//ancestors
|
|||
@property(nonatomic, retain)NSMutableArray* _Nonnull ancestors; |
|||
|
|||
//signing info
|
|||
@property(nonatomic, retain)NSMutableDictionary* _Nonnull signingInfo; |
|||
|
|||
//Binary object
|
|||
// has path, hash, etc
|
|||
@property(nonatomic, retain)Binary* _Nonnull binary; |
|||
|
|||
//timestamp
|
|||
@property(nonatomic, retain)NSDate* _Nonnull timestamp; |
|||
|
|||
/* METHODS */ |
|||
|
|||
//init with a pid
|
|||
// method will then (try) fill out rest of object
|
|||
-(id _Nullable)init:(pid_t)processID; |
|||
|
|||
//generate signing info
|
|||
// also classifies if Apple/from App Store/etc.
|
|||
-(void)generateSigningInfo:(SecCSFlags)flags; |
|||
|
|||
//set process's path
|
|||
-(void)pathFromPid; |
|||
|
|||
//generate list of ancestors
|
|||
-(void)enumerateAncestors; |
|||
|
|||
//class method
|
|||
// get's parent of arbitrary process
|
|||
+(pid_t)getParentID:(pid_t)child; |
|||
|
|||
@end |
|||
|
|||
/* OBJECT: BINARY */ |
|||
|
|||
@interface Binary : NSObject |
|||
{ |
|||
|
|||
} |
|||
|
|||
/* PROPERTIES */ |
|||
|
|||
//path
|
|||
@property(nonatomic, retain)NSString* _Nonnull path; |
|||
|
|||
//name
|
|||
@property(nonatomic, retain)NSString* _Nonnull name; |
|||
|
|||
//icon
|
|||
@property(nonatomic, retain)NSImage* _Nonnull icon; |
|||
|
|||
//file attributes
|
|||
@property(nonatomic, retain)NSDictionary* _Nullable attributes; |
|||
|
|||
//spotlight meta data
|
|||
@property(nonatomic, retain)NSDictionary* _Nullable metadata; |
|||
|
|||
//bundle
|
|||
// nil for non-apps
|
|||
@property(nonatomic, retain)NSBundle* _Nullable bundle; |
|||
|
|||
//signing info
|
|||
@property(nonatomic, retain)NSDictionary* _Nonnull signingInfo; |
|||
|
|||
//hash
|
|||
@property(nonatomic, retain)NSMutableString* _Nonnull sha256; |
|||
|
|||
//identifier
|
|||
// either signing id or sha256 hash
|
|||
@property(nonatomic, retain)NSString* _Nonnull identifier; |
|||
|
|||
/* METHODS */ |
|||
|
|||
//init w/ a path
|
|||
-(id _Nonnull)init:(NSString* _Nonnull)path; |
|||
|
|||
/* the following methods are rather CPU-intensive
|
|||
as such, if the proc monitoring is run with the 'goEasy' option, they aren't automatically invoked |
|||
*/ |
|||
|
|||
//get an icon for a process
|
|||
// for apps, this will be app's icon, otherwise just a standard system one
|
|||
-(void)getIcon; |
|||
|
|||
//generate signing info (statically)
|
|||
-(void)generateSigningInfo:(SecCSFlags)flags; |
|||
|
|||
/* the following methods are not invoked automatically
|
|||
as such, if you code has to manually invoke them if you want this info |
|||
*/ |
|||
|
|||
//generate hash
|
|||
// algo: sha256
|
|||
-(void)generateHash; |
|||
|
|||
//generate id
|
|||
// either signing id, or sha256 hash
|
|||
-(void)generateIdentifier; |
|||
|
|||
@end |
|||
|
|||
#endif |
@ -0,0 +1,25 @@ |
|||
// |
|||
// HandleSwitchTo.swift |
|||
// RSwitch |
|||
// |
|||
// Created by hrbrmstr on 8/25/19. |
|||
// Copyright ยฉ 2019 Bob Rudis. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
|
|||
import Foundation |
|||
import Cocoa |
|||
|
|||
extension AppDelegate { |
|||
|
|||
@objc func switch_to(_ sender: NSMenuItem?) { |
|||
|
|||
let app = sender!.representedObject as! NSRunningApplication |
|||
|
|||
app.activate(options: NSApplication.ActivationOptions.activateIgnoringOtherApps) |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>com.apple.security.get-task-allow</key> |
|||
<true/> |
|||
</dict> |
|||
</plist> |
@ -0,0 +1 @@ |
|||
SUCCESS |
@ -0,0 +1 @@ |
|||
{"":{"dependencies":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/RSwitch-master.d","diagnostics":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/RSwitch-master.dia","swift-dependencies":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/RSwitch-master.swiftdeps"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/AboutViewController.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AboutViewController.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AboutViewController.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Alerts.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Alerts.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Alerts.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/AppDelegate.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AppDelegate.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AppDelegate.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Bundle.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Bundle.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Bundle.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/DownloadRStudio.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadRStudio.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadRStudio.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/DownloadTarball.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadTarball.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadTarball.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/HandleSwitch.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleSwitch.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleSwitch.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/HandleUpdate.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleUpdate.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleUpdate.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Menu.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Menu.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Menu.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Notify.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Notify.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Notify.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/String+Version.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/String+Version.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/String+Version.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Utils.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Utils.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Utils.o"},"/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/ViewController.swift":{"llvm-bc":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/ViewController.bc","object":"/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/ViewController.o"}} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,4 @@ |
|||
version: "Apple Swift version 5.1 (swiftlang-1100.0.270.6 clang-1100.0.32.1)" |
|||
options: "31f9dde5ec8ab8a7473738363610d79b" |
|||
build_time: [1566730886, 39869000] |
|||
inputs: |
@ -0,0 +1,4 @@ |
|||
version: "Apple Swift version 5.1 (swiftlang-1100.0.270.6 clang-1100.0.32.1)" |
|||
options: "31f9dde5ec8ab8a7473738363610d79b" |
|||
build_time: [1566730710, 120239000] |
|||
inputs: |
@ -0,0 +1,4 @@ |
|||
version: "Apple Swift version 5.1 (swiftlang-1100.0.270.6 clang-1100.0.32.1)" |
|||
options: "31f9dde5ec8ab8a7473738363610d79b" |
|||
build_time: [1566730886, 39869000] |
|||
inputs: |
@ -0,0 +1,13 @@ |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleSwitch.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/HandleUpdate.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadTarball.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AboutViewController.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Bundle.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Notify.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/DownloadRStudio.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Menu.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Alerts.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/ViewController.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/AppDelegate.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/String+Version.o |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/build/RSwitch.build/Release/RSwitch.build/Objects-normal/x86_64/Utils.o |
@ -0,0 +1,13 @@ |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/HandleSwitch.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/HandleUpdate.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/DownloadTarball.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/AboutViewController.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Bundle.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Notify.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/DownloadRStudio.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Menu.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Alerts.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/ViewController.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/AppDelegate.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/String+Version.swift |
|||
/Users/hrbrmstr/Development/rswitch/RSwitch/RSwitch/swift/Utils.swift |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>com.apple.security.get-task-allow</key> |
|||
<true/> |
|||
</dict> |
|||
</plist> |
Binary file not shown.
@ -0,0 +1,10 @@ |
|||
#!/bin/sh |
|||
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null |
|||
if [ $? != 0 ] ; then |
|||
# print error to STDERR |
|||
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 |
|||
exit 1 |
|||
fi |
|||
# This output is used by Xcode 'outputs' to avoid re-running this script phase. |
|||
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}" |
|||
|
@ -0,0 +1 @@ |
|||
{"case-sensitive":"false","roots":[],"version":0} |
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@ |
|||
name: "RSwitch" |
|||
navbar: |
|||
title: "RSwitch" |
|||
left: |
|||
- text: "Use" |
|||
href: index.html |
|||
- text: "Develop" |
|||
href: develop.html |
|||
- text: "Acknowledgements" |
|||
href: acknowledgements.html |
|||
- text: "Landing Page" |
|||
href: "https://rud.is/rswitch" |
|||
output: |
|||
html_document: |
|||
toc: true |
|||
theme: darkly |
|||
include: |
|||
after_body: footer.html |
@ -0,0 +1,362 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"> |
|||
|
|||
<head> |
|||
|
|||
<meta charset="utf-8" /> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|||
<meta name="generator" content="pandoc" /> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" /> |
|||
|
|||
|
|||
|
|||
|
|||
<title>Acknowledgements</title> |
|||
|
|||
<script src="site_libs/jquery-1.11.3/jquery.min.js"></script> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
|||
<link href="site_libs/bootstrap-3.3.5/css/darkly.min.css" rel="stylesheet" /> |
|||
<script src="site_libs/bootstrap-3.3.5/js/bootstrap.min.js"></script> |
|||
<script src="site_libs/bootstrap-3.3.5/shim/html5shiv.min.js"></script> |
|||
<script src="site_libs/bootstrap-3.3.5/shim/respond.min.js"></script> |
|||
<script src="site_libs/navigation-1.1/tabsets.js"></script> |
|||
<link href="site_libs/highlightjs-9.12.0/default.css" rel="stylesheet" /> |
|||
<script src="site_libs/highlightjs-9.12.0/highlight.js"></script> |
|||
|
|||
<style type="text/css">code{white-space: pre;}</style> |
|||
<style type="text/css"> |
|||
pre:not([class]) { |
|||
background-color: white; |
|||
} |
|||
</style> |
|||
<script type="text/javascript"> |
|||
if (window.hljs) { |
|||
hljs.configure({languages: []}); |
|||
hljs.initHighlightingOnLoad(); |
|||
if (document.readyState && document.readyState === "complete") { |
|||
window.setTimeout(function() { hljs.initHighlighting(); }, 0); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
|
|||
<style type="text/css"> |
|||
h1 { |
|||
font-size: 34px; |
|||
} |
|||
h1.title { |
|||
font-size: 38px; |
|||
} |
|||
h2 { |
|||
font-size: 30px; |
|||
} |
|||
h3 { |
|||
font-size: 24px; |
|||
} |
|||
h4 { |
|||
font-size: 18px; |
|||
} |
|||
h5 { |
|||
font-size: 16px; |
|||
} |
|||
h6 { |
|||
font-size: 12px; |
|||
} |
|||
.table th:not([align]) { |
|||
text-align: left; |
|||
} |
|||
</style> |
|||
|
|||
|
|||
|
|||
|
|||
<style type = "text/css"> |
|||
.main-container { |
|||
max-width: 940px; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
code { |
|||
color: inherit; |
|||
background-color: rgba(0, 0, 0, 0.04); |
|||
} |
|||
img { |
|||
max-width:100%; |
|||
height: auto; |
|||
} |
|||
.tabbed-pane { |
|||
padding-top: 12px; |
|||
} |
|||
.html-widget { |
|||
margin-bottom: 20px; |
|||
} |
|||
button.code-folding-btn:focus { |
|||
outline: none; |
|||
} |
|||
summary { |
|||
display: list-item; |
|||
} |
|||
</style> |
|||
|
|||
|
|||
<style type="text/css"> |
|||
/* padding for bootstrap navbar */ |
|||
body { |
|||
padding-top: 60px; |
|||
padding-bottom: 40px; |
|||
} |
|||
/* offset scroll position for anchor links (for fixed navbar) */ |
|||
.section h1 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h2 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h3 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h4 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h5 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h6 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.dropdown-submenu { |
|||
position: relative; |
|||
} |
|||
.dropdown-submenu>.dropdown-menu { |
|||
top: 0; |
|||
left: 100%; |
|||
margin-top: -6px; |
|||
margin-left: -1px; |
|||
border-radius: 0 6px 6px 6px; |
|||
} |
|||
.dropdown-submenu:hover>.dropdown-menu { |
|||
display: block; |
|||
} |
|||
.dropdown-submenu>a:after { |
|||
display: block; |
|||
content: " "; |
|||
float: right; |
|||
width: 0; |
|||
height: 0; |
|||
border-color: transparent; |
|||
border-style: solid; |
|||
border-width: 5px 0 5px 5px; |
|||
border-left-color: #cccccc; |
|||
margin-top: 5px; |
|||
margin-right: -10px; |
|||
} |
|||
.dropdown-submenu:hover>a:after { |
|||
border-left-color: #ffffff; |
|||
} |
|||
.dropdown-submenu.pull-left { |
|||
float: none; |
|||
} |
|||
.dropdown-submenu.pull-left>.dropdown-menu { |
|||
left: -100%; |
|||
margin-left: 10px; |
|||
border-radius: 6px 0 6px 6px; |
|||
} |
|||
</style> |
|||
|
|||
<script> |
|||
// manage active state of menu based on current page |
|||
$(document).ready(function () { |
|||
// active menu anchor |
|||
href = window.location.pathname |
|||
href = href.substr(href.lastIndexOf('/') + 1) |
|||
if (href === "") |
|||
href = "index.html"; |
|||
var menuAnchor = $('a[href="' + href + '"]'); |
|||
|
|||
// mark it active |
|||
menuAnchor.parent().addClass('active'); |
|||
|
|||
// if it's got a parent navbar menu mark it active as well |
|||
menuAnchor.closest('li.dropdown').addClass('active'); |
|||
}); |
|||
</script> |
|||
|
|||
<!-- tabsets --> |
|||
|
|||
<style type="text/css"> |
|||
.tabset-dropdown > .nav-tabs { |
|||
display: inline-table; |
|||
max-height: 500px; |
|||
min-height: 44px; |
|||
overflow-y: auto; |
|||
background: white; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li.active:before { |
|||
content: "๎"; |
|||
font-family: 'Glyphicons Halflings'; |
|||
display: inline-block; |
|||
padding: 10px; |
|||
border-right: 1px solid #ddd; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before { |
|||
content: ""; |
|||
border: none; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open:before { |
|||
content: "๎"; |
|||
font-family: 'Glyphicons Halflings'; |
|||
display: inline-block; |
|||
padding: 10px; |
|||
border-right: 1px solid #ddd; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li.active { |
|||
display: block; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li > a, |
|||
.tabset-dropdown > .nav-tabs > li > a:focus, |
|||
.tabset-dropdown > .nav-tabs > li > a:hover { |
|||
border: none; |
|||
display: inline-block; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open > li { |
|||
display: block; |
|||
float: none; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li { |
|||
display: none; |
|||
} |
|||
</style> |
|||
|
|||
<!-- code folding --> |
|||
|
|||
|
|||
|
|||
|
|||
</head> |
|||
|
|||
<body> |
|||
|
|||
|
|||
<div class="container-fluid main-container"> |
|||
|
|||
|
|||
|
|||
|
|||
<div class="navbar navbar-default navbar-fixed-top" role="navigation"> |
|||
<div class="container"> |
|||
<div class="navbar-header"> |
|||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
</button> |
|||
<a class="navbar-brand" href="index.html">RSwitch</a> |
|||
</div> |
|||
<div id="navbar" class="navbar-collapse collapse"> |
|||
<ul class="nav navbar-nav"> |
|||
<li> |
|||
<a href="index.html">Use</a> |
|||
</li> |
|||
<li> |
|||
<a href="develop.html">Develop</a> |
|||
</li> |
|||
<li> |
|||
<a href="acknowledgements.html">Acknowledgements</a> |
|||
</li> |
|||
<li> |
|||
<a href="https://rud.is/rswitch">Landing Page</a> |
|||
</li> |
|||
</ul> |
|||
<ul class="nav navbar-nav navbar-right"> |
|||
|
|||
</ul> |
|||
</div><!--/.nav-collapse --> |
|||
</div><!--/.container --> |
|||
</div><!--/.navbar --> |
|||
|
|||
<div class="fluid-row" id="header"> |
|||
|
|||
|
|||
|
|||
<h1 class="title toc-ignore">Acknowledgements</h1> |
|||
|
|||
</div> |
|||
|
|||
|
|||
<p>RSwitch wasnโt my idea. Itโs been around forever on the <a href="http://mac.r-project.org/">R for macOS Developerโs Page</a> but stopped working on Catalina since it hadnโt been updated in ages, was only 32-bit (which is a no-go for Catalina), and had no available source code to modify.</p> |
|||
<p>Despite having found and old-old copy of the source code by hacking URLs via the Internet Archive, none of that code was used to make this incarnation of RSwitch.</p> |
|||
<p>RSwitch uses three external frameworks to accomplish its tasks:</p> |
|||
<ul> |
|||
<li><a href="https://github.com/scinfu/SwiftSoup">SwiftSoup</a> by Nabil Chatbi</li> |
|||
<li><a href="https://github.com/objective-see/ProcInfo">ProcInfo</a> by the infamous Patrick Wardle</li> |
|||
<li><a href="https://github.com/DragonCherry/VersionCompare/">VersionCompare</a> by DragonCherry</li> |
|||
</ul> |
|||
<p>The current (but, likely not final) app icon and menubar icon is based on the <a href="https://thenounproject.com/search/?q=dial&i=866019#">โdialโ Noun Project font icon</a> created by Icon Mark.</p> |
|||
|
|||
<hr noshade size=1/> |
|||
<p>Copyright © 2019 Bob Rudis. All rights reserved.</p> |
|||
|
|||
|
|||
|
|||
</div> |
|||
|
|||
<script> |
|||
|
|||
// add bootstrap table styles to pandoc tables |
|||
function bootstrapStylePandocTables() { |
|||
$('tr.header').parent('thead').parent('table').addClass('table table-condensed'); |
|||
} |
|||
$(document).ready(function () { |
|||
bootstrapStylePandocTables(); |
|||
}); |
|||
|
|||
|
|||
</script> |
|||
|
|||
<!-- tabsets --> |
|||
|
|||
<script> |
|||
$(document).ready(function () { |
|||
window.buildTabsets("TOC"); |
|||
}); |
|||
|
|||
$(document).ready(function () { |
|||
$('.tabset-dropdown > .nav-tabs > li').click(function () { |
|||
$(this).parent().toggleClass('nav-tabs-open') |
|||
}); |
|||
}); |
|||
</script> |
|||
|
|||
<!-- code folding --> |
|||
|
|||
|
|||
<!-- dynamically load mathjax for compatibility with self-contained --> |
|||
<script> |
|||
(function () { |
|||
var script = document.createElement("script"); |
|||
script.type = "text/javascript"; |
|||
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; |
|||
document.getElementsByTagName("head")[0].appendChild(script); |
|||
})(); |
|||
</script> |
|||
|
|||
</body> |
|||
</html> |
After Width: | Height: | Size: 109 KiB |
@ -0,0 +1,376 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"> |
|||
|
|||
<head> |
|||
|
|||
<meta charset="utf-8" /> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|||
<meta name="generator" content="pandoc" /> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" /> |
|||
|
|||
|
|||
|
|||
|
|||
<title>Developing RSwitch</title> |
|||
|
|||
<script src="site_libs/jquery-1.11.3/jquery.min.js"></script> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
|||
<link href="site_libs/bootstrap-3.3.5/css/darkly.min.css" rel="stylesheet" /> |
|||
<script src="site_libs/bootstrap-3.3.5/js/bootstrap.min.js"></script> |
|||
<script src="site_libs/bootstrap-3.3.5/shim/html5shiv.min.js"></script> |
|||
<script src="site_libs/bootstrap-3.3.5/shim/respond.min.js"></script> |
|||
<script src="site_libs/navigation-1.1/tabsets.js"></script> |
|||
<link href="site_libs/highlightjs-9.12.0/default.css" rel="stylesheet" /> |
|||
<script src="site_libs/highlightjs-9.12.0/highlight.js"></script> |
|||
|
|||
<style type="text/css">code{white-space: pre;}</style> |
|||
<style type="text/css"> |
|||
pre:not([class]) { |
|||
background-color: white; |
|||
} |
|||
</style> |
|||
<script type="text/javascript"> |
|||
if (window.hljs) { |
|||
hljs.configure({languages: []}); |
|||
hljs.initHighlightingOnLoad(); |
|||
if (document.readyState && document.readyState === "complete") { |
|||
window.setTimeout(function() { hljs.initHighlighting(); }, 0); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
|
|||
<style type="text/css"> |
|||
h1 { |
|||
font-size: 34px; |
|||
} |
|||
h1.title { |
|||
font-size: 38px; |
|||
} |
|||
h2 { |
|||
font-size: 30px; |
|||
} |
|||
h3 { |
|||
font-size: 24px; |
|||
} |
|||
h4 { |
|||
font-size: 18px; |
|||
} |
|||
h5 { |
|||
font-size: 16px; |
|||
} |
|||
h6 { |
|||
font-size: 12px; |
|||
} |
|||
.table th:not([align]) { |
|||
text-align: left; |
|||
} |
|||
</style> |
|||
|
|||
|
|||
|
|||
|
|||
<style type = "text/css"> |
|||
.main-container { |
|||
max-width: 940px; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
code { |
|||
color: inherit; |
|||
background-color: rgba(0, 0, 0, 0.04); |
|||
} |
|||
img { |
|||
max-width:100%; |
|||
height: auto; |
|||
} |
|||
.tabbed-pane { |
|||
padding-top: 12px; |
|||
} |
|||
.html-widget { |
|||
margin-bottom: 20px; |
|||
} |
|||
button.code-folding-btn:focus { |
|||
outline: none; |
|||
} |
|||
summary { |
|||
display: list-item; |
|||
} |
|||
</style> |
|||
|
|||
|
|||
<style type="text/css"> |
|||
/* padding for bootstrap navbar */ |
|||
body { |
|||
padding-top: 60px; |
|||
padding-bottom: 40px; |
|||
} |
|||
/* offset scroll position for anchor links (for fixed navbar) */ |
|||
.section h1 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h2 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h3 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h4 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h5 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.section h6 { |
|||
padding-top: 65px; |
|||
margin-top: -65px; |
|||
} |
|||
.dropdown-submenu { |
|||
position: relative; |
|||
} |
|||
.dropdown-submenu>.dropdown-menu { |
|||
top: 0; |
|||
left: 100%; |
|||
margin-top: -6px; |
|||
margin-left: -1px; |
|||
border-radius: 0 6px 6px 6px; |
|||
} |
|||
.dropdown-submenu:hover>.dropdown-menu { |
|||
display: block; |
|||
} |
|||
.dropdown-submenu>a:after { |
|||
display: block; |
|||
content: " "; |
|||
float: right; |
|||
width: 0; |
|||
height: 0; |
|||
border-color: transparent; |
|||
border-style: solid; |
|||
border-width: 5px 0 5px 5px; |
|||
border-left-color: #cccccc; |
|||
margin-top: 5px; |
|||
margin-right: -10px; |
|||
} |
|||
.dropdown-submenu:hover>a:after { |
|||
border-left-color: #ffffff; |
|||
} |
|||
.dropdown-submenu.pull-left { |
|||
float: none; |
|||
} |
|||
.dropdown-submenu.pull-left>.dropdown-menu { |
|||
left: -100%; |
|||
margin-left: 10px; |
|||
border-radius: 6px 0 6px 6px; |
|||
} |
|||
</style> |
|||
|
|||
<script> |
|||
// manage active state of menu based on current page |
|||
$(document).ready(function () { |
|||
// active menu anchor |
|||
href = window.location.pathname |
|||
href = href.substr(href.lastIndexOf('/') + 1) |
|||
if (href === "") |
|||
href = "index.html"; |
|||
var menuAnchor = $('a[href="' + href + '"]'); |
|||
|
|||
// mark it active |
|||
menuAnchor.parent().addClass('active'); |
|||
|
|||
// if it's got a parent navbar menu mark it active as well |
|||
menuAnchor.closest('li.dropdown').addClass('active'); |
|||
}); |
|||
</script> |
|||
|
|||
<!-- tabsets --> |
|||
|
|||
<style type="text/css"> |
|||
.tabset-dropdown > .nav-tabs { |
|||
display: inline-table; |
|||
max-height: 500px; |
|||
min-height: 44px; |
|||
overflow-y: auto; |
|||
background: white; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li.active:before { |
|||
content: "๎"; |
|||
font-family: 'Glyphicons Halflings'; |
|||
display: inline-block; |
|||
padding: 10px; |
|||
border-right: 1px solid #ddd; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before { |
|||
content: ""; |
|||
border: none; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open:before { |
|||
content: "๎"; |
|||
font-family: 'Glyphicons Halflings'; |
|||
display: inline-block; |
|||
padding: 10px; |
|||
border-right: 1px solid #ddd; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li.active { |
|||
display: block; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li > a, |
|||
.tabset-dropdown > .nav-tabs > li > a:focus, |
|||
.tabset-dropdown > .nav-tabs > li > a:hover { |
|||
border: none; |
|||
display: inline-block; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs.nav-tabs-open > li { |
|||
display: block; |
|||
float: none; |
|||
} |
|||
|
|||
.tabset-dropdown > .nav-tabs > li { |
|||
display: none; |
|||
} |
|||
</style> |
|||
|
|||
<!-- code folding --> |
|||
|
|||
|
|||
|
|||
|
|||
</head> |
|||
|
|||
<body> |
|||
|
|||
|
|||
<div class="container-fluid main-container"> |
|||
|
|||
|
|||
|
|||
|
|||
<div class="navbar navbar-default navbar-fixed-top" role="navigation"> |
|||
<div class="container"> |
|||
<div class="navbar-header"> |
|||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
</button> |
|||
<a class="navbar-brand" href="index.html">RSwitch</a> |
|||
</div> |
|||
<div id="navbar" class="navbar-collapse collapse"> |
|||
<ul class="nav navbar-nav"> |
|||
<li> |
|||
<a href="index.html">Use</a> |
|||
</li> |
|||
<li> |
|||
<a href="develop.html">Develop</a> |
|||
</li> |
|||
<li> |
|||
<a href="acknowledgements.html">Acknowledgements</a> |
|||
</li> |
|||
<li> |
|||
<a href="https://rud.is/rswitch">Landing Page</a> |
|||
</li> |
|||
</ul> |
|||
<ul class="nav navbar-nav navbar-right"> |
|||
|
|||
</ul> |
|||
</div><!--/.nav-collapse --> |
|||
</div><!--/.container --> |
|||
</div><!--/.navbar --> |
|||
|
|||
<div class="fluid-row" id="header"> |
|||
|
|||
|
|||
|
|||
<h1 class="title toc-ignore">Developing RSwitch</h1> |
|||
|
|||
</div> |
|||
|
|||
|
|||
<p>Contributions to RSwitch are welcome and encouraged!</p> |
|||
<p>You will need:</p> |
|||
<ul> |
|||
<li><a href="https://developer.apple.com/xcode/">Xcode 11</a> (still in beta as of this writing)</li> |
|||
<li>Familiarity with <a href="https://swift.org/blog/swift-5-released/">Swift 5.x</a></li> |
|||
<li>Tolerance to use one of the following social coding sites: |
|||
<ul> |
|||
<li><a href="https://git.rud.is/hrbrmstr/RSwitch">My self-hosted Gitea instance</a></li> |
|||
<li><a href="https://git.sr.ht/~hrbrmstr/RSwitch">SourceHut</a></li> |
|||
<li><a href="https://gitlab.com/hrbrmstr/RSwitch">GitLab</a></li> |
|||
<li><a href="https://bitbucket.com/hrbrmstr/RSwitch">Bitbucket</a></li> |
|||
<li><a href="https://github.com/hrbrmstr/RSwitch">GitHub</a></li> |
|||
</ul></li> |
|||
<li>The ability to use <a href="https://git-scm.com/book/ms/v2/Git-Tools-Signing-Your-Work">signed git commits</a></li> |
|||
</ul> |
|||
<p>To work on anything related to RSwitch:</p> |
|||
<ul> |
|||
<li>claim or file a new issue</li> |
|||
<li>get concensus on the feature/change</li> |
|||
<li>develop and test on a fork & branch</li> |
|||
<li>share a copy of the app back to the folks monitoring the issue</li> |
|||
<li>submit a PR once the feature/change has been finalized</li> |
|||
</ul> |
|||
|
|||
<hr noshade size=1/> |
|||
<p>Copyright © 2019 Bob Rudis. All rights reserved.</p> |
|||
|
|||
|
|||
|
|||
</div> |
|||
|
|||
<script> |
|||
|
|||
// add bootstrap table styles to pandoc tables |
|||
function bootstrapStylePandocTables() { |
|||
$('tr.header').parent('thead').parent('table').addClass('table table-condensed'); |
|||
} |
|||
$(document).ready(function () { |
|||
bootstrapStylePandocTables(); |
|||
}); |
|||
|
|||
|
|||
</script> |
|||
|
|||
<!-- tabsets --> |
|||
|
|||
<script> |
|||
$(document).ready(function () { |
|||
window.buildTabsets("TOC"); |
|||
}); |
|||
|
|||
$(document).ready(function () { |
|||
$('.tabset-dropdown > .nav-tabs > li').click(function () { |
|||
$(this).parent().toggleClass('nav-tabs-open') |
|||
}); |
|||
}); |
|||
</script> |
|||
|
|||
<!-- code folding --> |
|||
|
|||
|
|||
|