diff options
| author | 2019-05-22 21:08:31 +0200 | |
|---|---|---|
| committer | 2023-07-21 03:30:28 +0700 | |
| commit | 03d93c67ff8266d6253d1dd30c38bb35be59a599 (patch) | |
| tree | 0c3008cb8d92fb21b23edbac246badb6de75130f /src | |
| parent | 5cbf60922b08238365fc4640d5fcb082574e557e (diff) | |
| download | ideviceinstaller-03d93c67ff8266d6253d1dd30c38bb35be59a599.tar.gz ideviceinstaller-03d93c67ff8266d6253d1dd30c38bb35be59a599.tar.bz2 | |
Add options for using external sinf and iTunes metadata
Diffstat (limited to 'src')
| -rw-r--r-- | src/ideviceinstaller.c | 137 |
1 files changed, 113 insertions, 24 deletions
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index d2efbd3..a46b312 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c | |||
| @@ -94,6 +94,8 @@ const char APPARCH_PATH[] = "ApplicationArchives"; | |||
| 94 | 94 | ||
| 95 | char *udid = NULL; | 95 | char *udid = NULL; |
| 96 | char *cmdarg = NULL; | 96 | char *cmdarg = NULL; |
| 97 | char *extsinf = NULL; | ||
| 98 | char *extmeta = NULL; | ||
| 97 | 99 | ||
| 98 | enum cmd_mode { | 100 | enum cmd_mode { |
| 99 | CMD_NONE = 0, | 101 | CMD_NONE = 0, |
| @@ -433,6 +435,8 @@ static void print_usage(int argc, char **argv, int is_error) | |||
| 433 | " (can be passed multiple times)\n" | 435 | " (can be passed multiple times)\n" |
| 434 | " install PATH Install app from package file specified by PATH.\n" | 436 | " install PATH Install app from package file specified by PATH.\n" |
| 435 | " PATH can also be a .ipcc file for carrier bundles.\n" | 437 | " PATH can also be a .ipcc file for carrier bundles.\n" |
| 438 | " -s, --sinf PATH Pass an external SINF file\n" | ||
| 439 | " -m, --metadata PATH Pass an external iTunesMetadata file\n" | ||
| 436 | " uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n" | 440 | " uninstall BUNDLEID Uninstall app specified by BUNDLEID.\n" |
| 437 | " upgrade PATH Upgrade app from package file specified by PATH.\n" | 441 | " upgrade PATH Upgrade app from package file specified by PATH.\n" |
| 438 | "\n" | 442 | "\n" |
| @@ -491,6 +495,8 @@ static void parse_opts(int argc, char **argv) | |||
| 491 | { "all", no_argument, NULL, LIST_ALL }, | 495 | { "all", no_argument, NULL, LIST_ALL }, |
| 492 | { "xml", no_argument, NULL, OUTPUT_XML }, | 496 | { "xml", no_argument, NULL, OUTPUT_XML }, |
| 493 | { "json", no_argument, NULL, OUTPUT_JSON }, | 497 | { "json", no_argument, NULL, OUTPUT_JSON }, |
| 498 | { "sinf", required_argument, NULL, 's' }, | ||
| 499 | { "metadata", required_argument, NULL, 'm' }, | ||
| 494 | { "uninstall", no_argument, NULL, ARCHIVE_UNINSTALL }, | 500 | { "uninstall", no_argument, NULL, ARCHIVE_UNINSTALL }, |
| 495 | { "app-only", no_argument, NULL, ARCHIVE_APP_ONLY }, | 501 | { "app-only", no_argument, NULL, ARCHIVE_APP_ONLY }, |
| 496 | { "docs-only", no_argument, NULL, ARCHIVE_DOCS_ONLY }, | 502 | { "docs-only", no_argument, NULL, ARCHIVE_DOCS_ONLY }, |
| @@ -501,7 +507,7 @@ static void parse_opts(int argc, char **argv) | |||
| 501 | int c; | 507 | int c; |
| 502 | 508 | ||
| 503 | while (1) { | 509 | while (1) { |
| 504 | c = getopt_long(argc, argv, "hu:nwdvb:a:", longopts, (int*)0); | 510 | c = getopt_long(argc, argv, "hu:nwdvb:a:s:m:", longopts, (int*)0); |
| 505 | if (c == -1) { | 511 | if (c == -1) { |
| 506 | break; | 512 | break; |
| 507 | } | 513 | } |
| @@ -543,6 +549,22 @@ static void parse_opts(int argc, char **argv) | |||
| 543 | } | 549 | } |
| 544 | plist_array_append_item(bundle_ids, plist_new_string(optarg)); | 550 | plist_array_append_item(bundle_ids, plist_new_string(optarg)); |
| 545 | break; | 551 | break; |
| 552 | case 's': | ||
| 553 | if (!*optarg) { | ||
| 554 | printf("ERROR: path for --sinf must not be empty!\n"); | ||
| 555 | print_usage(argc, argv, 1); | ||
| 556 | exit(2); | ||
| 557 | } | ||
| 558 | extsinf = strdup(optarg); | ||
| 559 | break; | ||
| 560 | case 'm': | ||
| 561 | if (!*optarg) { | ||
| 562 | printf("ERROR: path for --metadata must not be empty!\n"); | ||
| 563 | print_usage(argc, argv, 1); | ||
| 564 | exit(2); | ||
| 565 | } | ||
| 566 | extmeta = strdup(optarg); | ||
| 567 | break; | ||
| 546 | case 'w': | 568 | case 'w': |
| 547 | use_notifier = 1; | 569 | use_notifier = 1; |
| 548 | break; | 570 | break; |
| @@ -746,6 +768,37 @@ static void afc_upload_dir(afc_client_t afc, const char* path, const char* afcpa | |||
| 746 | } | 768 | } |
| 747 | } | 769 | } |
| 748 | 770 | ||
| 771 | static char *buf_from_file(const char *filename, size_t *size) | ||
| 772 | { | ||
| 773 | struct stat st; | ||
| 774 | FILE *fp = NULL; | ||
| 775 | |||
| 776 | if (stat(filename, &st) == -1 || (fp = fopen(filename, "r")) == NULL) { | ||
| 777 | return NULL; | ||
| 778 | } | ||
| 779 | size_t filesize = st.st_size; | ||
| 780 | if (filesize == 0) { | ||
| 781 | return NULL; | ||
| 782 | } | ||
| 783 | char *ibuf = malloc(filesize * sizeof(char)); | ||
| 784 | if (ibuf == NULL) { | ||
| 785 | return NULL; | ||
| 786 | } | ||
| 787 | size_t amount = fread(ibuf, 1, filesize, fp); | ||
| 788 | if (amount != filesize) { | ||
| 789 | fprintf(stderr, "ERROR: could not read %ld bytes from %s\n", filesize, filename); | ||
| 790 | free(ibuf); | ||
| 791 | return NULL; | ||
| 792 | } | ||
| 793 | fclose(fp); | ||
| 794 | |||
| 795 | if (size) { | ||
| 796 | *size = filesize; | ||
| 797 | } | ||
| 798 | |||
| 799 | return ibuf; | ||
| 800 | } | ||
| 801 | |||
| 749 | int main(int argc, char **argv) | 802 | int main(int argc, char **argv) |
| 750 | { | 803 | { |
| 751 | idevice_t device = NULL; | 804 | idevice_t device = NULL; |
| @@ -1153,21 +1206,41 @@ run_again: | |||
| 1153 | goto leave_cleanup; | 1206 | goto leave_cleanup; |
| 1154 | } | 1207 | } |
| 1155 | 1208 | ||
| 1156 | /* extract iTunesMetadata.plist from package */ | ||
| 1157 | char *zbuf = NULL; | 1209 | char *zbuf = NULL; |
| 1158 | uint32_t len = 0; | 1210 | uint32_t len = 0; |
| 1159 | plist_t meta_dict = NULL; | 1211 | plist_t meta_dict = NULL; |
| 1160 | if (zip_get_contents(zf, ITUNES_METADATA_PLIST_FILENAME, 0, &zbuf, &len) == 0) { | 1212 | |
| 1161 | meta = plist_new_data(zbuf, len); | 1213 | if (extmeta) { |
| 1162 | if (memcmp(zbuf, "bplist00", 8) == 0) { | 1214 | size_t flen = 0; |
| 1163 | plist_from_bin(zbuf, len, &meta_dict); | 1215 | zbuf = buf_from_file(extmeta, &flen); |
| 1216 | if (zbuf && flen) { | ||
| 1217 | meta = plist_new_data(zbuf, flen); | ||
| 1218 | if (memcmp(zbuf, "bplist00", 8) == 0) { | ||
| 1219 | plist_from_bin(zbuf, flen, &meta_dict); | ||
| 1220 | } else { | ||
| 1221 | plist_from_xml(zbuf, flen, &meta_dict); | ||
| 1222 | } | ||
| 1223 | free(zbuf); | ||
| 1164 | } else { | 1224 | } else { |
| 1165 | plist_from_xml(zbuf, len, &meta_dict); | 1225 | fprintf(stderr, "WARNING: could not load external iTunesMetadata %s!\n", extmeta); |
| 1166 | } | 1226 | } |
| 1167 | } else { | 1227 | zbuf = NULL; |
| 1168 | fprintf(stderr, "WARNING: could not locate %s in archive!\n", ITUNES_METADATA_PLIST_FILENAME); | 1228 | } |
| 1229 | |||
| 1230 | if (!meta && !meta_dict) { | ||
| 1231 | /* extract iTunesMetadata.plist from package */ | ||
| 1232 | if (zip_get_contents(zf, ITUNES_METADATA_PLIST_FILENAME, 0, &zbuf, &len) == 0) { | ||
| 1233 | meta = plist_new_data(zbuf, len); | ||
| 1234 | if (memcmp(zbuf, "bplist00", 8) == 0) { | ||
| 1235 | plist_from_bin(zbuf, len, &meta_dict); | ||
| 1236 | } else { | ||
| 1237 | plist_from_xml(zbuf, len, &meta_dict); | ||
| 1238 | } | ||
| 1239 | } else { | ||
| 1240 | fprintf(stderr, "WARNING: could not locate %s in archive!\n", ITUNES_METADATA_PLIST_FILENAME); | ||
| 1241 | } | ||
| 1242 | free(zbuf); | ||
| 1169 | } | 1243 | } |
| 1170 | free(zbuf); | ||
| 1171 | 1244 | ||
| 1172 | /* determine .app directory in archive */ | 1245 | /* determine .app directory in archive */ |
| 1173 | zbuf = NULL; | 1246 | zbuf = NULL; |
| @@ -1231,23 +1304,37 @@ run_again: | |||
| 1231 | goto leave_cleanup; | 1304 | goto leave_cleanup; |
| 1232 | } | 1305 | } |
| 1233 | 1306 | ||
| 1234 | char *sinfname = NULL; | 1307 | if (extsinf) { |
| 1235 | if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { | 1308 | size_t flen = 0; |
| 1236 | fprintf(stderr, "Out of memory!?\n"); | 1309 | zbuf = buf_from_file(extsinf, &flen); |
| 1237 | goto leave_cleanup; | 1310 | if (zbuf && flen) { |
| 1311 | sinf = plist_new_data(zbuf, flen); | ||
| 1312 | free(zbuf); | ||
| 1313 | } else { | ||
| 1314 | fprintf(stderr, "WARNING: could not load external SINF %s!\n", extsinf); | ||
| 1315 | } | ||
| 1316 | zbuf = NULL; | ||
| 1238 | } | 1317 | } |
| 1239 | free(bundleexecutable); | ||
| 1240 | 1318 | ||
| 1241 | /* extract .sinf from package */ | 1319 | if (!sinf) { |
| 1242 | zbuf = NULL; | 1320 | char *sinfname = NULL; |
| 1243 | len = 0; | 1321 | if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { |
| 1244 | if (zip_get_contents(zf, sinfname, 0, &zbuf, &len) == 0) { | 1322 | fprintf(stderr, "Out of memory!?\n"); |
| 1245 | sinf = plist_new_data(zbuf, len); | 1323 | goto leave_cleanup; |
| 1246 | } else { | 1324 | } |
| 1247 | fprintf(stderr, "WARNING: could not locate %s in archive!\n", sinfname); | 1325 | free(bundleexecutable); |
| 1326 | |||
| 1327 | /* extract .sinf from package */ | ||
| 1328 | zbuf = NULL; | ||
| 1329 | len = 0; | ||
| 1330 | if (zip_get_contents(zf, sinfname, 0, &zbuf, &len) == 0) { | ||
| 1331 | sinf = plist_new_data(zbuf, len); | ||
| 1332 | } else { | ||
| 1333 | fprintf(stderr, "WARNING: could not locate %s in archive!\n", sinfname); | ||
| 1334 | } | ||
| 1335 | free(sinfname); | ||
| 1336 | free(zbuf); | ||
| 1248 | } | 1337 | } |
| 1249 | free(sinfname); | ||
| 1250 | free(zbuf); | ||
| 1251 | 1338 | ||
| 1252 | /* copy archive to device */ | 1339 | /* copy archive to device */ |
| 1253 | pkgname = NULL; | 1340 | pkgname = NULL; |
| @@ -1582,6 +1669,8 @@ leave_cleanup: | |||
| 1582 | 1669 | ||
| 1583 | free(udid); | 1670 | free(udid); |
| 1584 | free(copy_path); | 1671 | free(copy_path); |
| 1672 | free(extsinf); | ||
| 1673 | free(extmeta); | ||
| 1585 | free(bundleidentifier); | 1674 | free(bundleidentifier); |
| 1586 | plist_free(bundle_ids); | 1675 | plist_free(bundle_ids); |
| 1587 | plist_free(return_attrs); | 1676 | plist_free(return_attrs); |
