diff --git a/Geranium.xcodeproj/project.pbxproj b/Geranium.xcodeproj/project.pbxproj index 6fc6798..162c6d8 100644 --- a/Geranium.xcodeproj/project.pbxproj +++ b/Geranium.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 7916D9E42B34D9C4008E88F2 /* CurrentlyDisabledDaemonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7916D9E32B34D9C4008E88F2 /* CurrentlyDisabledDaemonView.swift */; }; 7918209A2B31F109007EEC24 /* LogHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791820992B31F109007EEC24 /* LogHelper.swift */; }; 792845532B2C67910021E1FD /* FileCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792845522B2C67910021E1FD /* FileCleaner.swift */; }; 7928455A2B2C80A40021E1FD /* DaemonDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792845592B2C80A40021E1FD /* DaemonDisabler.swift */; }; @@ -51,6 +52,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 7916D9E32B34D9C4008E88F2 /* CurrentlyDisabledDaemonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentlyDisabledDaemonView.swift; sourceTree = ""; }; 791820992B31F109007EEC24 /* LogHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogHelper.swift; sourceTree = ""; }; 792845522B2C67910021E1FD /* FileCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCleaner.swift; sourceTree = ""; }; 792845592B2C80A40021E1FD /* DaemonDisabler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaemonDisabler.swift; sourceTree = ""; }; @@ -225,6 +227,7 @@ isa = PBXGroup; children = ( FAA457282B26668900FC7287 /* DaemonView.swift */, + 7916D9E32B34D9C4008E88F2 /* CurrentlyDisabledDaemonView.swift */, 799615432B34A1930053558E /* DaemonWelcomeView.swift */, 792845592B2C80A40021E1FD /* DaemonDisabler.swift */, ); @@ -383,6 +386,7 @@ buildActionMask = 2147483647; files = ( 7989FD082B34894400FBAB8D /* BookMarkSlider.swift in Sources */, + 7916D9E42B34D9C4008E88F2 /* CurrentlyDisabledDaemonView.swift in Sources */, FAA457122B2661E300FC7287 /* TSUtil.m in Sources */, 7989FD062B3486B100FBAB8D /* CustomMapView.swift in Sources */, FAA457272B26667E00FC7287 /* HomeView.swift in Sources */, diff --git a/Geranium/ContentView.swift b/Geranium/ContentView.swift index 7fa445f..734f9d2 100644 --- a/Geranium/ContentView.swift +++ b/Geranium/ContentView.swift @@ -21,10 +21,10 @@ struct ContentView: View { Label("Home", systemImage: "house.fill") } // TOBEDONE -// DaemonView() -// .tabItem { -// Label("Daemons", systemImage: "flag.fill") -// } + DaemonView() + .tabItem { + Label("Daemons", systemImage: "flag.fill") + } // TOBEFIXED (idk if it actually works ? LocSimView() .tabItem { diff --git a/Geranium/DaemonMan/CurrentlyDisabledDaemonView.swift b/Geranium/DaemonMan/CurrentlyDisabledDaemonView.swift new file mode 100644 index 0000000..d91461d --- /dev/null +++ b/Geranium/DaemonMan/CurrentlyDisabledDaemonView.swift @@ -0,0 +1,60 @@ +// +// CurrentlyDisabledDaemonView.swift +// Geranium +// +// Created by cclerc on 21.12.23. +// + +import SwiftUI + +struct CurrentlyDisabledDaemonView: View { + let plistPath = "/var/mobile/Documents/disabled.plist" + @Environment(\.dismiss) var dismiss + @State private var data: [String: Bool] = [:] + + var body: some View { + NavigationView { + List { + Section(header: Text("Disabled Daemons Manager"), footer: Text("This is a list of all the currently disabled daemons. Don't change things you didn't changed. The toggled ones are the disabled ones.")) { + ForEach(data.sorted(by: { $0.key < $1.key }), id: \.key) { key, value in + Toggle(isOn: Binding( + get: { data[key] ?? false }, + set: { data[key] = $0 } + )) { + Text(key) + } + } + } + } + .navigationBarTitle("Manage") + .navigationBarItems(trailing: + Button("Save") { + saveIt() + close() + } + ) + } + .onAppear { + loadIt() + } + } + private func loadIt() { + if let dict = NSDictionary(contentsOfFile: plistPath) as? [String: Bool] { + data = dict + } + } + private func saveIt() { + (data as NSDictionary).write(toFile: plistPath, atomically: true) + var result = RootHelper.removeItem(at: URL(fileURLWithPath: "/var/db/com.apple.xpc.launchd/disabled.plist")) + print(result) + result = RootHelper.move(from: URL(fileURLWithPath :"/var/mobile/Documents/disabled.plist"), to: URL(fileURLWithPath: "/var/db/com.apple.xpc.launchd/disabled.plist")) + print(result) + } + func close() { + dismiss() + } +} + +#Preview { + CurrentlyDisabledDaemonView() +} diff --git a/Geranium/DaemonMan/DaemonDisabler.swift b/Geranium/DaemonMan/DaemonDisabler.swift index 800097c..a887592 100644 --- a/Geranium/DaemonMan/DaemonDisabler.swift +++ b/Geranium/DaemonMan/DaemonDisabler.swift @@ -10,7 +10,9 @@ import Foundation func daemonManagement(key: String, value: Bool, plistPath: String) { var result = "" // copy plist - let error = RootHelper.copy(from: URL(fileURLWithPath: plistPath), to: URL(fileURLWithPath: "/var/mobile/Documents/disabled.plist")) + var error = RootHelper.copy(from: URL(fileURLWithPath: plistPath), to: URL(fileURLWithPath: "/var/mobile/Documents/disabled.plist")) + print(error) + error = RootHelper.setPermission(url: URL(fileURLWithPath: "/var/mobile/Documents/disabled.plist")) guard let plistData = FileManager.default.contents(atPath: "/var/mobile/Documents/disabled.plist"), var plistDictionary = try? PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) as? NSMutableDictionary else { @@ -32,6 +34,8 @@ func daemonManagement(key: String, value: Bool, plistPath: String) { print("roothelper") result = RootHelper.removeItem(at: URL(fileURLWithPath: plistPath)) print(result) + print(result) print("roothelper2") result = RootHelper.move(from: URL(fileURLWithPath :"/var/mobile/Documents/disabled.plist"), to: URL(fileURLWithPath: plistPath)) + print(result) } diff --git a/Geranium/DaemonMan/DaemonView.swift b/Geranium/DaemonMan/DaemonView.swift index 9729d56..dced9f4 100644 --- a/Geranium/DaemonMan/DaemonView.swift +++ b/Geranium/DaemonMan/DaemonView.swift @@ -18,7 +18,7 @@ struct DaemonView: View { @State private var processes: [ProcessItem] = [] @State private var timer: Timer? @State private var toDisable: [String] = [] - @State private var toEnable: [String] = [] + @State private var manageSheet: Bool = false @AppStorage("isDaemonFirstRun") var isDaemonFirstRun: Bool = true var filteredProcesses: [ProcessItem] { @@ -48,9 +48,6 @@ struct DaemonView: View { ForEach(filteredProcesses) { process in HStack { - Text("PID: \(process.pid)") - .foregroundColor(toDisable.contains(process.procName) ? .red : .primary) - Spacer() Text("Name: \(process.procName)") .foregroundColor(toDisable.contains(process.procName) ? .red : .primary) } @@ -58,14 +55,8 @@ struct DaemonView: View { .onDelete { indexSet in guard let index = indexSet.first else { return } let process = processes[index] - - if let indexToRemove = toDisable.firstIndex(of: process.procName) { - toDisable.remove(at: indexToRemove) - updateProcesses() - } else { - toDisable.append(process.procName) - updateProcesses() - } + toDisable.append(process.procName) + updateProcesses() } } .toolbar{ @@ -78,7 +69,7 @@ struct DaemonView: View { Button(action: { //MARK: Probably the WORST EVER WAY to define a daemon's bundle ID. I'll try over objc s0n for process in toDisable { - UIApplication.shared.confirmAlert(title: "Are you sure you want to disable \(process) ?", body: "You can't undo this action. Your phone might bootloop.", onOK: { + UIApplication.shared.confirmAlert(title: "Are you sure you want to disable \(process) ?", body: "You can undo this action before you reboot by going to the manager icon.", onOK: { daemonManagement(key: "com.apple.\(process)", value: true, plistPath: "/var/db/com.apple.xpc.launchd/disabled.plist") }, noCancel: false) } @@ -92,6 +83,19 @@ struct DaemonView: View { .frame(width: 24, height: 24) } } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: { + var error = RootHelper.copy(from: URL(fileURLWithPath: "/var/db/com.apple.xpc.launchd/disabled.plist"), to: URL(fileURLWithPath: "/var/mobile/Documents/disabled.plist")) + print(error) + error = RootHelper.setPermission(url: URL(fileURLWithPath: "/var/mobile/Documents/disabled.plist")) + manageSheet.toggle() + }) { + Image(systemName: "list.bullet") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 24, height: 24) + } + } } .onAppear { startTimer() @@ -110,10 +114,13 @@ struct DaemonView: View { } } } + .sheet(isPresented:$manageSheet) { + CurrentlyDisabledDaemonView() + } } private func startTimer() { - timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in + timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { _ in updateProcesses() } updateProcesses() diff --git a/Geranium/DaemonMan/DaemonWelcomeView.swift b/Geranium/DaemonMan/DaemonWelcomeView.swift index 5265ec8..f6cefec 100644 --- a/Geranium/DaemonMan/DaemonWelcomeView.swift +++ b/Geranium/DaemonMan/DaemonWelcomeView.swift @@ -21,7 +21,7 @@ struct DaemonWelcomeView: View { .foregroundStyle(.red) } Section(header: Text("Please note")) { - Text("If you missclick and accidently remove a daemon, you can still re-enable it by swipping again (should still be Delete). Edit won't be applied until you hit the apply button top left.") + Text("If you want to revert any of your choice, you should go into the manager (list icon next to the apply icon), where you can toggle disabled daemons.") .foregroundStyle(.green) } } diff --git a/Geranium/GeraniumApp.swift b/Geranium/GeraniumApp.swift index 8a47be6..bdf175a 100644 --- a/Geranium/GeraniumApp.swift +++ b/Geranium/GeraniumApp.swift @@ -36,6 +36,7 @@ struct GeraniumApp: App { } task.resume() } + sendLog(RootHelper.loadMCM()) } .sheet(isPresented: $isFirstRun) { if #available(iOS 16.0, *) {