diff options
Diffstat (limited to 'adb/commandline.c')
-rw-r--r-- | adb/commandline.c | 118 |
1 files changed, 90 insertions, 28 deletions
diff --git a/adb/commandline.c b/adb/commandline.c index 64fbe16..a69f867 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -1370,50 +1370,112 @@ static int delete_file(transport_type transport, char* serial, char* filename) return 0; } -int install_app(transport_type transport, char* serial, int argc, char** argv) +static const char* get_basename(const char* filename) +{ + const char* basename = adb_dirstop(filename); + if (basename) { + basename++; + return basename; + } else { + return filename; + } +} + +static int check_file(const char* filename) { struct stat st; - int err; - const char *const DATA_DEST = "/data/local/tmp/%s"; - const char *const SD_DEST = "/sdcard/tmp/%s"; + + if (filename == NULL) { + return 0; + } + + if (stat(filename, &st) != 0) { + fprintf(stderr, "can't find '%s' to install\n", filename); + return 1; + } + + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "can't install '%s' because it's not a file\n", filename); + return 1; + } + + return 0; +} + +int install_app(transport_type transport, char* serial, int argc, char** argv) +{ + static const char *const DATA_DEST = "/data/local/tmp/%s"; + static const char *const SD_DEST = "/sdcard/tmp/%s"; const char* where = DATA_DEST; - char to[PATH_MAX]; - char* filename = argv[argc - 1]; - const char* p; + char apk_dest[PATH_MAX]; + char verification_dest[PATH_MAX]; + char* apk_file; + char* verification_file = NULL; + int file_arg = -1; + int err; int i; - for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-s")) + for (i = 1; i < argc; i++) { + if (*argv[i] != '-') { + file_arg = i; + break; + } else if (!strcmp(argv[i], "-s")) { where = SD_DEST; + } } - p = adb_dirstop(filename); - if (p) { - p++; - snprintf(to, sizeof to, where, p); - } else { - snprintf(to, sizeof to, where, filename); + if (file_arg < 0) { + fprintf(stderr, "can't find filename in arguments"); + return 1; + } else if (file_arg + 2 < argc) { + fprintf(stderr, "too many files specified; only takes APK file and verifier file"); + return 1; } - if (p[0] == '\0') { + + apk_file = argv[file_arg]; + + if (file_arg != argc - 1) { + verification_file = argv[file_arg + 1]; } - err = stat(filename, &st); - if (err != 0) { - fprintf(stderr, "can't find '%s' to install\n", filename); + if (check_file(apk_file) || check_file(verification_file)) { return 1; } - if (!S_ISREG(st.st_mode)) { - fprintf(stderr, "can't install '%s' because it's not a file\n", - filename); - return 1; + + snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file)); + if (verification_file != NULL) { + snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file)); + + if (!strcmp(apk_dest, verification_dest)) { + fprintf(stderr, "APK and verification file can't have the same name\n"); + return 1; + } + } + + err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */); + if (err) { + return err; + } else { + argv[file_arg] = apk_dest; /* destination name, not source location */ } - if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) { - /* file in place; tell the Package Manager to install it */ - argv[argc - 1] = to; /* destination name, not source location */ - pm_command(transport, serial, argc, argv); - delete_file(transport, serial, to); + if (verification_file != NULL) { + err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */); + if (err) { + goto cleanup_apk; + } else { + argv[file_arg + 1] = verification_dest; /* destination name, not source location */ + } + } + + pm_command(transport, serial, argc, argv); + + if (verification_file != NULL) { + delete_file(transport, serial, verification_dest); } +cleanup_apk: + delete_file(transport, serial, apk_dest); + return err; } |