Clover.app v1.08 Beta

Fixes and improvement for the Disable Sleep Proxy client and the save NVRAM  functions. Other small fixes.
This commit is contained in:
vectorsigma72 2019-11-21 00:13:41 +01:00
parent d447228625
commit c822eefd22
5 changed files with 175 additions and 113 deletions

View File

@ -855,7 +855,7 @@
CODE_SIGN_ENTITLEMENTS = Clover/Clover.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.07;
CURRENT_PROJECT_VERSION = 1.08;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
@ -869,7 +869,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
);
MARKETING_VERSION = 1.07;
MARKETING_VERSION = 1.08;
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
@ -884,7 +884,7 @@
CODE_SIGN_ENTITLEMENTS = Clover/Clover.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.07;
CURRENT_PROJECT_VERSION = 1.08;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
@ -898,7 +898,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Clover/Frameworks",
);
MARKETING_VERSION = 1.07;
MARKETING_VERSION = 1.08;
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;

View File

@ -147,6 +147,7 @@ func getMediaName(from diskOrMtp: String) -> String? {
return name
}
/// Get Media Name (kDADiskDescriptionDeviceProtocolKey).
func getDeviceProtocol(from diskOrMtp: String) -> String {
var prot : String = kNotAvailable
@ -343,6 +344,7 @@ func isMountPoint(path: String) -> Bool {
return (mtp != nil)
}
/// mount the given disk object. The path for the mount point is optional.
func mount(disk bsdName: String, at path: String?) {
var disk : String = bsdName
if disk.hasPrefix("disk") || disk.hasPrefix("/dev/disk") {
@ -401,6 +403,7 @@ func mount(disk bsdName: String, at path: String?) {
}
}
/// mount the given disk object. The path for the mount point is optional. Code executed in a closure that return a boolean value.
func mount(disk bsdName: String,
at path: String?,
reply: @escaping (Bool) -> ()) {
@ -467,6 +470,7 @@ func mount(disk bsdName: String,
reply(false)
}
/// unmount the given disk object or mount point. force used to kill any pid is using the disk.
func umount(disk diskOrMtp: String, force: Bool) {
let disk : String = diskOrMtp
let mtp : String? = getMountPoint(from: diskOrMtp)
@ -517,6 +521,7 @@ func umount(disk diskOrMtp: String, force: Bool) {
}
}
/// unmount the given disk object or mount point. force used to kill any pid is using the disk. Code executed in a closure that return a boolean value.
func umount(disk diskOrMtp: String,
force: Bool,
reply: @escaping (Bool) -> ()) {
@ -574,6 +579,7 @@ func umount(disk diskOrMtp: String,
reply(false)
}
/// Helper function for the mount/umout call back
fileprivate func printDAReturn(r: DAReturn) -> String {
switch Int(r) {
case kDAReturnError:
@ -603,5 +609,4 @@ fileprivate func printDAReturn(r: DAReturn) -> String {
default:
return "Unknown"
}
}

View File

@ -392,7 +392,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
let nvdata = nvram.object(forKey: key) as? Data
value = String(decoding: nvdata ?? Data(), as: UTF8.self)
}
self.disbaleSleepProxyButton.state = (value == "true") ? .on : .off
self.makeRootRWButton.state = (value == "true") ? .on : .off
}
}

View File

@ -9,11 +9,16 @@
import Foundation
let fm = FileManager.default
let daemonVersion = "1.0.4"
let daemonVersion = "1.0.7"
let wrapperPath = "/Library/Application Support/Clover/CloverWrapper.sh"
let loginwindow = "/var/root/Library/Preferences/com.apple.loginwindow.plist"
let lh = "/Library/Application Support/Clover/CloverLogOut"
let loginWindowPath = "/var/root/Library/Preferences/com.apple.loginwindow.plist"
let cloverLogOut = "/Library/Application Support/Clover/CloverLogOut"
let cloverDaemonNewPath = "/Library/Application Support/Clover/CloverDaemonNew"
let launchPlistPath = "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist"
let oldLaunchPlistPath = "/Library/LaunchDaemons/com.projectosx.clover.daemon.plist"
func execAttr() -> [FileAttributeKey : Any] {
var attributes = [FileAttributeKey : Any]()
@ -62,46 +67,59 @@ func checkSleepProxyClient(nvram: NSDictionary) {
let mDNSResponderPath = "/System/Library/LaunchDaemons/com.apple.mDNSResponder.plist"
let disableOption = "-DisableSleepProxyClient"
var value = "false"
if let nvdata = nvram.object(forKey: "Clover.DisableSleepProxyClient") as? Data {
let value = String(decoding: nvdata, as: UTF8.self)
value = String(decoding: nvdata, as: UTF8.self)
print("Clover.DisableSleepProxyClient=\(value)")
if !fm.fileExists(atPath: mDNSResponderPath) {
print("Error: cannot found \(mDNSResponderPath)")
return
}
if !fm.isWritableFile(atPath: "/") {
print("Cannot go ahead as / is still read-only at this moment, will try again at power off.")
return
}
// check if enabled or disabled
if let mDNSResponder = NSDictionary(contentsOfFile: mDNSResponderPath) {
if let ProgramArguments = mDNSResponder.object(forKey: "ProgramArguments") as? NSArray {
var index : Int = -1
var serviceDisabled = false
for i in 0..<ProgramArguments.count {
if let arg = ProgramArguments.object(at: i) as? String {
if arg == disableOption {
index = i
serviceDisabled = true
break
}
} else {
print("Clover.DisableSleepProxyClient is not set.")
}
if !fm.fileExists(atPath: mDNSResponderPath) {
print("Error: cannot found \(mDNSResponderPath)")
return
}
if !fm.isWritableFile(atPath: "/") {
print("Cannot go ahead as / is read-only")
return
}
let toDisable : Bool = value == "true"
// check if enabled or disabled
if let mDNSResponder = NSDictionary(contentsOfFile: mDNSResponderPath) {
if let ProgramArguments = mDNSResponder.object(forKey: "ProgramArguments") as? NSArray {
var index : Int = -1
var serviceIsDisabled = false
for i in 0..<ProgramArguments.count {
if let arg = ProgramArguments.object(at: i) as? String {
if arg == disableOption {
index = i
serviceIsDisabled = true
break
}
}
if value == "true" && !serviceDisabled {
print("Trying to disable Sleep Proxy Client service as requested.")
let cmd = "/usr/libexec/PlistBuddy -c \"Add ProgramArguments: string \(disableOption)\" \(mDNSResponderPath)"
}
// no need to do anything if already as user wants.
if toDisable && serviceIsDisabled {
print("Sleep Proxy Client is already disabled.")
return
} else if !toDisable && !serviceIsDisabled {
print("Sleep Proxy Client is already enabled as default.")
return
}
if toDisable {
print("Trying to disable Sleep Proxy Client service.")
let cmd = "/usr/libexec/PlistBuddy -c \"Add ProgramArguments: string \(disableOption)\" \(mDNSResponderPath)"
run(cmd: cmd)
} else {
print("Trying to enable Sleep Proxy Client service as default.")
if index >= 0 {
let cmd = "/usr/libexec/PlistBuddy -c \"delete :ProgramArguments:\(index)\" \(mDNSResponderPath)"
run(cmd: cmd)
} else if value != "true" && serviceDisabled {
print("Trying to enable Sleep Proxy Client service as requested.")
if index >= 0 {
let cmd = "/usr/libexec/PlistBuddy -c \"delete :ProgramArguments:\(index)\" \(mDNSResponderPath)"
run(cmd: cmd)
} else {
print("Bug: cant find the index of '\(disableOption)'.\n")
}
} else {
print("Sleep Proxy Client \(serviceDisabled ? "disabled" : "enabled") as requested.")
}
}
}
@ -109,7 +127,44 @@ func checkSleepProxyClient(nvram: NSDictionary) {
}
func getLogOutHook() -> String? {
return NSDictionary(contentsOfFile: loginwindow)?.object(forKey: "LogoutHook") as? String
return NSDictionary(contentsOfFile: loginWindowPath)?.object(forKey: "LogoutHook") as? String
}
func removeCloverRCScripts() {
if fm.fileExists(atPath: oldLaunchPlistPath) {
print("unloading old CloverDaemon..")
run(cmd: "launchctl unload \(oldLaunchPlistPath)")
try? fm.removeItem(atPath: oldLaunchPlistPath)
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon") {
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon")
}
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice") {
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice")
}
}
let oldRCScripts : [String] = ["/etc/rc.boot.d/10.save_and_rotate_boot_log.local",
"/etc/rc.boot.d/20.mount_ESP.local",
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local.disabled",
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local",
"/etc/rc.clover.lib",
"/etc/rc.shutdown.d/80.save_nvram_plist.local"];
for rc in oldRCScripts {
if fm.fileExists(atPath: rc) {
if !fm.isWritableFile(atPath: "/") {
run(cmd: "mount -uw /")
sleep(2)
}
print("Removing \(rc).")
do {
try fm.removeItem(atPath: rc)
} catch {
print(error)
}
}
}
}
func main() {
@ -135,38 +190,7 @@ func main() {
}
// check if old daemon exist
let oldLaunchDaemon = "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist"
if fm.fileExists(atPath: oldLaunchDaemon) {
print("unloading old CloverDaemon")
run(cmd: "launchctl unload \(oldLaunchDaemon)")
try? fm.removeItem(atPath: oldLaunchDaemon)
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon") {
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon")
}
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice") {
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice")
}
}
let oldRCScripts : [String] = ["/Library/Application Support/Clover/CloverDaemon-stopservice",
"/etc/rc.boot.d/10.save_and_rotate_boot_log.local",
"/etc/rc.boot.d/20.mount_ESP.local",
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local.disabled",
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local",
"/etc/rc.clover.lib",
"/etc/rc.shutdown.d/80.save_nvram_plist.local"];
if fm.fileExists(atPath: "/etc/rc.clover.lib") {
for rc in oldRCScripts {
print("Removing old rc scripts..")
run(cmd: "mount -uw /")
sleep(2)
if fm.fileExists(atPath: rc) {
try? fm.removeItem(atPath: rc)
}
}
}
removeCloverRCScripts()
/*
Clean some lines from clover.daemon.log.
@ -210,8 +234,7 @@ func main() {
}
}
}
// using the logout Hook only if EmuVariableUefiPresent
let loh = getLogOutHook()
@ -220,12 +243,12 @@ func main() {
// if a hook exist and is not our one, then add a wrapper
if (loh != nil) {
if loh! != lh && fm.fileExists(atPath: loh!) {
if loh! != cloverLogOut && fm.fileExists(atPath: loh!) {
let wrapper =
"""
#!/bin/sh
'\(lh)'
'\(cloverLogOut)'
# This file is automatically generated by CloverDaemonNew because
# it has detected you added a logout script somewhere else.
@ -248,10 +271,10 @@ func main() {
print(error)
}
} else {
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(lh)'")
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
}
} else {
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(lh)'")
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
}
if !fm.isWritableFile(atPath: "/") {
@ -263,7 +286,7 @@ func main() {
} else {
// what to do? remove the logout hook if it's our
if (loh != nil) {
if loh! == lh {
if loh! == cloverLogOut {
// it is CloverLogOut
print("Removing CloverLogOut hook as EmuVariable is no longer present.")
run(cmd: "defaults delete com.apple.loginwindow LogoutHook")
@ -305,12 +328,15 @@ func main() {
/*
Clean old nvram.plist user may have in all volumes
Note: never delete in / as this will be done at shut down/restart
if the nvram is correctly saved somewhere else (e.g. in the ESP)
if the nvram is correctly saved somewhere else (e.g. in the ESP).
Also don't delete nvram.plist from external devices as this is not or
shouldn't be our business.
*/
/*
for v in getVolumes() {
let nvramtPath = v.addPath("nvram.plist")
if v != "/" {
if v != "/" && isInternalDevice(diskOrMtp: v) {
if fm.fileExists(atPath: nvramtPath) {
if fm.isDeletableFile(atPath: nvramtPath) {
do {
@ -325,7 +351,7 @@ func main() {
}
}
}
*/
} else {
print("Error: nvram not present in this System.")
}
@ -359,10 +385,11 @@ if CommandLine.arguments.contains("--install") {
launch.setValue("/Library/Logs/CloverEFI/clover.daemon.log", forKey: "StandardErrorPath")
launch.setValue("/Library/Logs/CloverEFI/clover.daemon.log", forKey: "StandardOutPath")
let ProgramArguments = NSArray(object: "/Library/Application Support/Clover/CloverDaemonNew")
let ProgramArguments = NSArray(object: cloverDaemonNewPath)
launch.setValue(ProgramArguments, forKey: "ProgramArguments")
removeCloverRCScripts()
do {
if !fm.fileExists(atPath: "/Library/Application Support/Clover") {
try fm.createDirectory(atPath: "/Library/Application Support/Clover",
@ -370,41 +397,39 @@ if CommandLine.arguments.contains("--install") {
attributes: nil)
}
if fm.fileExists(atPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist") {
try fm.removeItem(atPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
if fm.fileExists(atPath: launchPlistPath) {
try fm.removeItem(atPath: launchPlistPath)
}
if fm.fileExists(atPath: "/Library/Application Support/Clover/\(myName)") {
try fm.removeItem(atPath: "/Library/Application Support/Clover/\(myName)")
if fm.fileExists(atPath: cloverDaemonNewPath) {
try fm.removeItem(atPath: cloverDaemonNewPath)
}
launch.write(toFile: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist",
atomically: true)
launch.write(toFile: launchPlistPath, atomically: true)
try fm.copyItem(atPath: myPath, toPath: "/Library/Application Support/Clover/\(myName)")
try fm.copyItem(atPath: myPath, toPath: cloverDaemonNewPath)
try fm.setAttributes(execAttr(),
ofItemAtPath: "/Library/Application Support/Clover/\(myName)")
ofItemAtPath: cloverDaemonNewPath)
let logouthookSrc = myPath.deletingLastPath.addPath("CloverLogOut")
if fm.fileExists(atPath: lh) {
try fm.removeItem(atPath: lh)
if fm.fileExists(atPath: cloverLogOut) {
try fm.removeItem(atPath: cloverLogOut)
}
if fm.fileExists(atPath: logouthookSrc) {
try fm.copyItem(atPath: logouthookSrc,
toPath: lh)
toPath: cloverLogOut)
try fm.setAttributes(execAttr(),
ofItemAtPath: lh)
ofItemAtPath: cloverLogOut)
}
try fm.setAttributes(launchAttr(),
ofItemAtPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
if fm.fileExists(atPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist") {
run(cmd: "launchctl unload /Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
try fm.setAttributes(launchAttr(), ofItemAtPath: launchPlistPath)
if fm.fileExists(atPath: launchPlistPath) {
run(cmd: "launchctl unload \(launchPlistPath)")
}
run(cmd: "launchctl load /Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
run(cmd: "launchctl start /Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
run(cmd: "launchctl load \(launchPlistPath)")
run(cmd: "launchctl start \(launchPlistPath)")
exit(EXIT_SUCCESS)
} catch {
print(error)
@ -412,13 +437,21 @@ if CommandLine.arguments.contains("--install") {
} else if CommandLine.arguments.contains("--uninstall") {
print("uninstalling daemon...")
do {
if fm.fileExists(atPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist") {
run(cmd: "launchctl unload /Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
try fm.removeItem(atPath: "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist")
if fm.fileExists(atPath: launchPlistPath) {
run(cmd: "launchctl unload \(launchPlistPath)")
try fm.removeItem(atPath: launchPlistPath)
}
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemonNew") {
try fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemonNew")
if fm.fileExists(atPath: cloverDaemonNewPath) {
try fm.removeItem(atPath: cloverDaemonNewPath)
}
if fm.fileExists(atPath: cloverLogOut) {
try fm.removeItem(atPath: cloverLogOut)
}
if fm.fileExists(atPath: wrapperPath) {
try fm.removeItem(atPath: wrapperPath)
}
exit(EXIT_SUCCESS)
} catch {

View File

@ -10,6 +10,7 @@ import Foundation
let cmdVersion = "1.0.2"
let savedNVRAMPath = "/tmp/NVRAM_saved"
let NVRAMSavedToRoot = "/tmp/NVRAM_savedToRoot"
func log(_ str: String) {
let logUrl = URL(fileURLWithPath: "/Library/Logs/CloverEFI/clover.daemon.log")
@ -75,6 +76,16 @@ func saveNVRAM(nvram: NSMutableDictionary, volume: String) {
log("\(error)")
}
}
if fm.fileExists(atPath: NVRAMSavedToRoot) {
do {
try fm.removeItem(atPath: NVRAMSavedToRoot)
} catch {
log("\(error)")
}
}
} else {
try? "".write(toFile: NVRAMSavedToRoot, atomically: false, encoding: .utf8)
}
} else {
log("Error: nvram cannot be saved to \(volume) with UUID: \(uuid).")
@ -110,7 +121,20 @@ func main() {
if fm.fileExists(atPath: savedNVRAMPath) {
if let old = NSDictionary(contentsOfFile: savedNVRAMPath) {
if nvram.isEqual(to: old) {
log("nvram not changed, nothing to do.")
/*
We are going to exit but if the nvram is already saved
and is saved in the ESP, then remove /.nvram.plist
*/
if !fm.fileExists(atPath: NVRAMSavedToRoot) {
if fm.fileExists(atPath: "/nvram.plist") {
do {
try fm.removeItem(atPath: "/nvram.plist")
} catch {
log("\(error)")
}
}
}
log("nvram not changed, nothing to do.") // hope user didn't delete it :-)
log("- CloverLogOut: end at \(now)")
exit(EXIT_SUCCESS)
}