mirror of
https://github.com/blacktop/ipsw.git
synced 2026-05-08 12:22:26 +00:00
167 lines
3.5 KiB
Go
167 lines
3.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
"github.com/AlecAivazis/survey/v2/terminal"
|
|
"github.com/apex/log"
|
|
"github.com/blacktop/ipsw/pkg/usb"
|
|
"github.com/blacktop/ipsw/pkg/usb/lockdownd"
|
|
"github.com/blacktop/ipsw/pkg/usb/mount"
|
|
)
|
|
|
|
func PickDevice() (*lockdownd.DeviceValues, error) {
|
|
var deets []*lockdownd.DeviceValues
|
|
|
|
conn, err := usb.NewConn()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to usbmuxd: %w", err)
|
|
}
|
|
defer conn.Close()
|
|
|
|
devices, err := conn.ListDevices()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list devices: %w", err)
|
|
}
|
|
|
|
if len(devices) == 0 {
|
|
return nil, fmt.Errorf("no devices found")
|
|
}
|
|
|
|
for _, device := range devices {
|
|
ldc, err := lockdownd.NewClient(device.SerialNumber)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deet, err := ldc.GetValues()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deets = append(deets, deet)
|
|
|
|
ldc.Close()
|
|
}
|
|
|
|
if len(deets) == 1 {
|
|
return deets[0], nil
|
|
}
|
|
|
|
selected := make(map[string]*lockdownd.DeviceValues, len(deets))
|
|
for _, d := range deets {
|
|
selected[fmt.Sprintf("%s_%s_%s", d.ProductType, d.HardwareModel, d.BuildVersion)] = d
|
|
}
|
|
|
|
if len(selected) == 1 {
|
|
return deets[0], nil // can happen if device setup to connect via network
|
|
}
|
|
|
|
var choices []string
|
|
for s := range selected {
|
|
choices = append(choices, s)
|
|
}
|
|
|
|
var picked string
|
|
prompt := &survey.Select{
|
|
Message: "Select what iDevice to connect to:",
|
|
Options: choices,
|
|
}
|
|
if err := survey.AskOne(prompt, &picked); err == terminal.InterruptErr {
|
|
log.Warn("Exiting...")
|
|
os.Exit(0)
|
|
}
|
|
|
|
return selected[picked], nil
|
|
}
|
|
|
|
func PickDevices() ([]*lockdownd.DeviceValues, error) {
|
|
var deets []*lockdownd.DeviceValues
|
|
|
|
conn, err := usb.NewConn()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to usbmuxd: %w", err)
|
|
}
|
|
defer conn.Close()
|
|
|
|
devices, err := conn.ListDevices()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list devices: %w", err)
|
|
}
|
|
|
|
if len(devices) == 0 {
|
|
return nil, fmt.Errorf("no devices found")
|
|
}
|
|
|
|
for _, device := range devices {
|
|
ldc, err := lockdownd.NewClient(device.SerialNumber)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deet, err := ldc.GetValues()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deets = append(deets, deet)
|
|
|
|
ldc.Close()
|
|
}
|
|
|
|
if len(deets) == 1 {
|
|
return deets, nil
|
|
} else {
|
|
var choices []string
|
|
for _, d := range deets {
|
|
choices = append(choices, fmt.Sprintf("%s_%s_%s", d.ProductType, d.HardwareModel, d.BuildVersion))
|
|
}
|
|
selected := []int{}
|
|
prompt := &survey.MultiSelect{
|
|
Message: "Select what iDevices to connect to:",
|
|
Options: choices,
|
|
}
|
|
if err := survey.AskOne(prompt, &selected); err == terminal.InterruptErr {
|
|
log.Warn("Exiting...")
|
|
os.Exit(0)
|
|
}
|
|
// filter based on selection
|
|
var picked []*lockdownd.DeviceValues
|
|
for _, idx := range selected {
|
|
picked = append(picked, deets[idx])
|
|
}
|
|
|
|
return picked, nil
|
|
}
|
|
}
|
|
|
|
func IsDeveloperModeEnabled(udid string) (bool, error) {
|
|
cli, err := lockdownd.NewClient(udid)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to connect to lockdownd: %w", err)
|
|
}
|
|
defer cli.Close()
|
|
return cli.DeveloperModeEnabled()
|
|
}
|
|
|
|
func IsDeveloperImageMounted(udid string) error {
|
|
cli, err := mount.NewClient(udid)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to connect to mobile_image_mounter: %w", err)
|
|
}
|
|
defer cli.Close()
|
|
|
|
images, err := cli.ListImages()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list images: %w", err)
|
|
}
|
|
|
|
if len(images) == 0 {
|
|
return fmt.Errorf("mount the Developer image with the `ipsw idev img mount` command or by opening Xcode")
|
|
}
|
|
|
|
return nil
|
|
}
|