summaryrefslogtreecommitdiffstats
path: root/src/ideviceinstaller.c
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2013-01-11 20:11:11 +0100
committerGravatar Martin Szulecki2013-01-11 20:11:11 +0100
commit1641d9a8e82a0c5f1ad6968916fce2e63187c400 (patch)
tree4b88991c41592b50018c154bd0da5fd7019b35c9 /src/ideviceinstaller.c
parent7b85d07800030beecf2e2386c3c7539d3ad0629c (diff)
downloadideviceinstaller-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.
Diffstat (limited to 'src/ideviceinstaller.c')
-rw-r--r--src/ideviceinstaller.c94
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
176 return 0; 176 return 0;
177} 177}
178 178
179static int zip_get_app_directory(struct zip* zf, char** path)
180{
181 int i = 0;
182 int c = zip_get_num_files(zf);
183 int len = 0;
184 const char* name = NULL;
185
186 /* look through all filenames in the archive */
187 do {
188 /* get filename at current index */
189 name = zip_get_name(zf, i++, 0);
190 if (name != NULL) {
191 /* check if we have a "Payload/.../" name */
192 len = strlen(name);
193 if (!strncmp(name, "Payload/", 8) && (len > 8)) {
194 /* locate the second directory delimiter */
195 const char* p = name + 8;
196 do {
197 if (*p == '/') {
198 break;
199 }
200 } while(p++ != NULL);
201
202 /* try next entry if not found */
203 if (p == NULL)
204 continue;
205
206 len = p - name + 1;
207
208 if (*path != NULL) {
209 free(*path);
210 *path = NULL;
211 }
212
213 /* allocate and copy filename */
214 *path = (char*)malloc(len + 1);
215 strncpy(*path, name, len);
216
217 /* add terminating null character */
218 char* t = *path + len;
219 *t = '\0';
220 break;
221 }
222 }
223 } while(i < c);
224
225 /* check if the path actually exists */
226 int zindex = zip_name_locate(zf, *path, 0);
227 if (zindex < 0) {
228 return -1;
229 }
230
231 return 0;
232}
233
179static void do_wait_when_needed() 234static void do_wait_when_needed()
180{ 235{
181 int i = 0; 236 int i = 0;
@@ -633,44 +688,23 @@ run_again:
633 free(zbuf); 688 free(zbuf);
634 } 689 }
635 690
636 plist_t info = NULL; 691 /* determine .app directory in archive */
637 zbuf = NULL; 692 zbuf = NULL;
638 len = 0; 693 len = 0;
694 plist_t info = NULL;
639 char filename[256]; 695 char filename[256];
640 filename[0] = '\0'; 696 filename[0] = '\0';
697 char* app_directory_name = NULL;
641 698
642 /* check for "Payload" directory */ 699 if (zip_get_app_directory(zf, &app_directory_name)) {
643 int zindex = zip_name_locate(zf, "Payload/", 0); 700 fprintf(stderr, "Unable to locate app directory in archive!\n");
644 if (zindex < 0) {
645 fprintf(stderr, "Unable to locate Payload folder in archive!\n");
646 zip_unchange_all(zf);
647 zip_close(zf);
648 goto leave_cleanup; 701 goto leave_cleanup;
649 } 702 }
650 703
651 /* check for "*.app" directory */
652 if (meta_dict) {
653 plist_t nm = plist_dict_get_item(meta_dict, "itemName");
654 plist_t fe = plist_dict_get_item(meta_dict, "fileExtension");
655 if (nm && (plist_get_node_type(nm) == PLIST_STRING) && fe && (plist_get_node_type(fe) == PLIST_STRING)) {
656 char* val = NULL;
657 plist_get_string_val(nm, &val);
658 if (val) {
659 strcpy(filename, "Payload/");
660 strcat(filename, val);
661 free(val);
662 val = NULL;
663 plist_get_string_val(fe, &val);
664 strcat(filename, val);
665 strcat(filename, "/");
666 }
667 }
668 }
669 if (filename[0] == '\0') {
670 strcpy(filename, zip_get_name(zf, zindex+1, 0));
671 }
672
673 /* construct full filename to Info.plist */ 704 /* construct full filename to Info.plist */
705 strcpy(filename, app_directory_name);
706 free(app_directory_name);
707 app_directory_name = NULL;
674 strcat(filename, "Info.plist"); 708 strcat(filename, "Info.plist");
675 709
676 if (zip_get_contents(zf, filename, 0, &zbuf, &len) < 0) { 710 if (zip_get_contents(zf, filename, 0, &zbuf, &len) < 0) {
@@ -708,7 +742,7 @@ run_again:
708 } 742 }
709 743
710 char *sinfname = NULL; 744 char *sinfname = NULL;
711 if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { 745 if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) {
712 fprintf(stderr, "Out of memory!?\n"); 746 fprintf(stderr, "Out of memory!?\n");
713 goto leave_cleanup; 747 goto leave_cleanup;
714 } 748 }