diff options
| author | 2019-05-22 21:08:31 +0200 | |
|---|---|---|
| committer | 2023-07-21 03:30:28 +0700 | |
| commit | 03d93c67ff8266d6253d1dd30c38bb35be59a599 (patch) | |
| tree | 0c3008cb8d92fb21b23edbac246badb6de75130f | |
| parent | 5cbf60922b08238365fc4640d5fcb082574e557e (diff) | |
| download | ideviceinstaller-03d93c67ff8266d6253d1dd30c38bb35be59a599.tar.gz ideviceinstaller-03d93c67ff8266d6253d1dd30c38bb35be59a599.tar.bz2 | |
Add options for using external sinf and iTunes metadata
| -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";  char *udid = NULL;  char *cmdarg = NULL; +char *extsinf = NULL; +char *extmeta = NULL;  enum cmd_mode {  	CMD_NONE = 0, @@ -433,6 +435,8 @@ static void print_usage(int argc, char **argv, int is_error)  	"            (can be passed multiple times)\n"  	"  install PATH        Install app from package file specified by PATH.\n"  	"                      PATH can also be a .ipcc file for carrier bundles.\n" +	"        -s, --sinf PATH  Pass an external SINF file\n" +	"        -m, --metadata PATH  Pass an external iTunesMetadata file\n"  	"  uninstall BUNDLEID  Uninstall app specified by BUNDLEID.\n"  	"  upgrade PATH        Upgrade app from package file specified by PATH.\n"          "\n" @@ -491,6 +495,8 @@ static void parse_opts(int argc, char **argv)  		{ "all", no_argument, NULL, LIST_ALL },  		{ "xml", no_argument, NULL, OUTPUT_XML },  		{ "json", no_argument, NULL, OUTPUT_JSON }, +		{ "sinf", required_argument, NULL, 's' }, +		{ "metadata", required_argument, NULL, 'm' },  		{ "uninstall", no_argument, NULL, ARCHIVE_UNINSTALL },  		{ "app-only", no_argument, NULL, ARCHIVE_APP_ONLY },  		{ "docs-only", no_argument, NULL, ARCHIVE_DOCS_ONLY }, @@ -501,7 +507,7 @@ static void parse_opts(int argc, char **argv)  	int c;  	while (1) { -		c = getopt_long(argc, argv, "hu:nwdvb:a:", longopts, (int*)0); +		c = getopt_long(argc, argv, "hu:nwdvb:a:s:m:", longopts, (int*)0);  		if (c == -1) {  			break;  		} @@ -543,6 +549,22 @@ static void parse_opts(int argc, char **argv)  			}  			plist_array_append_item(bundle_ids, plist_new_string(optarg));  			break; +		case 's': +			if (!*optarg) { +				printf("ERROR: path for --sinf must not be empty!\n"); +				print_usage(argc, argv, 1); +				exit(2); +			} +			extsinf = strdup(optarg); +			break; +		case 'm': +			if (!*optarg) { +				printf("ERROR: path for --metadata must not be empty!\n"); +				print_usage(argc, argv, 1); +				exit(2); +			} +			extmeta = strdup(optarg); +			break;  		case 'w':  			use_notifier = 1;  			break; @@ -746,6 +768,37 @@ static void afc_upload_dir(afc_client_t afc, const char* path, const char* afcpa  	}  } +static char *buf_from_file(const char *filename, size_t *size) +{ +	struct stat st; +	FILE *fp = NULL; + +	if (stat(filename, &st) == -1 || (fp = fopen(filename, "r")) == NULL) { +		return NULL; +	} +	size_t filesize = st.st_size; +	if (filesize == 0) { +		return NULL; +	} +	char *ibuf = malloc(filesize * sizeof(char)); +	if (ibuf == NULL) { +		return NULL; +	} +	size_t amount = fread(ibuf, 1, filesize, fp); +	if (amount != filesize) { +		fprintf(stderr, "ERROR: could not read %ld bytes from %s\n", filesize, filename); +		free(ibuf); +		return NULL; +	} +	fclose(fp); + +	if (size) { +		*size = filesize; +	} + +	return ibuf; +} +  int main(int argc, char **argv)  {  	idevice_t device = NULL; @@ -1153,21 +1206,41 @@ run_again:  				goto leave_cleanup;  			} -			/* extract iTunesMetadata.plist from package */  			char *zbuf = NULL;  			uint32_t len = 0;  			plist_t meta_dict = NULL; -			if (zip_get_contents(zf, ITUNES_METADATA_PLIST_FILENAME, 0, &zbuf, &len) == 0) { -				meta = plist_new_data(zbuf, len); -				if (memcmp(zbuf, "bplist00", 8) == 0) { -					plist_from_bin(zbuf, len, &meta_dict); + +			if (extmeta) { +				size_t flen = 0; +				zbuf = buf_from_file(extmeta, &flen); +				if (zbuf && flen) { +					meta = plist_new_data(zbuf, flen); +					if (memcmp(zbuf, "bplist00", 8) == 0) { +						plist_from_bin(zbuf, flen, &meta_dict); +					} else { +						plist_from_xml(zbuf, flen, &meta_dict); +					} +					free(zbuf);  				} else { -					plist_from_xml(zbuf, len, &meta_dict); +					fprintf(stderr, "WARNING: could not load external iTunesMetadata %s!\n", extmeta);  				} -			} else { -				fprintf(stderr, "WARNING: could not locate %s in archive!\n", ITUNES_METADATA_PLIST_FILENAME); +				zbuf = NULL; +			} + +			if (!meta && !meta_dict) { +				/* extract iTunesMetadata.plist from package */ +				if (zip_get_contents(zf, ITUNES_METADATA_PLIST_FILENAME, 0, &zbuf, &len) == 0) { +					meta = plist_new_data(zbuf, len); +					if (memcmp(zbuf, "bplist00", 8) == 0) { +						plist_from_bin(zbuf, len, &meta_dict); +					} else { +						plist_from_xml(zbuf, len, &meta_dict); +					} +				} else { +					fprintf(stderr, "WARNING: could not locate %s in archive!\n", ITUNES_METADATA_PLIST_FILENAME); +				} +				free(zbuf);  			} -			free(zbuf);  			/* determine .app directory in archive */  			zbuf = NULL; @@ -1231,23 +1304,37 @@ run_again:  				goto leave_cleanup;  			} -			char *sinfname = NULL; -			if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { -				fprintf(stderr, "Out of memory!?\n"); -				goto leave_cleanup; +			if (extsinf) { +				size_t flen = 0; +				zbuf = buf_from_file(extsinf, &flen); +				if (zbuf && flen) { +					sinf = plist_new_data(zbuf, flen); +					free(zbuf); +				} else { +					fprintf(stderr, "WARNING: could not load external SINF %s!\n", extsinf); +				} +				zbuf = NULL;  			} -			free(bundleexecutable); -			/* extract .sinf from package */ -			zbuf = NULL; -			len = 0; -			if (zip_get_contents(zf, sinfname, 0, &zbuf, &len) == 0) { -				sinf = plist_new_data(zbuf, len); -			} else { -				fprintf(stderr, "WARNING: could not locate %s in archive!\n", sinfname); +			if (!sinf) { +				char *sinfname = NULL; +				if (asprintf(&sinfname, "Payload/%s.app/SC_Info/%s.sinf", bundleexecutable, bundleexecutable) < 0) { +					fprintf(stderr, "Out of memory!?\n"); +					goto leave_cleanup; +				} +				free(bundleexecutable); + +				/* extract .sinf from package */ +				zbuf = NULL; +				len = 0; +				if (zip_get_contents(zf, sinfname, 0, &zbuf, &len) == 0) { +					sinf = plist_new_data(zbuf, len); +				} else { +					fprintf(stderr, "WARNING: could not locate %s in archive!\n", sinfname); +				} +				free(sinfname); +				free(zbuf);  			} -			free(sinfname); -			free(zbuf);  			/* copy archive to device */  			pkgname = NULL; @@ -1582,6 +1669,8 @@ leave_cleanup:  	free(udid);  	free(copy_path); +	free(extsinf); +	free(extmeta);  	free(bundleidentifier);  	plist_free(bundle_ids);  	plist_free(return_attrs); | 
