diff options
-rw-r--r-- | src/ideviceinstaller.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index a99df2c..3aac8ae 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c @@ -35,6 +35,7 @@ #include <inttypes.h> #include <limits.h> #include <sys/stat.h> +#include <dirent.h> #include <libimobiledevice/libimobiledevice.h> #include <libimobiledevice/lockdown.h> @@ -428,6 +429,42 @@ static int afc_upload_file(afc_client_t afc, const char* filename, const char* d return 0; } +static void afc_upload_dir(afc_client_t afc, const char* path, const char* afcpath) +{ + afc_make_directory(afc, afcpath); + + DIR *dir = opendir(path); + if (dir) { + struct dirent* ep; + while ((ep = readdir(dir))) { + if ((strcmp(ep->d_name, ".") == 0) || (strcmp(ep->d_name, "..") == 0)) { + continue; + } + char *fpath = (char*)malloc(strlen(path)+1+strlen(ep->d_name)+1); + char *apath = (char*)malloc(strlen(afcpath)+1+strlen(ep->d_name)+1); + + struct stat st; + + strcpy(fpath, path); + strcat(fpath, "/"); + strcat(fpath, ep->d_name); + + strcpy(apath, afcpath); + strcat(apath, "/"); + strcat(apath, ep->d_name); + + if ((stat(fpath, &st) == 0) && S_ISDIR(st.st_mode)) { + afc_upload_dir(afc, fpath, apath); + } else { + afc_upload_file(afc, fpath, apath); + } + free(fpath); + free(apath); + } + closedir(dir); + } +} + int main(int argc, char **argv) { idevice_t phone = NULL; @@ -652,17 +689,19 @@ run_again: free(strs); } - /* open install package */ - int errp = 0; - struct zip *zf = zip_open(appid, 0, &errp); - if (!zf) { - fprintf(stderr, "ERROR: zip_open: %s: %d\n", appid, errp); - goto leave_cleanup; - } - plist_t client_opts = instproxy_client_options_new(); + /* open install package */ + int errp = 0; + struct zip *zf = NULL; + if ((strlen(appid) > 5) && (strcmp(&appid[strlen(appid)-5], ".ipcc") == 0)) { + zf = zip_open(appid, 0, &errp); + if (!zf) { + fprintf(stderr, "ERROR: zip_open: %s: %d\n", appid, errp); + goto leave_cleanup; + } + char* ipcc = strdup(appid); if ((asprintf(&pkgname, "%s/%s", PKG_PATH, basename(ipcc)) > 0) && pkgname) { afc_make_directory(afc, pkgname); @@ -749,7 +788,21 @@ run_again: printf("done.\n"); instproxy_client_options_add(client_opts, "PackageType", "CarrierBundle", NULL); + } else if (S_ISDIR(fst.st_mode)) { + /* upload developer app directory */ + instproxy_client_options_add(client_opts, "PackageType", "Developer", NULL); + + asprintf(&pkgname, "%s/%s", PKG_PATH, basename(appid)); + + printf("Uploading %s package contents...\n", basename(appid)); + afc_upload_dir(afc, appid, pkgname); } else { + zf = zip_open(appid, 0, &errp); + if (!zf) { + fprintf(stderr, "ERROR: zip_open: %s: %d\n", appid, errp); + goto leave_cleanup; + } + /* extract iTunesMetadata.plist from package */ char *zbuf = NULL; uint32_t len = 0; @@ -860,8 +913,10 @@ run_again: instproxy_client_options_add(client_opts, "iTunesMetadata", meta, NULL); } } - zip_unchange_all(zf); - zip_close(zf); + if (zf) { + zip_unchange_all(zf); + zip_close(zf); + } /* perform installation or upgrade */ if (install_mode) { |