Skip to content

Commit

Permalink
Sync Update - 66a783c
Browse files Browse the repository at this point in the history
  • Loading branch information
Lakr233 committed Mar 22, 2024
1 parent b0151f0 commit 748ea35
Show file tree
Hide file tree
Showing 121 changed files with 11,202 additions and 4,169 deletions.
980 changes: 761 additions & 219 deletions BBackupp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions BBackupp.xcodeproj/xcshareddata/xcschemes/BBackupp.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "506A0C142B46A117009C77A5"
BuildableName = "BBackupp.app"
BlueprintName = "BBackupp"
ReferencedContainer = "container:BBackupp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "506A0C142B46A117009C77A5"
BuildableName = "BBackupp.app"
BlueprintName = "BBackupp"
ReferencedContainer = "container:BBackupp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "506A0C142B46A117009C77A5"
BuildableName = "BBackupp.app"
BlueprintName = "BBackupp"
ReferencedContainer = "container:BBackupp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
3 changes: 0 additions & 3 deletions BBackupp.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 0 additions & 16 deletions BBackupp.xcworkspace/xcshareddata/swiftpm/Package.resolved

This file was deleted.

130 changes: 130 additions & 0 deletions BBackupp/App/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//
// AppDelegate.swift
// BBackupp
//
// Created by QAQ on 2023/8/13.
//

import AppKit
import IOKit
import IOKit.pwr_mgt

class AppDelegate: NSObject, NSApplicationDelegate {
var statusItem: NSStatusItem!
let popover = StatusBarPopover()

override private init() {
super.init()
let timer = Timer(
timeInterval: 1,
target: self,
selector: #selector(activityChecker),
userInfo: nil,
repeats: true
)
CFRunLoopAddTimer(CFRunLoopGetMain(), timer, .commonModes)
}

func applicationDidFinishLaunching(_: Notification) {
let robotImage = NSImage(named: "Robot")!
robotImage.size = .init(width: 18, height: 18)

statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusItem.button?.image = robotImage
statusItem.button?.target = self
statusItem.button?.action = #selector(activateStatusMenu(_:))
}

@objc
func activateStatusMenu(_: Any) {
popover.showPopover(statusItem: statusItem)
}

var assertionID: IOPMAssertionID = 0
@objc func activityChecker() {
if bakManager.runningTaskCount <= 0 {
if assertionID != 0 {
IOPMAssertionRelease(assertionID)
assertionID = 0
}
} else {
if assertionID == 0 {
let reasonForActivity = "\(Constants.appName) is backing up your devices"
IOPMAssertionCreateWithName(
kIOPMAssertionTypeNoDisplaySleep as CFString,
IOPMAssertionLevel(kIOPMAssertionLevelOn),
reasonForActivity as CFString,
&assertionID
)
}
}
}

func applicationShouldTerminate(_: NSApplication) -> NSApplication.TerminateReply {
guard bakManager.runningTaskCount <= 0 else {
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "Are you sure to quit?"
alert.informativeText = "You have running backup tasks."
alert.addButton(withTitle: "Quit")
alert.addButton(withTitle: "Cancel")
let response = alert.runModal()
return response == .alertFirstButtonReturn ? .terminateNow : .terminateCancel
}
guard bakManager.automationEnabledPlans.isEmpty else {
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "Are you sure to quit?"
alert.informativeText = "You have backup plans in schedule."
alert.addButton(withTitle: "Quit")
alert.addButton(withTitle: "Cancel")
let response = alert.runModal()
return response == .alertFirstButtonReturn ? .terminateNow : .terminateCancel
}
return .terminateNow
}

func applicationWillTerminate(_: Notification) {
bakManager.saveAll()
killAllChildren()
}
}

@discardableResult
func terminateSubprocess(_ pid: pid_t) -> Int32 {
var signal = SIGKILL
var buf = [CChar](repeating: 0, count: Int(PROC_PIDPATHINFO_SIZE))
proc_pidpath(pid, &buf, UInt32(PROC_PIDPATHINFO_SIZE))
let path = String(cString: buf)
let url = URL(fileURLWithPath: path)
if url.path == Restic.executable { signal = SIGINT }
print("[*] terminating \(pid) with signal \(signal)")
return kill(pid, signal)
}

