Skip to content
This repository has been archived by the owner on Jan 5, 2022. It is now read-only.

Commit

Permalink
Add quiet option and list-devices mode
Browse files Browse the repository at this point in the history
  • Loading branch information
jacksonh committed Apr 2, 2012
1 parent 6a3077f commit 3177d76
Showing 1 changed file with 44 additions and 26 deletions.
70 changes: 44 additions & 26 deletions fruitstrap.c
Expand Up @@ -13,6 +13,8 @@
#define PREP_CMDS_PATH "/tmp/fruitstrap-gdb-prep-cmds"
#define GDB_SHELL "/Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb/gdb-arm-apple-darwin --arch armv7 -q -x " PREP_CMDS_PATH

#define PRINT(...) if (!quiet) printf(__VA_ARGS__)

// approximation of what Xcode does:
#define GDB_PREP_CMDS CFSTR("set mi-show-protections off\n\
set auto-raise-load-levels 1\n\
Expand Down Expand Up @@ -44,11 +46,12 @@ int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url,
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
int AMDeviceLookupApplications(AMDeviceRef device, int zero, CFDictionaryRef* result);

bool found_device = false, debug = false, verbose = false;
bool found_device = false, debug = false, verbose = false, quiet = false;
char *app_path = NULL;
char *device_id = NULL;
char *args = NULL;
int timeout = 0;
bool list_devices = FALSE;
CFStringRef last_path = NULL;
service_conn_t gdbfd;

Expand Down Expand Up @@ -102,7 +105,7 @@ CFStringRef copy_device_support_path(AMDeviceRef device) {
if (!found)
{
CFRelease(path);
printf("[ !! ] Unable to locate DeviceSupport directory.\n");
PRINT("[ !! ] Unable to locate DeviceSupport directory.\n");
exit(1);
}

Expand Down Expand Up @@ -145,7 +148,7 @@ CFStringRef copy_developer_disk_image_path(AMDeviceRef device) {

if (!found) {
CFRelease(path);
printf("[ !! ] Unable to locate DeviceSupport directory containing DeveloperDiskImage.dmg.\n");
PRINT("[ !! ] Unable to locate DeviceSupport directory containing DeveloperDiskImage.dmg.\n");
exit(1);
}

Expand All @@ -156,11 +159,11 @@ void mount_callback(CFDictionaryRef dict, int arg) {
CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));

if (CFEqual(status, CFSTR("LookingUpImage"))) {
printf("[ 0%%] Looking up developer disk image\n");
PRINT("[ 0%%] Looking up developer disk image\n");
} else if (CFEqual(status, CFSTR("CopyingImage"))) {
printf("[ 30%%] Copying DeveloperDiskImage.dmg to device\n");
PRINT("[ 30%%] Copying DeveloperDiskImage.dmg to device\n");
} else if (CFEqual(status, CFSTR("MountingImage"))) {
printf("[ 90%%] Mounting developer disk image\n");
PRINT("[ 90%%] Mounting developer disk image\n");
}
}

