diff options
author | Martin Szulecki | 2013-01-11 20:11:11 +0100 |
---|---|---|
committer | Martin Szulecki | 2013-01-11 20:11:11 +0100 |
commit | 1641d9a8e82a0c5f1ad6968916fce2e63187c400 (patch) | |
tree | 4b88991c41592b50018c154bd0da5fd7019b35c9 | |
parent | 7b85d07800030beecf2e2386c3c7539d3ad0629c (diff) | |
download | ideviceinstaller-1641d9a8e82a0c5f1ad6968916fce2e63187c400.tar.gz ideviceinstaller-1641d9a8e82a0c5f1ad6968916fce2e63187c400.tar.bz2 |
Refactor logic to locate the app directory within an archive
The method to determine the Payload/*.app directory in the archive has not
worked for a couple of use-cases. We now scan the file list in the archive
to locate the directory which should work for all cases.
-rw-r--r-- | src/ideviceinstaller.c | 94 |
1 files changed, 64 insertions, 30 deletions
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index 12577f7..54bd318 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c @@ -176,6 +176,61 @@ static int zip_get_contents(struct zip *zf, const char *filename, int locate_fla return 0; } +static int zip_get_app_directory(struct zip* zf, char** path) +{ + int i = 0; + int c = zip_get_num_files(zf); + int len = 0; + const char* name = NULL; + + /* look through all filenames in the archive */ + do { + /* get filename at current index */ + name = zip_get_name(zf, i++, 0); + if (name != NULL) { + /* check if we have a "Payload/.../" name */ + len = strlen(name); + if (!strncmp(name, "Payload/", 8) && (len > 8)) { + /* locate the second directory delimiter */ + const char* p = name + 8; + do { + if (*p == '/') { + break; + } + } while(p++ != NULL); + + /* try next entry if not found */ + if (p == NULL) + continue; + + len = p - name + 1; + + if (*path != NULL) { + free(*path); + *path = NULL; + } + + /* allocate and copy filename */ + *path = (char*)malloc(len + 1); + strncpy(*path, name, len); + + /* add terminating null character */ + char* t = *path + len; + *t = '\0'; + break; + } + } + } while(i < c); + + /* check if the path actually exists */ + int zindex = zip_name_locate(zf, *path, 0); + if (zindex < 0) { + return -1; + } + + return 0; +} + static void do_wait_when_needed() { int i = 0; @@ -633,44 +688,23 @@ run_again: free(zbuf); } - plist_t info = NULL; + /* determine .app directory in archive */ zbuf = NULL; len = 0; + plist_t info = NULL; char filename[256]; filename[0] = '\0'; + char* app_directory_name = NULL; - /* check for "Payload" directory */ - int zindex = zip_name_locate(zf, "Payload/", 0); - if (zindex < 0) { - fprintf(stderr, "Unable to locate Payload folder in archive!\n"); - zip_unchange_all(zf); - zip_close(zf); + if (zip_get_app_directory(zf, &app_directory_name)) { + fprintf(stderr, "Unable to locate app directory in archive!\n"); goto leave_cleanup; } - /* check for "*.app" directory */ - if (meta_dict) { - plist_t nm = plist_dict_get_item(meta_dict, "itemName"); - plist_t fe = plist_dict_get_item(meta_dict, "fileExtension"); - if (nm && (plist_get_node_type(nm) == PLIST_STRING) && fe && (plist_get_node_type(fe) == PLIST_STRING)) { - char* val = NULL; - plist_get_string_val(nm, &val); - if (val) { - strcpy(filename, "Payload/"); - strcat(filename, val); - free(val); - val = NULL; - plist_get_string_val(fe, &val); - strcat(filename, val); - strcat(filename, "/"); - } - } - } - if (filename[0] == '\0') { - strcpy(filename, zip_get_name(zf, zindex+1, 0)); - } - /* construct full filename to Info.plist */ + strcpy(filename, app_directory_name); + free(app_directory_name); + app_directory_name = NULL; strcat(filename, "Info.plist"); if (zip_get_contents(zf, filename, 0, &zbuf, &len) < 0) { @@ -708,7 +742,7 @@ run_again: } char *sinfname = NULL; - if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { + if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { fprintf(stderr, "Out of memory!?\n"); goto leave_cleanup; } |