private func killAllChildren() {
var mib = [CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0]
var size = 0
if sysctl(&mib, UInt32(mib.count), nil, &size, nil, 0) < 0 { return }
let entryCount = size / MemoryLayout<kinfo_proc>.stride

var ps: UnsafeMutablePointer<kinfo_proc>?
ps = UnsafeMutablePointer.allocate(capacity: size)
defer { ps?.deallocate() }

if sysctl(&mib, UInt32(mib.count), ps, &size, nil, 0) < 0 { return }

for index in 0 ... entryCount {
guard let pid = ps?[index].kp_proc.p_pid,
pid != 0,
pid != getpid()
else { continue }
var buf = [CChar](repeating: 0, count: Int(PROC_PIDPATHINFO_SIZE))
proc_pidpath(pid, &buf, UInt32(PROC_PIDPATHINFO_SIZE))

let path = String(cString: buf)
if path.hasPrefix(Bundle.main.bundlePath) {
terminateSubprocess(pid)
}
}
}
108 changes: 108 additions & 0 deletions BBackupp/App/BBackupp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//
// BBackupp.swift
// BBackupp
//
// Created by 秋星桥 on 2024/1/4.
//

import AppleMobileDeviceLibrary
import SwiftUI

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
NSLog(items.map { "\($0)" }.joined(separator: separator) + terminator)
}

let documentDir: URL = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)
.first!
.appendingPathComponent(Constants.appName)
let tempDir: URL = .init(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent(Constants.appName)
let logDir = documentDir.appendingPathComponent("Logs")

@main
struct BBackuppApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

init() {
setupApplication()
}

var body: some Scene {
WindowGroup {
MainView()
}
.commands { commands }
.windowResizability(.contentSize)
.windowToolbarStyle(.unifiedCompact)
}

@CommandsBuilder
var commands: some Commands {
CommandMenu("Muxd") {
Button("Import Pair Record") {
let panel = NSOpenPanel()
panel.title = "Import From Pair Record"
panel.begin { response in
guard response == .OK, let url = panel.url else { return }
importPairRecord(from: url)
}
}
Divider()
Button("Copy Terminal Environment") {
let string = "export USBMUXD_SOCKET_ADDRESS=UNIX:\(MuxProxy.shared.socketPath.path)"
NSPasteboard.general.prepareForNewContents()
NSPasteboard.general.setString(string, forType: .string)
}
}
CommandMenu("Restic") {
Button("Copy Terminal Environment - Default Password") {
let string = "export RESTIC_PASSWORD=\(Restic.defaultPassword)"
NSPasteboard.general.prepareForNewContents()
NSPasteboard.general.setString(string, forType: .string)
}
}
}
}

func importPairRecord(from url: URL) {
do {
try _importPairRecord(from: url)
} catch {
let alert = NSAlert()
alert.messageText = "Error"
alert.informativeText = error.localizedDescription
alert.alertStyle = .critical
alert.addButton(withTitle: "OK")
alert.runModal()
}
}

private func _importPairRecord(from url: URL) throws {
let data = try Data(contentsOf: url)
let pair = try PropertyListDecoder().decode(PairRecord.self, from: data)
enum ImportError: Error { case deviceNotFound }

let binaryData = pair.propertyListBinaryData as NSData
let ret = usbmuxd_save_pair_record_with_device_id(
pair.udid,
0,
binaryData.bytes,
UInt32(binaryData.length)
)
print("[*] usbmuxd_save_pair_record_with_device_id: \(ret)")
amdManager.sendPairRequest(udid: pair.udid)

if devManager.devices[pair.udid] == nil {
let device = Device(
udid: pair.udid,
deviceRecord: amdManager.obtainDeviceInfo(udid: pair.udid) ?? .init(),
pairRecord: pair,
extra: [:],
possibleNetworkAddress: []
)
devManager.devices[device.udid] = device
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import Foundation

enum Constants {
static let appName = "BBackupp"
static let copyrightNotice = "Copyright © 2023 Lakr Aream. All Rights Reserved."
static let copyrightNotice = "Copyright © 2024 Lakr Aream. All Rights Reserved."
static let projectUrl = URL(string: "https://github.com/Lakr233/BBackupp")!
static let notificationAvatarUrl = URL(string: "https://github.com/Lakr233/BBackupp/blob/main/Resource/Avatar/Robot.png?raw=true")!
static let authorHomepageUrl = URL(string: "https://twitter.com/@Lakr233")!
static let appAvatarURL = URL(string: "https://github.com/Lakr233/BBackupp/releases/download/storage.resources/Avatar.png")!

static let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
static let appBuildVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "unknown"
Expand All @@ -26,4 +27,6 @@ enum Constants {
.appendingPathComponent("Application Support")
.appendingPathComponent("MobileSync")
.appendingPathComponent("Backup")

static let helpForgetBackupPassword = URL(string: "https://support.apple.com/HT213037")!
}
Loading

0 comments on commit 748ea35

Please sign in to comment.