diff --git a/Mist/Helpers/Codesigner.swift b/Mist/Helpers/Codesigner.swift index 02fc889..f6b3227 100644 --- a/Mist/Helpers/Codesigner.swift +++ b/Mist/Helpers/Codesigner.swift @@ -19,10 +19,10 @@ struct Codesigner { /// - Throws: A `MistError` if the command failed to execute. static func sign(_ url: URL, identity: String) async throws { let arguments: [String] = ["codesign", "--sign", identity, url.path] - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/DirectoryRemover.swift b/Mist/Helpers/DirectoryRemover.swift index dc2b110..ca9af73 100644 --- a/Mist/Helpers/DirectoryRemover.swift +++ b/Mist/Helpers/DirectoryRemover.swift @@ -29,7 +29,7 @@ struct DirectoryRemover { let response: HelperToolCommandResponse = try await client.sendMessage(request, to: XPCRoute.commandRoute) guard response.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: response.terminationStatus, string: response.standardError) + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/DiskImageCreator.swift b/Mist/Helpers/DiskImageCreator.swift index 7608642..d8d2fba 100644 --- a/Mist/Helpers/DiskImageCreator.swift +++ b/Mist/Helpers/DiskImageCreator.swift @@ -59,10 +59,10 @@ struct DiskImageCreator { private static func create(_ url: URL, with arguments: [String]) async throws { try await DirectoryRemover.remove(url) - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/DiskImageMounter.swift b/Mist/Helpers/DiskImageMounter.swift index ecd5645..d196c4a 100644 --- a/Mist/Helpers/DiskImageMounter.swift +++ b/Mist/Helpers/DiskImageMounter.swift @@ -26,10 +26,10 @@ struct DiskImageMounter { } let arguments: [String] = ["hdiutil", "attach", url.path, "-noverify", "-nobrowse", "-mountpoint", mountPoint.path] - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/DiskImageUnmounter.swift b/Mist/Helpers/DiskImageUnmounter.swift index b0cb644..e93982c 100644 --- a/Mist/Helpers/DiskImageUnmounter.swift +++ b/Mist/Helpers/DiskImageUnmounter.swift @@ -18,10 +18,10 @@ struct DiskImageUnmounter { /// - Throws: A `MistError` if the command failed to execute. static func unmount(_ url: URL) async throws { let arguments: [String] = ["hdiutil", "detach", url.path, "-force"] - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/FileAttributesUpdater.swift b/Mist/Helpers/FileAttributesUpdater.swift index 63bd36f..3ee1e29 100644 --- a/Mist/Helpers/FileAttributesUpdater.swift +++ b/Mist/Helpers/FileAttributesUpdater.swift @@ -30,7 +30,7 @@ struct FileAttributesUpdater { let response: HelperToolCommandResponse = try await client.sendMessage(request, to: XPCRoute.commandRoute) guard response.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: response.terminationStatus, string: response.standardError) + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/ISOConverter.swift b/Mist/Helpers/ISOConverter.swift index 57b2094..736ef05 100644 --- a/Mist/Helpers/ISOConverter.swift +++ b/Mist/Helpers/ISOConverter.swift @@ -19,10 +19,10 @@ struct ISOConverter { /// - Throws: An `Error` if the command failed to execute. static func convert(_ source: URL, destination: URL) async throws { let arguments: [String] = ["hdiutil", "convert", source.path, "-format", "UDTO", "-o", destination.path] - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/InstallMediaCreator.swift b/Mist/Helpers/InstallMediaCreator.swift index e65ddf9..7f20f20 100644 --- a/Mist/Helpers/InstallMediaCreator.swift +++ b/Mist/Helpers/InstallMediaCreator.swift @@ -25,7 +25,7 @@ struct InstallMediaCreator { let response: HelperToolCommandResponse = try await client.sendMessage(request, to: XPCRoute.commandRoute) guard response.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: response.terminationStatus, string: response.standardError) + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/InstallerCreator.swift b/Mist/Helpers/InstallerCreator.swift index 263f6ba..f91e11c 100644 --- a/Mist/Helpers/InstallerCreator.swift +++ b/Mist/Helpers/InstallerCreator.swift @@ -59,7 +59,7 @@ struct InstallerCreator { let response: HelperToolCommandResponse = try await client.sendMessage(request, to: XPCRoute.commandRoute) guard response.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: response.terminationStatus, string: response.standardError) + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/PackageCreator.swift b/Mist/Helpers/PackageCreator.swift index 8909f24..432a7d3 100644 --- a/Mist/Helpers/PackageCreator.swift +++ b/Mist/Helpers/PackageCreator.swift @@ -47,10 +47,10 @@ struct PackageCreator { private static func create(_ url: URL, with arguments: [String]) async throws { try await DirectoryRemover.remove(url) - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments) - guard result.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: result.terminationStatus, string: result.standardError) + guard response.terminationStatus == 0 else { + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Helpers/PrivilegedHelperTool.swift b/Mist/Helpers/PrivilegedHelperTool.swift index a20df32..6666211 100644 --- a/Mist/Helpers/PrivilegedHelperTool.swift +++ b/Mist/Helpers/PrivilegedHelperTool.swift @@ -23,9 +23,9 @@ struct PrivilegedHelperTool { do { // launchctl service is loaded let arguments: [String] = ["launchctl", "print", "system/\(String.helperIdentifier)"] - let result: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor().execute(arguments) + let response: HelperToolCommandResponse = try ShellExecutor().execute(arguments) - guard result.terminationStatus == 0 else { + guard response.terminationStatus == 0 else { return false } diff --git a/Mist/Helpers/ProcessKiller.swift b/Mist/Helpers/ProcessKiller.swift index 916907e..895c54c 100644 --- a/Mist/Helpers/ProcessKiller.swift +++ b/Mist/Helpers/ProcessKiller.swift @@ -19,7 +19,7 @@ struct ProcessKiller { let response: HelperToolCommandResponse = try await client.sendMessage(request, to: XPCRoute.commandRoute) guard response.terminationStatus == 0 else { - throw MistError.invalidTerminationStatus(status: response.terminationStatus, string: response.standardError) + throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError) } } } diff --git a/Mist/Model/MistError.swift b/Mist/Model/MistError.swift index 9b9c558..3a641b4 100644 --- a/Mist/Model/MistError.swift +++ b/Mist/Model/MistError.swift @@ -16,7 +16,7 @@ enum MistError: Error, Equatable { case invalidDownloadResumeData case invalidFileSize(invalid: UInt64, valid: UInt64) case invalidShasum(invalid: String, valid: String) - case invalidTerminationStatus(status: Int32, string: String?) + case invalidTerminationStatus(status: Int32, output: String?, error: String?) case invalidURL(_ url: String) case maximumRetriesReached case missingFileAttributes @@ -42,12 +42,20 @@ enum MistError: Error, Equatable { return "Invalid File Size: '\(invalid)', should be: '\(valid)'" case .invalidShasum(let invalid, let valid): return "Invalid Shasum: '\(invalid)', should be: '\(valid)'" - case .invalidTerminationStatus(let status, let string): - if let string: String = string { - return "Invalid Termination Status '\(status)': \(string)" - } else { - return "Invalid Termination Status: \(status)" + case .invalidTerminationStatus(let status, let output, let error): + var string: String = "Invalid Termination Status: \(status)" + + if let output: String = output, + !output.isEmpty { + string += "\n\n\(output)" } + + if let error: String = error, + !error.isEmpty { + string += "\n\n\(error)" + } + + return string case .invalidURL(let url): return "Invalid URL: '\(url)'" case .maximumRetriesReached: diff --git a/Mist/Views/Download/DownloadView.swift b/Mist/Views/Download/DownloadView.swift index edc96bd..17db894 100644 --- a/Mist/Views/Download/DownloadView.swift +++ b/Mist/Views/Download/DownloadView.swift @@ -166,7 +166,7 @@ struct DownloadView: View { switch error { case .userCancelled: return true - case .invalidTerminationStatus(let status, _): + case .invalidTerminationStatus(let status, _, _): // SIGTERM triggered via Privileged Helper Tool due to user cancellation guard status == 15 else { diff --git a/MistHelperTool/Info.plist b/MistHelperTool/Info.plist index 1a3746f..df540ce 100644 --- a/MistHelperTool/Info.plist +++ b/MistHelperTool/Info.plist @@ -3,7 +3,7 @@ BuildHash - a9b37eeef3f02041cf0206471219c999c03928fa8d1f3c83475e74e8fec8e196 + 185811c82f555c98602ef205e6722bf512e5f4c4e882eb4c719aafc45d467f53 CFBundleIdentifier com.ninxsoft.mist.helper CFBundleInfoDictionaryVersion diff --git a/MistHelperTool/main.swift b/MistHelperTool/main.swift index 4a899ef..9f11360 100644 --- a/MistHelperTool/main.swift +++ b/MistHelperTool/main.swift @@ -61,7 +61,7 @@ struct HelperToolCommandRunner { ShellExecutor.shared.terminate() return HelperToolCommandResponse(terminationStatus: 0, standardOutput: nil, standardError: nil) default: - let response: (terminationStatus: Int32, standardOutput: String?, standardError: String?) = try ShellExecutor.shared.execute(request.arguments, environment: request.environment) + let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(request.arguments, environment: request.environment) return HelperToolCommandResponse(terminationStatus: response.terminationStatus, standardOutput: response.standardOutput, standardError: response.standardError) } } diff --git a/Shared/ShellExecutor.swift b/Shared/ShellExecutor.swift index 1b8c0c6..ae0176d 100644 --- a/Shared/ShellExecutor.swift +++ b/Shared/ShellExecutor.swift @@ -27,7 +27,7 @@ class ShellExecutor: NSObject { _ arguments: [String], environment variables: [String: String] = [:], currentDirectoryPath: String? = nil - ) throws -> (terminationStatus: Int32, standardOutput: String?, standardError: String?) { + ) throws -> HelperToolCommandResponse { let outputPipe: Pipe = Pipe() let errorPipe: Pipe = Pipe() process = Process() @@ -56,7 +56,7 @@ class ShellExecutor: NSObject { let errorData: Data = errorPipe.fileHandleForReading.readDataToEndOfFile() let standardError: String? = String(data: errorData, encoding: .utf8) let terminationStatus: Int32 = process.terminationStatus - return (terminationStatus: terminationStatus, standardOutput: standardOutput, standardError: (standardError ?? "").isEmpty ? nil : standardError) + return HelperToolCommandResponse(terminationStatus: terminationStatus, standardOutput: standardOutput, standardError: standardError) } func terminate() {