From 35097bd5a01d0305f6c519196a9938a61786ebe3 Mon Sep 17 00:00:00 2001 From: "Michael R. Hines" Date: Tue, 19 Aug 2014 19:51:20 +0800 Subject: [PATCH 01/12] Don't forget about iPods too =) Update the readme to include iPods in the device identifier search. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8db9d1..bd44b49 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,4 @@ Install and debug iPhone apps without using Xcode. Designed to work on unjailbro Device Ids are the UDIDs of the iOS devices. From the command line, you can list device ids [this way](http://javierhz.blogspot.com/2012/06/how-to-get-udid-of-iphone-using-shell.html): - system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}' + system_profiler SPUSBDataType | sed -n -e '/iPod/,/Serial/p' | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}' From bf5a1e065ee4ed6468503fc49d1686b4ac71663c Mon Sep 17 00:00:00 2001 From: Alexandre Gomes Date: Mon, 6 Oct 2014 13:36:31 +0100 Subject: [PATCH 02/12] fix lldb status checking --- ios-deploy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios-deploy.c b/ios-deploy.c index 75b083a..efdca28 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -77,7 +77,7 @@ def connect_command(debugger, command, result, internal_dict):\n\ listener = lldb.target.GetDebugger().GetListener()\n\ listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n\ events = []\n\ - state = lldb.eStateInvalid\n\ + state = (process.GetState() or lldb.eStateInvalid)\n\ while state != lldb.eStateConnected:\n\ event = lldb.SBEvent()\n\ if listener.WaitForEvent(1, event):\n\ From 4869a343e884c41fae5ac5c84e0af72e920f850e Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 6 Oct 2014 22:32:36 +0200 Subject: [PATCH 03/12] fix AFCFileRef[Read|Write] prototypes Incorrect AFCFileRefRead prototype was causing crashes in 64-bit build when reading large files. --- MobileDevice.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MobileDevice.h b/MobileDevice.h index e078a44..d97eafb 100644 --- a/MobileDevice.h +++ b/MobileDevice.h @@ -396,11 +396,11 @@ afc_error_t AFCFileRefOpen(afc_connection *conn, const char *path, afc_error_t AFCFileRefSeek(afc_connection *conn, afc_file_ref ref, unsigned long long offset1, unsigned long long offset2); afc_error_t AFCFileRefRead(afc_connection *conn, afc_file_ref ref, - void *buf, unsigned int *len); + void *buf, size_t *len); afc_error_t AFCFileRefSetFileSize(afc_connection *conn, afc_file_ref ref, unsigned long long offset); afc_error_t AFCFileRefWrite(afc_connection *conn, afc_file_ref ref, - const void *buf, unsigned int len); + const void *buf, size_t len); afc_error_t AFCFileRefClose(afc_connection *conn, afc_file_ref ref); afc_error_t AFCFileInfoOpen(afc_connection *conn, const char *path, struct @@ -493,4 +493,4 @@ typedef unsigned int (*t_performOperation)(struct am_restore_device *rdev, } #endif -#endif \ No newline at end of file +#endif From 23afce0d3714e5599462cb2ed5326343973a148e Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 6 Oct 2014 22:40:43 +0200 Subject: [PATCH 04/12] handle no --args When no --args are passed application was started with {args} as argument instead of no argument. --- ios-deploy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index 75b083a..fb1f181 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -644,12 +644,12 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) { if (args) { CFStringRef cf_args = CFStringCreateWithCString(NULL, args, kCFStringEncodingASCII); CFStringFindAndReplace(cmds, CFSTR("{args}"), cf_args, range, 0); - rangeLLDB.length = CFStringGetLength(pmodule); CFStringFindAndReplace(pmodule, CFSTR("{args}"), cf_args, rangeLLDB, 0); CFRelease(cf_args); } else { - CFStringFindAndReplace(cmds, CFSTR(" {args}"), CFSTR(""), range, 0); + CFStringFindAndReplace(cmds, CFSTR("{args}"), CFSTR(""), range, 0); + CFStringFindAndReplace(pmodule, CFSTR("{args}"), CFSTR(""), rangeLLDB, 0); } range.length = CFStringGetLength(cmds); From 9a2da6f6427e740eec83d9136569968309798183 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 6 Oct 2014 23:02:06 +0200 Subject: [PATCH 05/12] Fix usage semantic and pair of resource leaks AFCConnectionOpen and AFCFIleInfoOpen don't require initialized pointer to pointer to result, but do require corresponding Close calls. --- ios-deploy.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index fb1f181..1c636bf 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -1014,12 +1014,24 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) printf("%s\n", dir); - afc_dictionary afc_dict; - afc_dictionary* afc_dict_p = &afc_dict; + afc_dictionary* afc_dict_p; + char *key, *val; + int not_dir; + AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p); - - afc_directory afc_dir; - afc_directory* afc_dir_p = &afc_dir; + while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) { + if (strcmp(key,"st_ifmt")==0) { + not_dir = strcmp(val,"S_IFDIR"); + break; + } + } + AFCKeyValueClose(afc_dict_p); + + if (not_dir) { + return; + } + + afc_directory* afc_dir_p; afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p); if (err != 0) @@ -1031,7 +1043,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) while(true) { err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent); - if (!dir_ent) + if (err != 0 || !dir_ent) break; if (strcmp(dir_ent, ".") == 0 || strcmp(dir_ent, "..") == 0) @@ -1119,11 +1131,11 @@ void list_files(AMDeviceRef device) { service_conn_t houseFd = start_house_arrest_service(device); - afc_connection afc_conn; - afc_connection* afc_conn_p = &afc_conn; - AFCConnectionOpen(houseFd, 0, &afc_conn_p); - - read_dir(houseFd, afc_conn_p, "/"); + afc_connection* afc_conn_p; + if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) { + read_dir(houseFd, afc_conn_p, "/"); + AFCConnectionClose(afc_conn_p); + } } void upload_file(AMDeviceRef device) { From 4589cd5d05016ed89fc73bbb5c2519b6654a3708 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 6 Oct 2014 23:16:40 +0200 Subject: [PATCH 06/12] arrange callback in read_dir for future use Custom callback is called for every file or directory listed on device. This will be used for file download. --- ios-deploy.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index 1c636bf..6082c00 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -1002,7 +1002,8 @@ CFStringRef get_bundle_id(CFURLRef app_url) return bundle_id; } -void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) +void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir, + void(*callback)(afc_connection *conn,const char *dir,int file)) { char *dir_ent; @@ -1028,16 +1029,18 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) AFCKeyValueClose(afc_dict_p); if (not_dir) { + if (callback) (*callback)(afc_conn_p, dir, not_dir); return; } afc_directory* afc_dir_p; afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p); - if (err != 0) - { + if (err != 0) { // Couldn't open dir - was probably a file return; + } else { + if (callback) (*callback)(afc_conn_p, dir, not_dir); } while(true) { @@ -1054,7 +1057,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) if (dir_joined[strlen(dir)-1] != '/') strcat(dir_joined, "/"); strcat(dir_joined, dir_ent); - read_dir(afcFd, afc_conn_p, dir_joined); + read_dir(afcFd, afc_conn_p, dir_joined, callback); free(dir_joined); } @@ -1133,7 +1136,7 @@ void list_files(AMDeviceRef device) afc_connection* afc_conn_p; if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) { - read_dir(houseFd, afc_conn_p, "/"); + read_dir(houseFd, afc_conn_p, "/", NULL); AFCConnectionClose(afc_conn_p); } } @@ -1147,7 +1150,7 @@ void upload_file(AMDeviceRef device) { afc_connection* afc_conn_p = &afc_conn; AFCConnectionOpen(houseFd, 0, &afc_conn_p); - // read_dir(houseFd, NULL, "/"); + // read_dir(houseFd, NULL, "/", NULL); if (!target_filename) { From c57f208422e5ae248b3d410ce5f869b42173fd7f Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Mon, 6 Oct 2014 22:09:39 -0700 Subject: [PATCH 07/12] Update version to 1.2.0 --- ios-deploy.c | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index f120544..c32f027 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -16,7 +16,7 @@ #include #include "MobileDevice.h" -#define APP_VERSION "1.1.0" +#define APP_VERSION "1.2.0" #define PREP_CMDS_PATH "/tmp/fruitstrap-lldb-prep-cmds-" #define LLDB_SHELL "lldb -s " PREP_CMDS_PATH diff --git a/package.json b/package.json index d81493a..6eb080f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ios-deploy", - "version": "1.1.0", - "description": "launch iOS apps iOS devices from the command line (Xcode 5)", + "version": "1.2.0", + "description": "launch iOS apps iOS devices from the command line (Xcode 6)", "main": "ios-deploy", "scripts": { "preinstall": "make ios-deploy" From 9f0c8a85c65d3aab7afd4d3e69e3490e24e7d801 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 7 Oct 2014 09:23:34 +0200 Subject: [PATCH 08/12] Add download option. Unlike upload option, download pulls down whole tree. For this reason --to is expected to be directory path. --- ios-deploy.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 3 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index c32f027..e56606e 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -1017,7 +1017,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir, afc_dictionary* afc_dict_p; char *key, *val; - int not_dir; + int not_dir = 0; AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p); while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) { @@ -1141,6 +1141,97 @@ void list_files(AMDeviceRef device) } } +void copy_file_callback(afc_connection* afc_conn_p, const char *name,int file) +{ + const char *local_name=name; + + if (*local_name=='/') local_name++; + + if (*local_name=='\0') return; + + if (file) { + afc_file_ref fref; + int err = AFCFileRefOpen(afc_conn_p,name,1,&fref); + + if (err) { + fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err); + return; + } + + FILE *fp = fopen(local_name,"w"); + + if (fp==NULL) { + fprintf(stderr,"fopen(\"%s\",\"w\") failer: %s\n",local_name,strerror(errno)); + AFCFileRefClose(afc_conn_p,fref); + return; + } + + char buf[4096]; + size_t sz=sizeof(buf); + + while (AFCFileRefRead(afc_conn_p,fref,buf,&sz)==0 && sz) { + fwrite(buf,sz,1,fp); + sz = sizeof(buf); + } + + AFCFileRefClose(afc_conn_p,fref); + fclose(fp); + } else { + if (mkdir(local_name,0777) && errno!=EEXIST) + fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno)); + } +} + +void mkdirhier(char *path) +{ + char *slash; + struct stat buf; + + if (path[0]=='.' && path[1]=='/') path+=2; + + if ((slash = strrchr(path,'/'))) { + *slash = '\0'; + if (stat(path,&buf)==0) { + *slash = '/'; + return; + } + mkdirhier(path); + mkdir (path,0777); + *slash = '/'; + } + + return; +} + +void download_tree(AMDeviceRef device) +{ + service_conn_t houseFd = start_house_arrest_service(device); + afc_connection* afc_conn_p = NULL; + char *dirname = NULL; + + if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) do { + + if (target_filename) { + dirname = strdup(target_filename); + mkdirhier(dirname); + if (mkdir(dirname,0777) && errno!=EEXIST) { + fprintf(stderr,"mkdir(\"%s\") failed: %s\n",dirname,strerror(errno)); + break; + } + if (chdir(dirname)) { + fprintf(stderr,"chdir(\"%s\") failed: %s\n",dirname,strerror(errno)); + break; + } + } + + read_dir(houseFd, afc_conn_p, "/", copy_file_callback); + + } while(0); + + if (dirname) free(dirname); + if (afc_conn_p) AFCConnectionClose(afc_conn_p); +} + void upload_file(AMDeviceRef device) { service_conn_t houseFd = start_house_arrest_service(device); @@ -1226,6 +1317,8 @@ void handle_device(AMDeviceRef device) { list_files(device); } else if (strcmp("upload", command) == 0) { upload_file(device); + } else if (strcmp("download", command) == 0) { + download_tree(device); } exit(0); } @@ -1379,7 +1472,8 @@ void usage(const char* app) { " -1, --bundle_id specify bundle id for list and upload\n" " -l, --list list files\n" " -o, --upload upload file\n" - " -2, --to use together with upload file. specify target for upload\n" + " -w, --download download app tree\n" + " -2, --to use together with up/download file/tree. specify target\n" " -V, --version print the executable version \n", app); } @@ -1409,12 +1503,13 @@ int main(int argc, char *argv[]) { { "list", no_argument, NULL, 'l' }, { "bundle_id", required_argument, NULL, '1'}, { "upload", required_argument, NULL, 'o'}, + { "download", no_argument, NULL, 'w'}, { "to", required_argument, NULL, '2'}, { NULL, 0, NULL, 0 }, }; char ch; - while ((ch = getopt_long(argc, argv, "VmcdvunlrILi:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "VmcdvunlrILiw:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1) { switch (ch) { case 'm': @@ -1479,6 +1574,10 @@ int main(int argc, char *argv[]) { command_only = true; command = "list"; break; + case 'w': + command_only = true; + command = "download"; + break; default: usage(argv[0]); return exitcode_error; From 7742c5d532a3583fa51ff7bc03ff40196e3a2bc1 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 7 Oct 2014 11:23:33 +0200 Subject: [PATCH 09/12] Allow --list and --download to pick specific subdirectories. Note that in a way it introduces inconsistency with help message. This is because arguments to --list and --download are optional and has to be passed with '=', e.g. --list=/Documents. --- ios-deploy.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index e56606e..1189753 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -154,6 +154,7 @@ bool justlaunch = false; char *app_path = NULL; char *device_id = NULL; char *args = NULL; +char *list_root = NULL; int timeout = 0; int port = 12345; CFStringRef last_path = NULL; @@ -1136,7 +1137,7 @@ void list_files(AMDeviceRef device) afc_connection* afc_conn_p; if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) { - read_dir(houseFd, afc_conn_p, "/", NULL); + read_dir(houseFd, afc_conn_p, list_root?list_root:"/", NULL); AFCConnectionClose(afc_conn_p); } } @@ -1224,7 +1225,7 @@ void download_tree(AMDeviceRef device) } } - read_dir(houseFd, afc_conn_p, "/", copy_file_callback); + read_dir(houseFd, afc_conn_p, list_root?list_root:"/", copy_file_callback); } while(0); @@ -1500,16 +1501,16 @@ int main(int argc, char *argv[]) { { "noinstall", no_argument, NULL, 'm' }, { "port", required_argument, NULL, 'p' }, { "uninstall", no_argument, NULL, 'r' }, - { "list", no_argument, NULL, 'l' }, + { "list", optional_argument, NULL, 'l' }, { "bundle_id", required_argument, NULL, '1'}, { "upload", required_argument, NULL, 'o'}, - { "download", no_argument, NULL, 'w'}, + { "download", optional_argument, NULL, 'w'}, { "to", required_argument, NULL, '2'}, { NULL, 0, NULL, 0 }, }; char ch; - while ((ch = getopt_long(argc, argv, "VmcdvunlrILiw:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "VmcdvunrILib:a:t:g:x:p:1:2:o:l::w::", longopts, NULL)) != -1) { switch (ch) { case 'm': @@ -1573,10 +1574,12 @@ int main(int argc, char *argv[]) { case 'l': command_only = true; command = "list"; + list_root = optarg; break; case 'w': command_only = true; command = "download"; + list_root = optarg; break; default: usage(argv[0]); From 63917d796b0d66c9145d3e82b33a094f0b17d736 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Tue, 7 Oct 2014 14:34:54 -0700 Subject: [PATCH 10/12] Added scripts for buildbox. --- resources/buildbox/build.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 resources/buildbox/build.sh diff --git a/resources/buildbox/build.sh b/resources/buildbox/build.sh new file mode 100755 index 0000000..aea6cbf --- /dev/null +++ b/resources/buildbox/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +echo "$ make" +make \ No newline at end of file From 4aa233d14704d8b16845e3fc2711b193b082ce23 Mon Sep 17 00:00:00 2001 From: Eddie Hillenbrand Date: Mon, 3 Nov 2014 16:09:36 -0800 Subject: [PATCH 11/12] Allow the symbols and the disk images to be in different DeviceSupport directories. --- ios-deploy.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index 1189753..121c36a 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -458,22 +458,38 @@ CFStringRef copy_device_support_path(AMDeviceRef device) { return path; } -CFStringRef copy_developer_disk_image_path(CFStringRef deviceSupportPath) { - CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), deviceSupportPath, CFSTR("DeveloperDiskImage.dmg")); - if (!path_exists(path)) { - CFRelease(path); - path = NULL; - } +CFStringRef copy_developer_disk_image_path(AMDeviceRef device) { + CFStringRef version = NULL; + CFStringRef build = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion")); + CFStringRef path = NULL; + CFMutableArrayRef version_parts = get_device_product_version_parts(device); - if (path == NULL) { - // Sometimes Latest seems to be missing in Xcode, in that case use find and hope for the best - path = copy_long_shot_disk_image_path(); - if (CFStringGetLength(path) < 5) { - CFRelease(path); - path = NULL; + while (CFArrayGetCount(version_parts) > 0) { + version = CFStringCreateByCombiningStrings(NULL, version_parts, CFSTR(".")); + if (path == NULL) { + path = copy_xcode_path_for(CFSTR("iOS DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build)); } + if (path == NULL) { + path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build)); + } + if (path == NULL) { + path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (*)/DeveloperDiskImage.dmg"), version)); + } + if (path == NULL) { + path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/DeveloperDiskImage.dmg"), version)); + } + if (path == NULL) { + path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport/Latest"), CFSTR("DeveloperDiskImage.dmg")); + } + CFRelease(version); + if (path != NULL) { + break; + } + CFArrayRemoveValueAtIndex(version_parts, CFArrayGetCount(version_parts) - 1); } + CFRelease(version_parts); + CFRelease(build); if (path == NULL) { printf("[ !! ] Unable to locate DeveloperDiskImage.dmg.\n[ !! ] This probably means you don't have Xcode installed, you will need to launch the app manually and logging output will not be shown!\n"); @@ -497,7 +513,7 @@ void mount_callback(CFDictionaryRef dict, int arg) { void mount_developer_image(AMDeviceRef device) { CFStringRef ds_path = copy_device_support_path(device); - CFStringRef image_path = copy_developer_disk_image_path(ds_path); + CFStringRef image_path = copy_developer_disk_image_path(device); CFStringRef sig_path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.signature"), image_path); if (verbose) { From 049a89e87308fba3664b129eaf85ba02f1ebef22 Mon Sep 17 00:00:00 2001 From: Eddie Hillenbrand Date: Tue, 4 Nov 2014 12:31:39 -0800 Subject: [PATCH 12/12] Fix for mismatched build numbers. --- ios-deploy.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ios-deploy.c b/ios-deploy.c index 121c36a..efa0b4b 100644 --- a/ios-deploy.c +++ b/ios-deploy.c @@ -187,10 +187,20 @@ Boolean path_exists(CFTypeRef path) { CFStringRef find_path(CFStringRef rootPath, CFStringRef namePattern, CFStringRef expression) { FILE *fpipe = NULL; CFStringRef quotedRootPath = rootPath; + CFStringRef cf_command; + CFRange slashLocation; + if (CFStringGetCharacterAtIndex(rootPath, 0) != '`') { quotedRootPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("'%@'"), rootPath); } - CFStringRef cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -name '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression); + + slashLocation = CFStringFind(namePattern, CFSTR("/"), 0); + if (slashLocation.location == kCFNotFound) { + cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -name '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression); + } else { + cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -path '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression); + } + if (quotedRootPath != rootPath) { CFRelease(quotedRootPath); } @@ -255,6 +265,7 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) { CFStringRef path; bool found = false; const char* home = get_home(); + CFRange slashLocation; // Try using xcode-select --print-path @@ -264,7 +275,12 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) { } // Try find `xcode-select --print-path` with search as a name pattern if (!found) { - path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("-maxdepth 1")); + slashLocation = CFStringFind(search, CFSTR("/"), 0); + if (slashLocation.location == kCFNotFound) { + path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("-maxdepth 1")); + } else { + path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("")); + } found = CFStringGetLength(path) > 0 && path_exists(path); } // If not look in the default xcode location (xcode-select is sometimes wrong) @@ -473,7 +489,7 @@ CFStringRef copy_developer_disk_image_path(AMDeviceRef device) { path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build)); } if (path == NULL) { - path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (*)/DeveloperDiskImage.dmg"), version)); + path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("*/%@ (*)/DeveloperDiskImage.dmg"), version)); } if (path == NULL) { path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/DeveloperDiskImage.dmg"), version));