mirror of
https://github.com/libimobiledevice/ideviceinstaller.git
synced 2026-03-18 20:02:26 +00:00
Add options for using external sinf and iTunes metadata
This commit is contained in:
committed by
Nikias Bassen
parent
5cbf60922b
commit
03d93c67ff
+113
-24
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user