summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ideviceinstaller.c137
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);