summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/ideviceinstaller.188
-rw-r--r--src/ideviceinstaller.c264
2 files changed, 172 insertions, 180 deletions
diff --git a/man/ideviceinstaller.1 b/man/ideviceinstaller.1
index 8ede2db..b13b0e6 100644
--- a/man/ideviceinstaller.1
+++ b/man/ideviceinstaller.1
@@ -7,29 +7,13 @@ ideviceinstaller \- Manage apps on iOS devices.
7 7
8.SH DESCRIPTION 8.SH DESCRIPTION
9 9
10Allows to install, upgrade, uninstall, archive, restore and enumerate installed 10Allows to enumerate, install, upgrade, and uninstall apps on iOS devices.
11or archived apps on iOS devices.
12 11
13.SH OPTIONS 12.SH COMMANDS
14
15.SS General options:
16.TP
17.B \-d, \-\-debug
18enable communication debugging.
19.TP
20.B \-u, \-\-udid UDID
21target specific device by its 40-digit device UDID.
22.TP
23.B \-h, \-\-help
24prints usage information
25
26.SS Commands:
27.TP 13.TP
28.B \-l, \-\-list-apps 14.B list
29list apps installed on the device. 15List installed apps on the device.
30
31.RS 16.RS
32.B Additional options:
33.TP 17.TP
34\-b <bundleID> 18\-b <bundleID>
35Only query for given bundle identifier (can be passed multiple times) 19Only query for given bundle identifier (can be passed multiple times)
@@ -47,42 +31,37 @@ list all types of apps
47\-o xml 31\-o xml
48print output in xml format (PList) 32print output in xml format (PList)
49.RE 33.RE
50
51.TP 34.TP
52.B \-i, \-\-install ARCHIVE 35.B install PATH
53install app from a package file specified by ARCHIVE. ARCHIVE can also be a 36Install app from a package file specified by PATH. PATH can also be a .ipcc
54.ipcc file for carrier bundle installation or a .app directory for developer 37file for carrier bundle installation or a .app directory for developer
55app installation. 38app installation.
56 39
57.TP 40.TP
58.B \-U, \-\-uninstall APPID 41.B uninstall BUNDLEID
59uninstall app specified by APPID. 42Uninstall app specified by BUNDLEID.
60 43
61.TP 44.TP
62.B \-g, \-\-upgrade ARCHIVE 45.B upgrade PATH
63upgrade app from a package file specified by ARCHIVE. 46Upgrade app from a package file specified by PATH.
64 47
65.TP 48.TP
66.B \-r, \-\-restore APPID 49.B restore BUNDLEID
67restore archived app specified by APPID. 50Restore archived app specified by BUNDLEID.
68 51
69.TP 52.TP
70.B \-L, \-\-list-archives 53.B list-archives
71list archived applications on the device. 54List archived apps on the device.
72
73.RS 55.RS
74.B Additional options:
75.TP 56.TP
76\-o xml 57\-o xml
77print output in xml format (PList) 58print full output as xml plist
78.RE 59.RE
79 60
80.TP 61.TP
81.B \-a, \-\-archive APPID 62.B archive BUNDLEID
82archive app specified by APPID. 63Archive app specified by BUNDLEID.
83
84.RS 64.RS
85.B Additional options:
86.TP 65.TP
87\-o uninstall 66\-o uninstall
88uninstall the package after making an archive 67uninstall the package after making an archive
@@ -101,11 +80,34 @@ only valid when copy=PATH is used: remove after copy
101.RE 80.RE
102 81
103.TP 82.TP
104.B \-R, \-\-remove-archive APPID 83.B remove-archive BUNDLEID
105remove app archive specified by APPID. 84Remove app archive specified by BUNDLEID.
85
86
87.SH OPTIONS
88.TP
89.B \-u, \-\-udid UDID
90Target specific device by UDID.
91.TP
92.B \-n, \-\-network
93Connect to network device.
94.TP
95.B \-w, \-\-notify-wait
96Wait for app installed/uninstalled notification to before reporting success of operation.
97.TP
98.B \-h, \-\-help
99Print usage information.
100.TP
101.B \-d, \-\-debug
102Enable communication debugging.
103.TP
104.B \-v, \-\-version
105Print version information.
106
107.SH AUTHORS
108Nikias Bassen
106 109
107.SH AUTHOR 110Martin Szulecki
108This manual page was written by Martin Szulecki.
109 111
110.SH ON THE WEB 112.SH ON THE WEB
111https://libimobiledevice.org 113https://libimobiledevice.org
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c
index d80f04d..55c10d0 100644
--- a/src/ideviceinstaller.c
+++ b/src/ideviceinstaller.c
@@ -94,7 +94,7 @@ const char APPARCH_PATH[] = "ApplicationArchives";
94 94
95char *udid = NULL; 95char *udid = NULL;
96char *options = NULL; 96char *options = NULL;
97char *appid = NULL; 97char *cmdarg = NULL;
98 98
99enum cmd_mode { 99enum cmd_mode {
100 CMD_NONE = 0, 100 CMD_NONE = 0,
@@ -147,7 +147,7 @@ static void print_apps(plist_t apps)
147 plist_get_string_val(p_bundle_identifier, &s_bundle_identifier); 147 plist_get_string_val(p_bundle_identifier, &s_bundle_identifier);
148 } 148 }
149 if (!s_bundle_identifier) { 149 if (!s_bundle_identifier) {
150 fprintf(stderr, "ERROR: Failed to get APPID!\n"); 150 fprintf(stderr, "ERROR: Failed to get bundle identifier!\n");
151 break; 151 break;
152 } 152 }
153 153
@@ -387,50 +387,49 @@ static void idevice_wait_for_command_to_complete()
387 idevice_event_unsubscribe(); 387 idevice_event_unsubscribe();
388} 388}
389 389
390static void print_usage(int argc, char **argv) 390static void print_usage(int argc, char **argv, int is_error)
391{ 391{
392 char *name = NULL; 392 char *name = strrchr(argv[0], '/');
393 393 fprintf((is_error) ? stderr : stdout, "Usage: %s OPTIONS\n", (name ? name + 1 : argv[0]));
394 name = strrchr(argv[0], '/'); 394 fprintf((is_error) ? stderr : stdout,
395 printf("Usage: %s OPTIONS\n", (name ? name + 1 : argv[0])); 395 "\n"
396 printf("\n"); 396 "Manage apps on iOS devices.\n"
397 printf("Manage apps on iOS devices.\n"); 397 "\n"
398 printf("\n"); 398 "COMMANDS:\n"
399 printf( 399 " list List installed apps\n"
400 "OPTIONS:\n" 400 " -b, --bundle-identifier Only query for given bundle identifier\n"
401 " -u, --udid UDID\tTarget specific device by UDID.\n" 401 " (can be passed multiple times)\n"
402 " -n, --network\t\tConnect to network device.\n" 402 " -o list_user list user apps only (this is the default)\n"
403 " -l, --list-apps\tList apps, possible options:\n" 403 " -o list_system list system apps only\n"
404 " -b, --bundle-identifier\tOnly query for given bundle identifier\n" 404 " -o list_all list all types of apps\n"
405 " (can be passed multiple times)\n" 405 " -o xml print full output as xml plist\n"
406 " -o list_user\t- list user apps only (this is the default)\n" 406 " install PATH Install app from package file specified by PATH.\n"
407 " -o list_system\t- list system apps only\n" 407 " PATH can also be a .ipcc file for carrier bundles.\n"
408 " -o list_all\t- list all types of apps\n" 408 " uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n"
409 " -o xml\t\t- print full output as xml plist\n" 409 " upgrade PATH Upgrade app from package file specified by PATH.\n"
410 " -i, --install ARCHIVE\tInstall app from package file specified by ARCHIVE.\n" 410 " list-archives List archived apps\n"
411 " \tARCHIVE can also be a .ipcc file for carrier bundles.\n" 411 " -o xml print full output as xml plist\n"
412 " -U, --uninstall APPID\tUninstall app specified by APPID.\n" 412 " archive BUNDLEID Archive app specified by BUNDLEID, possible options:\n"
413 " -g, --upgrade ARCHIVE\tUpgrade app from package file specified by ARCHIVE.\n" 413 " -o uninstall uninstall the package after making an archive\n"
414 " -L, --list-archives\tList archived applications, possible options:\n" 414 " -o app_only archive application data only\n"
415 " -o xml\t\t- print full output as xml plist\n" 415 " -o docs_only archive documents (user data) only\n"
416 " -a, --archive APPID\tArchive app specified by APPID, possible options:\n" 416 " -o copy=PATH copy the app archive to directory PATH when done\n"
417 " -o uninstall\t- uninstall the package after making an archive\n" 417 " -o remove only valid when copy=PATH is used: remove after copy\n"
418 " -o app_only\t- archive application data only\n" 418 " restore BUNDLEID Restore archived app specified by BUNDLEID\n"
419 " -o docs_only\t- archive documents (user data) only\n" 419 " remove-archive BUNDLEID Remove app archive specified by BUNDLEID\n"
420 " -o copy=PATH\t- copy the app archive to directory PATH when done\n" 420 "\n"
421 " -o remove\t- only valid when copy=PATH is used: remove after copy\n" 421 "OPTIONS:\n"
422 " -r, --restore APPID\tRestore archived app specified by APPID\n" 422 " -u, --udid UDID Target specific device by UDID\n"
423 " -R, --remove-archive APPID Remove app archive specified by APPID\n" 423 " -n, --network Connect to network device\n"
424 " -o, --options\t\tPass additional options to the specified command.\n" 424 " -w, --notify-wait Wait for app installed/uninstalled notification\n"
425 " -w, --notify-wait\t\tWait for app installed/uninstalled notification\n" 425 " to before reporting success of operation\n"
426 " \t\tto before reporting success of operation\n" 426 " -h, --help Print usage information\n"
427 " -h, --help\t\tprints usage information\n" 427 " -d, --debug Enable communication debugging\n"
428 " -d, --debug\t\tenable communication debugging\n" 428 " -v, --version Print version information\n"
429 " -v, --version\t\tprint version information\n" 429 "\n"
430 "\n" 430 "Homepage: <" PACKAGE_URL ">\n"
431 "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
431 ); 432 );
432 printf("Homepage: <" PACKAGE_URL ">\n");
433 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n");
434} 433}
435 434
436static void parse_opts(int argc, char **argv) 435static void parse_opts(int argc, char **argv)
@@ -439,14 +438,6 @@ static void parse_opts(int argc, char **argv)
439 { "help", no_argument, NULL, 'h' }, 438 { "help", no_argument, NULL, 'h' },
440 { "udid", required_argument, NULL, 'u' }, 439 { "udid", required_argument, NULL, 'u' },
441 { "network", no_argument, NULL, 'n' }, 440 { "network", no_argument, NULL, 'n' },
442 { "list-apps", no_argument, NULL, 'l' },
443 { "install", required_argument, NULL, 'i' },
444 { "uninstall", required_argument, NULL, 'U' },
445 { "upgrade", required_argument, NULL, 'g' },
446 { "list-archives", no_argument, NULL, 'L' },
447 { "archive", required_argument, NULL, 'a' },
448 { "restore", required_argument, NULL, 'r' },
449 { "remove-archive", required_argument, NULL, 'R' },
450 { "options", required_argument, NULL, 'o' }, 441 { "options", required_argument, NULL, 'o' },
451 { "notify-wait", no_argument, NULL, 'w' }, 442 { "notify-wait", no_argument, NULL, 'w' },
452 { "debug", no_argument, NULL, 'd' }, 443 { "debug", no_argument, NULL, 'd' },
@@ -457,39 +448,19 @@ static void parse_opts(int argc, char **argv)
457 int c; 448 int c;
458 449
459 while (1) { 450 while (1) {
460 c = getopt_long(argc, argv, "hU:li:u:g:La:r:R:o:nwdvb:", longopts, 451 c = getopt_long(argc, argv, "hu:o:nwdvb:", longopts, (int*)0);
461 (int *) 0);
462 if (c == -1) { 452 if (c == -1) {
463 break; 453 break;
464 } 454 }
465 455
466 /* verify if multiple modes have been supplied */
467 switch (c) {
468 case 'l':
469 case 'i':
470 case 'g':
471 case 'L':
472 case 'a':
473 case 'r':
474 case 'R':
475 if (cmd != CMD_NONE) {
476 printf("ERROR: A mode has already been supplied. Multiple modes are not supported.\n");
477 print_usage(argc, argv);
478 exit(2);
479 }
480 break;
481 default:
482 break;
483 }
484
485 switch (c) { 456 switch (c) {
486 case 'h': 457 case 'h':
487 print_usage(argc, argv); 458 print_usage(argc, argv, 0);
488 exit(0); 459 exit(0);
489 case 'u': 460 case 'u':
490 if (!*optarg) { 461 if (!*optarg) {
491 printf("ERROR: UDID must not be empty!\n"); 462 printf("ERROR: UDID must not be empty!\n");
492 print_usage(argc, argv); 463 print_usage(argc, argv, 1);
493 exit(2); 464 exit(2);
494 } 465 }
495 udid = strdup(optarg); 466 udid = strdup(optarg);
@@ -500,7 +471,7 @@ static void parse_opts(int argc, char **argv)
500 case 'b': 471 case 'b':
501 if (!*optarg) { 472 if (!*optarg) {
502 printf("ERROR: bundle identifier must not be empty!\n"); 473 printf("ERROR: bundle identifier must not be empty!\n");
503 print_usage(argc, argv); 474 print_usage(argc, argv, 1);
504 exit(2); 475 exit(2);
505 } 476 }
506 if (bundle_ids == NULL) { 477 if (bundle_ids == NULL) {
@@ -508,36 +479,6 @@ static void parse_opts(int argc, char **argv)
508 } 479 }
509 plist_array_append_item(bundle_ids, plist_new_string(optarg)); 480 plist_array_append_item(bundle_ids, plist_new_string(optarg));
510 break; 481 break;
511 case 'l':
512 cmd = CMD_LIST_APPS;
513 break;
514 case 'i':
515 cmd = CMD_INSTALL;
516 appid = strdup(optarg);
517 break;
518 case 'U':
519 cmd = CMD_UNINSTALL;
520 appid = strdup(optarg);
521 break;
522 case 'g':
523 cmd = CMD_UPGRADE;
524 appid = strdup(optarg);
525 break;
526 case 'L':
527 cmd = CMD_LIST_ARCHIVES;
528 break;
529 case 'a':
530 cmd = CMD_ARCHIVE;
531 appid = strdup(optarg);
532 break;
533 case 'r':
534 cmd = CMD_RESTORE;
535 appid = strdup(optarg);
536 break;
537 case 'R':
538 cmd = CMD_REMOVE_ARCHIVE;
539 appid = strdup(optarg);
540 break;
541 case 'o': 482 case 'o':
542 if (!options) { 483 if (!options) {
543 options = strdup(optarg); 484 options = strdup(optarg);
@@ -560,19 +501,69 @@ static void parse_opts(int argc, char **argv)
560 printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); 501 printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
561 exit(0); 502 exit(0);
562 default: 503 default:
563 print_usage(argc, argv); 504 print_usage(argc, argv, 1);
564 exit(2); 505 exit(2);
565 } 506 }
566 } 507 }
567 508
568 if (cmd == CMD_NONE) { 509 argv += optind;
569 printf("ERROR: No mode/command was supplied.\n"); 510 argc -= optind;
570 }
571 511
572 if (cmd == CMD_NONE || optind <= 1 || (argc - optind > 0)) { 512 if (argc == 0) {
573 print_usage(argc, argv); 513 fprintf(stderr, "ERROR: Missing command.\n\n");
514 print_usage(argc+optind, argv-optind, 1);
574 exit(2); 515 exit(2);
575 } 516 }
517
518 char *cmdstr = argv[0];
519
520 if (!strcmp(cmdstr, "list")) {
521 cmd = CMD_LIST_APPS;
522 } else if (!strcmp(cmdstr, "install")) {
523 cmd = CMD_INSTALL;
524 } else if (!strcmp(cmdstr, "upgrade")) {
525 cmd = CMD_UPGRADE;
526 } else if (!strcmp(cmdstr, "uninstall") || !strcmp(cmdstr, "remove")) {
527 cmd = CMD_UNINSTALL;
528 } else if (!strcmp(cmdstr, "archives") || !strcmp(cmdstr, "list-archives")) {
529 cmd = CMD_LIST_ARCHIVES;
530 } else if (!strcmp(cmdstr, "archive")) {
531 cmd = CMD_ARCHIVE;
532 } else if (!strcmp(cmdstr, "restore")) {
533 cmd = CMD_RESTORE;
534 } else if (!strcmp(cmdstr, "remove-archive")) {
535 cmd = CMD_REMOVE_ARCHIVE;
536 }
537
538 switch (cmd) {
539 case CMD_LIST_APPS:
540 case CMD_LIST_ARCHIVES:
541 break;
542 case CMD_INSTALL:
543 case CMD_UPGRADE:
544 if (argc < 2) {
545 fprintf(stderr, "ERROR: Missing filename for '%s' command.\n\n", cmdstr);
546 print_usage(argc+optind, argv-optind, 1);
547 exit(2);
548 }
549 cmdarg = argv[1];
550 break;
551 case CMD_UNINSTALL:
552 case CMD_ARCHIVE:
553 case CMD_RESTORE:
554 case CMD_REMOVE_ARCHIVE:
555 if (argc < 2) {
556 fprintf(stderr, "ERROR: Missing bundle ID for '%s' command.\n\n", cmdstr);
557 print_usage(argc+optind, argv-optind, 1);
558 exit(2);
559 }
560 cmdarg = argv[1];
561 break;
562 default:
563 fprintf(stderr, "ERROR: Invalid command '%s'.\n\n", cmdstr);
564 print_usage(argc+optind, argv-optind, 1);
565 exit(2);
566 }
576} 567}
577 568
578static int afc_upload_file(afc_client_t afc, const char* filename, const char* dstfn) 569static int afc_upload_file(afc_client_t afc, const char* filename, const char* dstfn)
@@ -583,7 +574,7 @@ static int afc_upload_file(afc_client_t afc, const char* filename, const char* d
583 574
584 f = fopen(filename, "rb"); 575 f = fopen(filename, "rb");
585 if (!f) { 576 if (!f) {
586 fprintf(stderr, "fopen: %s: %s\n", appid, strerror(errno)); 577 fprintf(stderr, "fopen: %s: %s\n", filename, strerror(errno));
587 return -1; 578 return -1;
588 } 579 }
589 580
@@ -866,8 +857,8 @@ run_again:
866 goto leave_cleanup; 857 goto leave_cleanup;
867 } 858 }
868 859
869 if (stat(appid, &fst) != 0) { 860 if (stat(cmdarg, &fst) != 0) {
870 fprintf(stderr, "ERROR: stat: %s: %s\n", appid, strerror(errno)); 861 fprintf(stderr, "ERROR: stat: %s: %s\n", cmdarg, strerror(errno));
871 goto leave_cleanup; 862 goto leave_cleanup;
872 } 863 }
873 864
@@ -892,14 +883,14 @@ run_again:
892 int errp = 0; 883 int errp = 0;
893 struct zip *zf = NULL; 884 struct zip *zf = NULL;
894 885
895 if ((strlen(appid) > 5) && (strcmp(&appid[strlen(appid)-5], ".ipcc") == 0)) { 886 if ((strlen(cmdarg) > 5) && (strcmp(&cmdarg[strlen(cmdarg)-5], ".ipcc") == 0)) {
896 zf = zip_open(appid, 0, &errp); 887 zf = zip_open(cmdarg, 0, &errp);
897 if (!zf) { 888 if (!zf) {
898 fprintf(stderr, "ERROR: zip_open: %s: %d\n", appid, errp); 889 fprintf(stderr, "ERROR: zip_open: %s: %d\n", cmdarg, errp);
899 goto leave_cleanup; 890 goto leave_cleanup;
900 } 891 }
901 892
902 char* ipcc = strdup(appid); 893 char* ipcc = strdup(cmdarg);
903 if ((asprintf(&pkgname, "%s/%s", PKG_PATH, basename(ipcc)) > 0) && pkgname) { 894 if ((asprintf(&pkgname, "%s/%s", PKG_PATH, basename(ipcc)) > 0) && pkgname) {
904 afc_make_directory(afc, pkgname); 895 afc_make_directory(afc, pkgname);
905 } 896 }
@@ -989,20 +980,20 @@ run_again:
989 /* upload developer app directory */ 980 /* upload developer app directory */
990 instproxy_client_options_add(client_opts, "PackageType", "Developer", NULL); 981 instproxy_client_options_add(client_opts, "PackageType", "Developer", NULL);
991 982
992 if (asprintf(&pkgname, "%s/%s", PKG_PATH, basename(appid)) < 0) { 983 if (asprintf(&pkgname, "%s/%s", PKG_PATH, basename(cmdarg)) < 0) {
993 fprintf(stderr, "ERROR: Out of memory allocating pkgname!?\n"); 984 fprintf(stderr, "ERROR: Out of memory allocating pkgname!?\n");
994 goto leave_cleanup; 985 goto leave_cleanup;
995 } 986 }
996 987
997 printf("Uploading %s package contents... ", basename(appid)); 988 printf("Uploading %s package contents... ", basename(cmdarg));
998 afc_upload_dir(afc, appid, pkgname); 989 afc_upload_dir(afc, cmdarg, pkgname);
999 printf("DONE.\n"); 990 printf("DONE.\n");
1000 991
1001 /* extract the CFBundleIdentifier from the package */ 992 /* extract the CFBundleIdentifier from the package */
1002 993
1003 /* construct full filename to Info.plist */ 994 /* construct full filename to Info.plist */
1004 char *filename = (char*)malloc(strlen(appid)+11+1); 995 char *filename = (char*)malloc(strlen(cmdarg)+11+1);
1005 strcpy(filename, appid); 996 strcpy(filename, cmdarg);
1006 strcat(filename, "/Info.plist"); 997 strcat(filename, "/Info.plist");
1007 998
1008 struct stat st; 999 struct stat st;
@@ -1044,9 +1035,9 @@ run_again:
1044 plist_free(info); 1035 plist_free(info);
1045 info = NULL; 1036 info = NULL;
1046 } else { 1037 } else {
1047 zf = zip_open(appid, 0, &errp); 1038 zf = zip_open(cmdarg, 0, &errp);
1048 if (!zf) { 1039 if (!zf) {
1049 fprintf(stderr, "ERROR: zip_open: %s: %d\n", appid, errp); 1040 fprintf(stderr, "ERROR: zip_open: %s: %d\n", cmdarg, errp);
1050 goto leave_cleanup; 1041 goto leave_cleanup;
1051 } 1042 }
1052 1043
@@ -1153,9 +1144,9 @@ run_again:
1153 goto leave_cleanup; 1144 goto leave_cleanup;
1154 } 1145 }
1155 1146
1156 printf("Copying '%s' to device... ", appid); 1147 printf("Copying '%s' to device... ", cmdarg);
1157 1148
1158 if (afc_upload_file(afc, appid, pkgname) < 0) { 1149 if (afc_upload_file(afc, cmdarg, pkgname) < 0) {
1159 printf("FAILED\n"); 1150 printf("FAILED\n");
1160 free(pkgname); 1151 free(pkgname);
1161 goto leave_cleanup; 1152 goto leave_cleanup;
@@ -1191,8 +1182,8 @@ run_again:
1191 wait_for_command_complete = 1; 1182 wait_for_command_complete = 1;
1192 notification_expected = 1; 1183 notification_expected = 1;
1193 } else if (cmd == CMD_UNINSTALL) { 1184 } else if (cmd == CMD_UNINSTALL) {
1194 printf("Uninstalling '%s'\n", appid); 1185 printf("Uninstalling '%s'\n", cmdarg);
1195 instproxy_uninstall(ipc, appid, NULL, status_cb, NULL); 1186 instproxy_uninstall(ipc, cmdarg, NULL, status_cb, NULL);
1196 wait_for_command_complete = 1; 1187 wait_for_command_complete = 1;
1197 notification_expected = 0; 1188 notification_expected = 0;
1198 } else if (cmd == CMD_LIST_ARCHIVES) { 1189 } else if (cmd == CMD_LIST_ARCHIVES) {
@@ -1353,7 +1344,7 @@ run_again:
1353 } 1344 }
1354 } 1345 }
1355 1346
1356 instproxy_archive(ipc, appid, client_opts, status_cb, NULL); 1347 instproxy_archive(ipc, cmdarg, client_opts, status_cb, NULL);
1357 1348
1358 instproxy_client_options_free(client_opts); 1349 instproxy_client_options_free(client_opts);
1359 wait_for_command_complete = 1; 1350 wait_for_command_complete = 1;
@@ -1375,7 +1366,7 @@ run_again:
1375 uint64_t af = 0; 1366 uint64_t af = 0;
1376 /* local filename */ 1367 /* local filename */
1377 char *localfile = NULL; 1368 char *localfile = NULL;
1378 if (asprintf(&localfile, "%s/%s.ipa", copy_path, appid) < 0) { 1369 if (asprintf(&localfile, "%s/%s.ipa", copy_path, cmdarg) < 0) {
1379 fprintf(stderr, "Out of memory!?\n"); 1370 fprintf(stderr, "Out of memory!?\n");
1380 goto leave_cleanup; 1371 goto leave_cleanup;
1381 } 1372 }
@@ -1390,7 +1381,7 @@ run_again:
1390 1381
1391 /* remote filename */ 1382 /* remote filename */
1392 char *remotefile = NULL; 1383 char *remotefile = NULL;
1393 if (asprintf(&remotefile, "%s/%s.zip", APPARCH_PATH, appid) < 0) { 1384 if (asprintf(&remotefile, "%s/%s.zip", APPARCH_PATH, cmdarg) < 0) {
1394 fprintf(stderr, "Out of memory!?\n"); 1385 fprintf(stderr, "Out of memory!?\n");
1395 goto leave_cleanup; 1386 goto leave_cleanup;
1396 } 1387 }
@@ -1475,7 +1466,7 @@ run_again:
1475 1466
1476 if (remove_after_copy) { 1467 if (remove_after_copy) {
1477 /* remove archive if requested */ 1468 /* remove archive if requested */
1478 printf("Removing '%s'\n", appid); 1469 printf("Removing '%s'\n", cmdarg);
1479 cmd = CMD_REMOVE_ARCHIVE; 1470 cmd = CMD_REMOVE_ARCHIVE;
1480 free(options); 1471 free(options);
1481 options = NULL; 1472 options = NULL;
@@ -1488,11 +1479,11 @@ run_again:
1488 } 1479 }
1489 goto leave_cleanup; 1480 goto leave_cleanup;
1490 } else if (cmd == CMD_RESTORE) { 1481 } else if (cmd == CMD_RESTORE) {
1491 instproxy_restore(ipc, appid, NULL, status_cb, NULL); 1482 instproxy_restore(ipc, cmdarg, NULL, status_cb, NULL);
1492 wait_for_command_complete = 1; 1483 wait_for_command_complete = 1;
1493 notification_expected = 1; 1484 notification_expected = 1;
1494 } else if (cmd == CMD_REMOVE_ARCHIVE) { 1485 } else if (cmd == CMD_REMOVE_ARCHIVE) {
1495 instproxy_remove_archive(ipc, appid, NULL, status_cb, NULL); 1486 instproxy_remove_archive(ipc, cmdarg, NULL, status_cb, NULL);
1496 wait_for_command_complete = 1; 1487 wait_for_command_complete = 1;
1497 } else { 1488 } else {
1498 printf("ERROR: no command selected?! This should not be reached!\n"); 1489 printf("ERROR: no command selected?! This should not be reached!\n");
@@ -1515,7 +1506,6 @@ leave_cleanup:
1515 idevice_free(device); 1506 idevice_free(device);
1516 1507
1517 free(udid); 1508 free(udid);
1518 free(appid);
1519 free(options); 1509 free(options);
1520 free(bundleidentifier); 1510 free(bundleidentifier);
1521 plist_free(bundle_ids); 1511 plist_free(bundle_ids);