Expand All @@ -171,10 +174,10 @@ void mount_developer_image(AMDeviceRef device) {
CFRelease(ds_path);

if (verbose) {
printf("Device support path: ");
PRINT("Device support path: ");
fflush(stdout);
CFShow(ds_path);
printf("Developer disk image: ");
PRINT("Developer disk image: ");
fflush(stdout);
CFShow(image_path);
}
Expand All @@ -193,11 +196,11 @@ void mount_developer_image(AMDeviceRef device) {

int result = AMDeviceMountImage(device, image_path, options, &mount_callback, 0);
if (result == 0) {
printf("[ 95%%] Developer disk image mounted successfully\n");
PRINT("[ 95%%] Developer disk image mounted successfully\n");
} else if (result == 0xe8000076 /* already mounted */) {
printf("[ 95%%] Developer disk image already mounted\n");
PRINT("[ 95%%] Developer disk image already mounted\n");
} else {
printf("[ !! ] Unable to mount developer disk image. (%x)\n", result);
PRINT("[ !! ] Unable to mount developer disk image. (%x)\n", result);
exit(1);
}

Expand All @@ -214,7 +217,7 @@ void transfer_callback(CFDictionaryRef dict, int arg) {
CFStringRef path = CFDictionaryGetValue(dict, CFSTR("Path"));

if ((last_path == NULL || !CFEqual(path, last_path)) && !CFStringHasSuffix(path, CFSTR(".ipa"))) {
printf("[%3d%%] Copying %s to device\n", percent / 2, CFStringGetCStringPtr(path, kCFStringEncodingMacRoman));
PRINT("[%3d%%] Copying %s to device\n", percent / 2, CFStringGetCStringPtr(path, kCFStringEncodingMacRoman));
}

if (last_path != NULL) {
Expand All @@ -229,7 +232,7 @@ void install_callback(CFDictionaryRef dict, int arg) {
CFStringRef status = CFDictionaryGetValue(dict, CFSTR("Status"));
CFNumberGetValue(CFDictionaryGetValue(dict, CFSTR("PercentComplete")), kCFNumberSInt32Type, &percent);

printf("[%3d%%] %s\n", (percent / 2) + 50, CFStringGetCStringPtr(status, kCFStringEncodingMacRoman));
PRINT("[%3d%%] %s\n", (percent / 2) + 50, CFStringGetCStringPtr(status, kCFStringEncodingMacRoman));
}

void fdvendor_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
Expand Down Expand Up @@ -388,19 +391,25 @@ void handle_device(AMDeviceRef device) {

CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);

PRINT ("found device id\n");
if (device_id != NULL) {
if(strcmp(device_id, CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding())) == 0) {
found_device = true;
} else {
return;
}
} else {
if (list_devices) {
printf ("%s\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
CFRetain(device); // don't know if this is necessary?
return;
}
found_device = true;
}

CFRetain(device); // don't know if this is necessary?

printf("[ 0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
PRINT("[ 0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));

AMDeviceConnect(device);
assert(AMDeviceIsPaired(device));
Expand Down Expand Up @@ -439,7 +448,7 @@ void handle_device(AMDeviceRef device) {
mach_error_t result = AMDeviceInstallApplication(installFd, path, options, install_callback, NULL);
if (result != 0)
{
printf("AMDeviceInstallApplication failed: %d\n", result);
PRINT("AMDeviceInstallApplication failed: %d\n", result);
exit(1);
}

Expand All @@ -448,7 +457,7 @@ void handle_device(AMDeviceRef device) {
CFRelease(path);
CFRelease(options);

printf("[100%%] Installed package %s\n", app_path);
PRINT("[100%%] Installed package %s\n", app_path);

if (!debug) exit(0); // no debug phase

Expand All @@ -457,16 +466,16 @@ void handle_device(AMDeviceRef device) {
assert(AMDeviceValidatePairing(device) == 0);
assert(AMDeviceStartSession(device) == 0);

printf("------ Debug phase ------\n");
PRINT("------ Debug phase ------\n");

mount_developer_image(device); // put debugserver on the device
start_remote_debug_server(device); // start debugserver
write_gdb_prep_cmds(device, url); // dump the necessary gdb commands into a file

CFRelease(url);

printf("[100%%] Connecting to remote debug server\n");
printf("-------------------------\n");
PRINT("[100%%] Connecting to remote debug server\n");
PRINT("-------------------------\n");

signal(SIGHUP, gdb_ready_handler);

Expand All @@ -490,22 +499,24 @@ void device_callback(struct am_device_notification_callback_info *info, void *ar

void timeout_callback(CFRunLoopTimerRef timer, void *info) {
if (!found_device) {
printf("Timed out waiting for device.\n");
PRINT("Timed out waiting for device.\n");
exit(1);
}
}

void usage(const char* app) {
printf("usage: %s [-d/--debug] [-i/--id device_id] -b/--bundle bundle.app [-a/--args arguments] [-t/--timeout timeout(seconds)]\n", app);
printf("usage: %s [-d/--debug] [-i/--id device_id] [-l/--list-devices] [-q/--quiet] -b/--bundle bundle.app [-a/--args arguments] [-t/--timeout timeout(seconds)]\n", app);
}

int main(int argc, char *argv[]) {
static struct option longopts[] = {
{ "debug", no_argument, NULL, 'd' },
{ "id", required_argument, NULL, 'i' },
{ "list-devices", no_argument, NULL, 'l' },
{ "bundle", required_argument, NULL, 'b' },
{ "args", required_argument, NULL, 'a' },
{ "verbose", no_argument, NULL, 'v' },
{ "quiet", no_argument, NULL, 'q' },
{ "timeout", required_argument, NULL, 't' },
{ NULL, 0, NULL, 0 },
};
Expand All @@ -532,31 +543,38 @@ int main(int argc, char *argv[]) {
case 't':
timeout = atoi(optarg);
break;
case 'l':
list_devices = 1;
break;
case 'q':
quiet = 1;
break;
default:
usage(argv[0]);
return 1;
}
}

if (!app_path) {
if (!list_devices && !app_path) {
usage(argv[0]);
exit(0);
}

printf("------ Install phase ------\n");
PRINT("------ Install phase ------\n");

assert(access(app_path, F_OK) == 0);
if (!list_devices)
assert(access(app_path, F_OK) == 0);

AMDSetLogLevel(5); // otherwise syslog gets flooded with crap
if (timeout > 0)
{
CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + timeout, 0, 0, 0, timeout_callback, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
printf("[....] Waiting up to %d seconds for iOS device to be connected\n", timeout);
PRINT("[....] Waiting up to %d seconds for iOS device to be connected\n", timeout);
}
else
{
printf("[....] Waiting for iOS device to be connected\n");
PRINT("[....] Waiting for iOS device to be connected\n");
}

struct am_device_notification *notify;
Expand Down

0 comments on commit 3177d76

Please sign in to comment.