diff options
Diffstat (limited to 'adb')
-rw-r--r-- | adb/Android.mk | 4 | ||||
-rw-r--r-- | adb/adb.h | 80 | ||||
-rw-r--r-- | adb/adb_auth_client.c | 2 | ||||
-rw-r--r-- | adb/adb_trace.h | 143 | ||||
-rw-r--r-- | adb/commandline.c | 328 | ||||
-rw-r--r-- | adb/fdevent.c | 13 | ||||
-rw-r--r-- | adb/file_sync_client.c | 110 | ||||
-rw-r--r-- | adb/file_sync_service.c | 9 | ||||
-rw-r--r-- | adb/file_sync_service.h | 2 | ||||
-rw-r--r-- | adb/remount_service.c | 41 | ||||
-rw-r--r-- | adb/services.c | 3 | ||||
-rw-r--r-- | adb/sysdeps.h | 3 | ||||
-rw-r--r-- | adb/sysdeps_win32.c | 4 | ||||
-rw-r--r-- | adb/usb_windows.c | 1 |
14 files changed, 442 insertions, 301 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index a82f026..3828ed3 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -40,13 +40,11 @@ ifeq ($(HOST_OS),windows) ifneq ($(strip $(USE_CYGWIN)),) # Pure cygwin case LOCAL_LDLIBS += -lpthread -lgdi32 - LOCAL_C_INCLUDES += /usr/include/w32api/ddk endif ifneq ($(strip $(USE_MINGW)),) # MinGW under Linux case LOCAL_LDLIBS += -lws2_32 -lgdi32 USE_SYSDEPS_WIN32 := 1 - LOCAL_C_INCLUDES += /usr/i586-mingw32msvc/include/ddk endif LOCAL_C_INCLUDES += development/host/windows/usb/api/ endif @@ -175,7 +173,7 @@ LOCAL_C_INCLUDES += external/openssl/include LOCAL_MODULE := adb -LOCAL_STATIC_LIBRARIES := libzipfile libunz libcutils +LOCAL_STATIC_LIBRARIES := libzipfile libunz libcutils liblog LOCAL_SHARED_LIBRARIES := libcrypto @@ -19,6 +19,7 @@ #include <limits.h> +#include "adb_trace.h" #include "transport.h" /* readx(), writex() */ #define MAX_PAYLOAD 4096 @@ -337,85 +338,6 @@ void put_apacket(apacket *p); int check_header(apacket *p); int check_data(apacket *p); -/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */ - -#define ADB_TRACE 1 - -/* IMPORTANT: if you change the following list, don't - * forget to update the corresponding 'tags' table in - * the adb_trace_init() function implemented in adb.c - */ -typedef enum { - TRACE_ADB = 0, /* 0x001 */ - TRACE_SOCKETS, - TRACE_PACKETS, - TRACE_TRANSPORT, - TRACE_RWX, /* 0x010 */ - TRACE_USB, - TRACE_SYNC, - TRACE_SYSDEPS, - TRACE_JDWP, /* 0x100 */ - TRACE_SERVICES, - TRACE_AUTH, -} AdbTrace; - -#if ADB_TRACE - -#if !ADB_HOST -/* - * When running inside the emulator, guest's adbd can connect to 'adb-debug' - * qemud service that can display adb trace messages (on condition that emulator - * has been started with '-debug adb' option). - */ - -/* Delivers a trace message to the emulator via QEMU pipe. */ -void adb_qemu_trace(const char* fmt, ...); -/* Macro to use to send ADB trace messages to the emulator. */ -#define DQ(...) adb_qemu_trace(__VA_ARGS__) -#else -#define DQ(...) ((void)0) -#endif /* !ADB_HOST */ - - extern int adb_trace_mask; - extern unsigned char adb_trace_output_count; - void adb_trace_init(void); - -# define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0) - - /* you must define TRACE_TAG before using this macro */ -# define D(...) \ - do { \ - if (ADB_TRACING) { \ - int save_errno = errno; \ - adb_mutex_lock(&D_lock); \ - fprintf(stderr, "%s::%s():", \ - __FILE__, __FUNCTION__); \ - errno = save_errno; \ - fprintf(stderr, __VA_ARGS__ ); \ - fflush(stderr); \ - adb_mutex_unlock(&D_lock); \ - errno = save_errno; \ - } \ - } while (0) -# define DR(...) \ - do { \ - if (ADB_TRACING) { \ - int save_errno = errno; \ - adb_mutex_lock(&D_lock); \ - errno = save_errno; \ - fprintf(stderr, __VA_ARGS__ ); \ - fflush(stderr); \ - adb_mutex_unlock(&D_lock); \ - errno = save_errno; \ - } \ - } while (0) -#else -# define D(...) ((void)0) -# define DR(...) ((void)0) -# define ADB_TRACING 0 -#endif /* ADB_TRACE */ - - #if !DEBUG_PACKETS #define print_packet(tag,p) do {} while (0) #endif diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c index 8409c63..55e9dca 100644 --- a/adb/adb_auth_client.c +++ b/adb/adb_auth_client.c @@ -175,7 +175,7 @@ static void adb_auth_event(int fd, unsigned events, void *data) if (events & FDE_READ) { ret = unix_read(fd, response, sizeof(response)); - if (ret < 0) { + if (ret <= 0) { D("Framework disconnect\n"); if (usb_transport) fdevent_remove(&usb_transport->auth_fde); diff --git a/adb/adb_trace.h b/adb/adb_trace.h new file mode 100644 index 0000000..8a5d9f8 --- /dev/null +++ b/adb/adb_trace.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ADB_TRACE_H +#define __ADB_TRACE_H + +#if !ADB_HOST +#include <android/log.h> +#endif + +/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */ +#define ADB_TRACE 1 + +/* IMPORTANT: if you change the following list, don't + * forget to update the corresponding 'tags' table in + * the adb_trace_init() function implemented in adb.c + */ +typedef enum { + TRACE_ADB = 0, /* 0x001 */ + TRACE_SOCKETS, + TRACE_PACKETS, + TRACE_TRANSPORT, + TRACE_RWX, /* 0x010 */ + TRACE_USB, + TRACE_SYNC, + TRACE_SYSDEPS, + TRACE_JDWP, /* 0x100 */ + TRACE_SERVICES, + TRACE_AUTH, + TRACE_FDEVENT, +} AdbTrace; + +#if ADB_TRACE + +#if !ADB_HOST +/* + * When running inside the emulator, guest's adbd can connect to 'adb-debug' + * qemud service that can display adb trace messages (on condition that emulator + * has been started with '-debug adb' option). + */ + +/* Delivers a trace message to the emulator via QEMU pipe. */ +void adb_qemu_trace(const char* fmt, ...); +/* Macro to use to send ADB trace messages to the emulator. */ +#define DQ(...) adb_qemu_trace(__VA_ARGS__) +#else +#define DQ(...) ((void)0) +#endif /* !ADB_HOST */ + +extern int adb_trace_mask; +extern unsigned char adb_trace_output_count; +void adb_trace_init(void); + +# define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0) + +/* you must define TRACE_TAG before using this macro */ +#if ADB_HOST +# define D(...) \ + do { \ + if (ADB_TRACING) { \ + int save_errno = errno; \ + adb_mutex_lock(&D_lock); \ + fprintf(stderr, "%s::%s():", \ + __FILE__, __FUNCTION__); \ + errno = save_errno; \ + fprintf(stderr, __VA_ARGS__ ); \ + fflush(stderr); \ + adb_mutex_unlock(&D_lock); \ + errno = save_errno; \ + } \ + } while (0) +# define DR(...) \ + do { \ + if (ADB_TRACING) { \ + int save_errno = errno; \ + adb_mutex_lock(&D_lock); \ + errno = save_errno; \ + fprintf(stderr, __VA_ARGS__ ); \ + fflush(stderr); \ + adb_mutex_unlock(&D_lock); \ + errno = save_errno; \ + } \ + } while (0) +# define DD(...) \ + do { \ + int save_errno = errno; \ + adb_mutex_lock(&D_lock); \ + fprintf(stderr, "%s::%s():", \ + __FILE__, __FUNCTION__); \ + errno = save_errno; \ + fprintf(stderr, __VA_ARGS__ ); \ + fflush(stderr); \ + adb_mutex_unlock(&D_lock); \ + errno = save_errno; \ + } while (0) +#else +# define D(...) \ + do { \ + if (ADB_TRACING) { \ + __android_log_print( \ + ANDROID_LOG_INFO, \ + __FUNCTION__, \ + __VA_ARGS__ ); \ + } \ + } while (0) +# define DR(...) \ + do { \ + if (ADB_TRACING) { \ + __android_log_print( \ + ANDROID_LOG_INFO, \ + __FUNCTION__, \ + __VA_ARGS__ ); \ + } \ + } while (0) +# define DD(...) \ + do { \ + __android_log_print( \ + ANDROID_LOG_INFO, \ + __FUNCTION__, \ + __VA_ARGS__ ); \ + } while (0) +#endif /* ADB_HOST */ +#else +# define D(...) ((void)0) +# define DR(...) ((void)0) +# define DD(...) ((void)0) +# define ADB_TRACING 0 +#endif /* ADB_TRACE */ + +#endif /* __ADB_TRACE_H */ diff --git a/adb/commandline.c b/adb/commandline.c index f4c2272..05b4ef6 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -15,6 +15,7 @@ */ #include <stdio.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -41,8 +42,9 @@ static int do_cmd(transport_type ttype, char* serial, char *cmd, ...); void get_my_path(char *s, size_t maxLen); int find_sync_dirs(const char *srcarg, - char **android_srcdir_out, char **data_srcdir_out); + char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out); int install_app(transport_type transport, char* serial, int argc, char** argv); +int install_multiple_app(transport_type transport, char* serial, int argc, char** argv); int uninstall_app(transport_type transport, char* serial, int argc, char** argv); static const char *gProductOutPath = NULL; @@ -151,12 +153,15 @@ void help() " - remove a specific reversed socket connection\n" " adb reverse --remove-all - remove all reversed socket connections from device\n" " adb jdwp - list PIDs of processes hosting a JDWP transport\n" - " adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n" + " adb install [-lrtsd] <file>\n" + " adb install-multiple [-lrtsdp] <file...>\n" " - push this package file to the device and install it\n" - " ('-l' means forward-lock the app)\n" - " ('-r' means reinstall the app, keeping its data)\n" - " ('-s' means install on SD card instead of internal storage)\n" - " ('--algo', '--key', and '--iv' mean the file is encrypted already)\n" + " (-l: forward lock application)\n" + " (-r: replace existing application)\n" + " (-t: allow test packages)\n" + " (-s: install application on sdcard)\n" + " (-d: allow version code downgrade)\n" + " (-p: partial application install)\n" " adb uninstall [-k] <package> - remove this app package from the device\n" " ('-k' means keep the data and cache directories)\n" " adb bugreport - return all information from the device\n" @@ -195,7 +200,7 @@ void help() " adb get-serialno - prints: <serial-number>\n" " adb get-devpath - prints: <device-path>\n" " adb status-window - continuously print device status for a specified device\n" - " adb remount - remounts the /system partition on the device read-write\n" + " adb remount - remounts the /system and /vendor (if present) partitions on the device read-write\n" " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n" " adb reboot-bootloader - reboots the device into the bootloader\n" " adb root - restarts the adbd daemon with root permissions\n" @@ -211,9 +216,9 @@ void help() "adb sync notes: adb sync [ <directory> ]\n" " <localdir> can be interpreted in several ways:\n" "\n" - " - If <directory> is not specified, both /system and /data partitions will be updated.\n" + " - If <directory> is not specified, /system, /vendor (if present), and /data partitions will be updated.\n" "\n" - " - If it is \"system\" or \"data\", only the corresponding partition\n" + " - If it is \"system\", \"vendor\" or \"data\", only the corresponding partition\n" " is updated.\n" "\n" "environmental variables:\n" @@ -279,6 +284,24 @@ static void read_and_dump(int fd) } } +static void read_status_line(int fd, char* buf, size_t count) +{ + count--; + while (count > 0) { + int len = adb_read(fd, buf, count); + if (len == 0) { + break; + } else if (len < 0) { + if (errno == EINTR) continue; + break; + } + + buf += len; + count -= len; + } + *buf = '\0'; +} + static void copy_to_file(int inFd, int outFd) { const size_t BUFSIZE = 32 * 1024; char* buf = (char*) malloc(BUFSIZE); @@ -653,7 +676,12 @@ static void status_window(transport_type ttype, const char* serial) } } -/** Duplicate and escape given argument. */ +static int should_escape(const char c) +{ + return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')'); +} + +/* Duplicate and escape given argument. */ static char *escape_arg(const char *s) { const char *ts; @@ -664,7 +692,7 @@ static char *escape_arg(const char *s) alloc_len = 0; for (ts = s; *ts != '\0'; ts++) { alloc_len++; - if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { + if (should_escape(*ts)) { alloc_len++; } } @@ -682,7 +710,7 @@ static char *escape_arg(const char *s) dest = ret; for (ts = s; *ts != '\0'; ts++) { - if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { + if (should_escape(*ts)) { *dest++ = '\\'; } *dest++ = *ts; @@ -1575,7 +1603,7 @@ top: parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, ©_attrs); if ((lpath != NULL) && (rpath != NULL)) { - return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress); + return do_sync_push(lpath, rpath, show_progress); } return usage(); @@ -1595,18 +1623,23 @@ top: return usage(); } - if(!strcmp(argv[0], "install")) { + if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); return install_app(ttype, serial, argc, argv); } - if(!strcmp(argv[0], "uninstall")) { + if (!strcmp(argv[0], "install-multiple")) { + if (argc < 2) return usage(); + return install_multiple_app(ttype, serial, argc, argv); + } + + if (!strcmp(argv[0], "uninstall")) { if (argc < 2) return usage(); return uninstall_app(ttype, serial, argc, argv); } if(!strcmp(argv[0], "sync")) { - char *srcarg, *android_srcpath, *data_srcpath; + char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath; int listonly = 0; int ret; @@ -1626,15 +1659,18 @@ top: } else { return usage(); } - ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath); + ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath); if(ret != 0) return usage(); if(android_srcpath != NULL) ret = do_sync_sync(android_srcpath, "/system", listonly); + if(ret == 0 && vendor_srcpath != NULL) + ret = do_sync_sync(vendor_srcpath, "/vendor", listonly); if(ret == 0 && data_srcpath != NULL) ret = do_sync_sync(data_srcpath, "/data", listonly); free(android_srcpath); + free(vendor_srcpath); free(data_srcpath); return ret; } @@ -1748,25 +1784,30 @@ static int do_cmd(transport_type ttype, char* serial, char *cmd, ...) } int find_sync_dirs(const char *srcarg, - char **android_srcdir_out, char **data_srcdir_out) + char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out) { - char *android_srcdir, *data_srcdir; + char *android_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL; + struct stat st; if(srcarg == NULL) { android_srcdir = product_file("system"); data_srcdir = product_file("data"); + vendor_srcdir = product_file("vendor"); + /* Check if vendor partition exists */ + if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode)) + vendor_srcdir = NULL; } else { /* srcarg may be "data", "system" or NULL. * if srcarg is NULL, then both data and system are synced */ if(strcmp(srcarg, "system") == 0) { android_srcdir = product_file("system"); - data_srcdir = NULL; } else if(strcmp(srcarg, "data") == 0) { - android_srcdir = NULL; data_srcdir = product_file("data"); + } else if(strcmp(srcarg, "vendor") == 0) { + vendor_srcdir = product_file("vendor"); } else { - /* It's not "system" or "data". + /* It's not "system", "vendor", or "data". */ return 1; } @@ -1777,11 +1818,15 @@ int find_sync_dirs(const char *srcarg, else free(android_srcdir); - if(data_srcdir_out != NULL) - *data_srcdir_out = data_srcdir; + if(vendor_srcdir_out != NULL) + *vendor_srcdir_out = vendor_srcdir; else - free(data_srcdir); + free(vendor_srcdir); + if(data_srcdir_out != NULL) + *data_srcdir_out = data_srcdir; + else + free(data_srcdir); return 0; } @@ -1826,7 +1871,7 @@ static int delete_file(transport_type transport, char* serial, char* filename) char buf[4096]; char* quoted; - snprintf(buf, sizeof(buf), "shell:rm "); + snprintf(buf, sizeof(buf), "shell:rm -f "); quoted = escape_arg(filename); strncat(buf, quoted, sizeof(buf)-1); free(quoted); @@ -1846,117 +1891,186 @@ static const char* get_basename(const char* filename) } } -static int check_file(const char* filename) +int install_app(transport_type transport, char* serial, int argc, char** argv) { - struct stat st; + static const char *const DATA_DEST = "/data/local/tmp/%s"; + static const char *const SD_DEST = "/sdcard/tmp/%s"; + const char* where = DATA_DEST; + int i; + struct stat sb; - if (filename == NULL) { - return 0; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-s")) { + where = SD_DEST; + } } - if (stat(filename, &st) != 0) { - fprintf(stderr, "can't find '%s' to install\n", filename); - return 1; + // Find last APK argument. + // All other arguments passed through verbatim. + int last_apk = -1; + for (i = argc - 1; i >= 0; i--) { + char* file = argv[i]; + char* dot = strrchr(file, '.'); + if (dot && !strcasecmp(dot, ".apk")) { + if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) { + fprintf(stderr, "Invalid APK file: %s\n", file); + return -1; + } + + last_apk = i; + break; + } } - if (!S_ISREG(st.st_mode)) { - fprintf(stderr, "can't install '%s' because it's not a file\n", filename); - return 1; + if (last_apk == -1) { + fprintf(stderr, "Missing APK file\n"); + return -1; } - return 0; + char* apk_file = argv[last_apk]; + char apk_dest[PATH_MAX]; + snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file)); + int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */); + if (err) { + goto cleanup_apk; + } else { + argv[last_apk] = apk_dest; /* destination name, not source location */ + } + + pm_command(transport, serial, argc, argv); + +cleanup_apk: + delete_file(transport, serial, apk_dest); + return err; } -int install_app(transport_type transport, char* serial, int argc, char** argv) +int install_multiple_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 apk_dest[PATH_MAX]; - char verification_dest[PATH_MAX]; - char* apk_file; - char* verification_file = NULL; - int file_arg = -1; - int err; + char buf[1024]; int i; - int verify_apk = 1; + struct stat sb; + unsigned long long total_size = 0; + + // Find all APK arguments starting at end. + // All other arguments passed through verbatim. + int first_apk = -1; + for (i = argc - 1; i >= 0; i--) { + char* file = argv[i]; + char* dot = strrchr(file, '.'); + if (dot && !strcasecmp(dot, ".apk")) { + if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) { + fprintf(stderr, "Invalid APK file: %s\n", file); + return -1; + } - for (i = 1; i < argc; i++) { - if (*argv[i] != '-') { - file_arg = i; + total_size += sb.st_size; + first_apk = i; + } else { break; - } else if (!strcmp(argv[i], "-i")) { - // Skip the installer package name. - i++; - } else if (!strcmp(argv[i], "-s")) { - where = SD_DEST; - } else if (!strcmp(argv[i], "--algo")) { - verify_apk = 0; - i++; - } else if (!strcmp(argv[i], "--iv")) { - verify_apk = 0; - i++; - } else if (!strcmp(argv[i], "--key")) { - verify_apk = 0; - i++; - } else if (!strcmp(argv[i], "--abi")) { - i++; - } - } - - if (file_arg < 0) { - fprintf(stderr, "can't find filename in arguments\n"); - return 1; - } else if (file_arg + 2 < argc) { - fprintf(stderr, "too many files specified; only takes APK file and verifier file\n"); + } + } + + if (first_apk == -1) { + fprintf(stderr, "Missing APK file\n"); return 1; } - apk_file = argv[file_arg]; + snprintf(buf, sizeof(buf), "exec:pm install-create -S %lld", total_size); + for (i = 1; i < first_apk; i++) { + char *quoted = escape_arg(argv[i]); + strncat(buf, " ", sizeof(buf) - 1); + strncat(buf, quoted, sizeof(buf) - 1); + free(quoted); + } - if (file_arg != argc - 1) { - verification_file = argv[file_arg + 1]; + // Create install session + int fd = adb_connect(buf); + if (fd < 0) { + fprintf(stderr, "Connect error for create: %s\n", adb_error()); + return -1; } + read_status_line(fd, buf, sizeof(buf)); + adb_close(fd); - if (check_file(apk_file) || check_file(verification_file)) { - return 1; + int session_id = -1; + if (!strncmp("Success", buf, 7)) { + char* start = strrchr(buf, '['); + char* end = strrchr(buf, ']'); + if (start && end) { + *end = '\0'; + session_id = strtol(start + 1, NULL, 10); + } + } + if (session_id < 0) { + fprintf(stderr, "Failed to create session\n"); + fputs(buf, stderr); + 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)); + // Valid session, now stream the APKs + int success = 1; + for (i = first_apk; i < argc; i++) { + char* file = argv[i]; + if (stat(file, &sb) == -1) { + fprintf(stderr, "Failed to stat %s\n", file); + success = 0; + goto finalize_session; + } - if (!strcmp(apk_dest, verification_dest)) { - fprintf(stderr, "APK and verification file can't have the same name\n"); - return 1; + snprintf(buf, sizeof(buf), "exec:pm install-write -S %lld %d %d_%s -", + (long long int) sb.st_size, session_id, i, get_basename(file)); + + int localFd = adb_open(file, O_RDONLY); + if (localFd < 0) { + fprintf(stderr, "Failed to open %s: %s\n", file, adb_error()); + success = 0; + goto finalize_session; } - } - err = do_sync_push(apk_file, apk_dest, verify_apk, 0 /* no show progress */); - if (err) { - goto cleanup_apk; - } else { - argv[file_arg] = apk_dest; /* destination name, not source location */ - } + int remoteFd = adb_connect(buf); + if (remoteFd < 0) { + fprintf(stderr, "Connect error for write: %s\n", adb_error()); + adb_close(localFd); + success = 0; + goto finalize_session; + } - if (verification_file != NULL) { - err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */, - 0 /* no show progress */); - if (err) { - goto cleanup_apk; - } else { - argv[file_arg + 1] = verification_dest; /* destination name, not source location */ + copy_to_file(localFd, remoteFd); + read_status_line(remoteFd, buf, sizeof(buf)); + + adb_close(localFd); + adb_close(remoteFd); + + if (strncmp("Success", buf, 7)) { + fprintf(stderr, "Failed to write %s\n", file); + fputs(buf, stderr); + success = 0; + goto finalize_session; } } - pm_command(transport, serial, argc, argv); - -cleanup_apk: - if (verification_file != NULL) { - delete_file(transport, serial, verification_dest); +finalize_session: + // Commit session if we streamed everything okay; otherwise abandon + if (success) { + snprintf(buf, sizeof(buf), "exec:pm install-commit %d", session_id); + } else { + snprintf(buf, sizeof(buf), "exec:pm install-abandon %d", session_id); } - delete_file(transport, serial, apk_dest); + fd = adb_connect(buf); + if (fd < 0) { + fprintf(stderr, "Connect error for finalize: %s\n", adb_error()); + return -1; + } + read_status_line(fd, buf, sizeof(buf)); + adb_close(fd); - return err; + if (!strncmp("Success", buf, 7)) { + fputs(buf, stderr); + return 0; + } else { + fprintf(stderr, "Failed to finalize session\n"); + fputs(buf, stderr); + return -1; + } } diff --git a/adb/fdevent.c b/adb/fdevent.c index 5c374a7..43e600c 100644 --- a/adb/fdevent.c +++ b/adb/fdevent.c @@ -28,10 +28,12 @@ #include <stdarg.h> #include <stddef.h> +#include "adb_trace.h" #include "fdevent.h" #include "transport.h" #include "sysdeps.h" +#define TRACE_TAG TRACE_FDEVENT /* !!! Do not enable DEBUG for the adb that will run as the server: ** both stdout and stderr are used to communicate between the client @@ -57,16 +59,6 @@ static void fatal(const char *fn, const char *fmt, ...) #define FATAL(x...) fatal(__FUNCTION__, x) #if DEBUG -#define D(...) \ - do { \ - adb_mutex_lock(&D_lock); \ - int save_errno = errno; \ - fprintf(stderr, "%s::%s():", __FILE__, __FUNCTION__); \ - errno = save_errno; \ - fprintf(stderr, __VA_ARGS__); \ - adb_mutex_unlock(&D_lock); \ - errno = save_errno; \ - } while(0) static void dump_fde(fdevent *fde, const char *info) { adb_mutex_lock(&D_lock); @@ -78,7 +70,6 @@ static void dump_fde(fdevent *fde, const char *info) adb_mutex_unlock(&D_lock); } #else -#define D(...) ((void)0) #define dump_fde(fde, info) do { } while(0) #endif diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c index d3cb113..ad59e81 100644 --- a/adb/file_sync_client.c +++ b/adb/file_sync_client.c @@ -335,7 +335,7 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf) #endif static int sync_send(int fd, const char *lpath, const char *rpath, - unsigned mtime, mode_t mode, int verifyApk, int show_progress) + unsigned mtime, mode_t mode, int show_progress) { syncmsg msg; int len, r; @@ -350,63 +350,6 @@ static int sync_send(int fd, const char *lpath, const char *rpath, snprintf(tmp, sizeof(tmp), ",%d", mode); r = strlen(tmp); - if (verifyApk) { - int lfd; - zipfile_t zip; - zipentry_t entry; - int amt; - - // if we are transferring an APK file, then sanity check to make sure - // we have a real zip file that contains an AndroidManifest.xml - // this requires that we read the entire file into memory. - lfd = adb_open(lpath, O_RDONLY); - if(lfd < 0) { - fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno)); - return -1; - } - - size = adb_lseek(lfd, 0, SEEK_END); - if (size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) { - fprintf(stderr, "error seeking in file '%s'\n", lpath); - adb_close(lfd); - return 1; - } - - file_buffer = (char *)malloc(size); - if (file_buffer == NULL) { - fprintf(stderr, "could not allocate buffer for '%s'\n", - lpath); - adb_close(lfd); - return 1; - } - amt = adb_read(lfd, file_buffer, size); - if (amt != size) { - fprintf(stderr, "error reading from file: '%s'\n", lpath); - adb_close(lfd); - free(file_buffer); - return 1; - } - - adb_close(lfd); - - zip = init_zipfile(file_buffer, size); - if (zip == NULL) { - fprintf(stderr, "file '%s' is not a valid zip file\n", - lpath); - free(file_buffer); - return 1; - } - - entry = lookup_zipentry(zip, "AndroidManifest.xml"); - release_zipfile(zip); - if (entry == NULL) { - fprintf(stderr, "file '%s' does not contain AndroidManifest.xml\n", - lpath); - free(file_buffer); - return 1; - } - } - msg.req.id = ID_SEND; msg.req.namelen = htoll(len + r); @@ -697,30 +640,33 @@ static int local_build_list(copyinfo **filelist, continue; strcpy(stat_path, lpath); strcat(stat_path, de->d_name); - stat(stat_path, &st); - if (S_ISDIR(st.st_mode)) { - ci = mkcopyinfo(lpath, rpath, name, 1); - ci->next = dirlist; - dirlist = ci; - } else { - ci = mkcopyinfo(lpath, rpath, name, 0); - if(lstat(ci->src, &st)) { - fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno)); - free(ci); - closedir(d); - return -1; - } - if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { - fprintf(stderr, "skipping special file '%s'\n", ci->src); - free(ci); + if(!lstat(stat_path, &st)) { + if (S_ISDIR(st.st_mode)) { + ci = mkcopyinfo(lpath, rpath, name, 1); + ci->next = dirlist; + dirlist = ci; } else { - ci->time = st.st_mtime; - ci->mode = st.st_mode; - ci->size = st.st_size; - ci->next = *filelist; - *filelist = ci; + ci = mkcopyinfo(lpath, rpath, name, 0); + if(lstat(ci->src, &st)) { + fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno)); + free(ci); + closedir(d); + return -1; + } + if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { + fprintf(stderr, "skipping special file '%s'\n", ci->src); + free(ci); + } else { + ci->time = st.st_mtime; + ci->mode = st.st_mode; + ci->size = st.st_size; + ci->next = *filelist; + *filelist = ci; + } } + } else { + fprintf(stderr, "cannot lstat '%s': %s\n",stat_path , strerror(errno)); } } @@ -786,7 +732,7 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i if(ci->flag == 0) { fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst); if(!listonly && - sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */, + sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no show progress */)) { return 1; } @@ -805,7 +751,7 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i } -int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress) +int do_sync_push(const char *lpath, const char *rpath, int show_progress) { struct stat st; unsigned mode; @@ -852,7 +798,7 @@ int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_p rpath = tmp; } BEGIN(); - if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk, show_progress)) { + if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, show_progress)) { return 1; } else { END(); diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c index b297552..7933858 100644 --- a/adb/file_sync_service.c +++ b/adb/file_sync_service.c @@ -39,6 +39,11 @@ static bool is_on_system(const char *name) { return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0); } +static bool is_on_vendor(const char *name) { + const char *VENDOR = "/vendor/"; + return (strncmp(VENDOR, name, strlen(VENDOR)) == 0); +} + static int mkdirs(char *name) { int ret; @@ -54,7 +59,7 @@ static int mkdirs(char *name) x = adb_dirstart(x); if(x == 0) return 0; *x = 0; - if (is_on_system(name)) { + if (is_on_system(name) || is_on_vendor(name)) { fs_config(name, 1, &uid, &gid, &mode, &cap); } ret = adb_mkdir(name, mode); @@ -369,7 +374,7 @@ static int do_send(int s, char *path, char *buffer) if(*tmp == '/') { tmp++; } - if (is_on_system(path)) { + if (is_on_system(path) || is_on_vendor(path)) { fs_config(tmp, 0, &uid, &gid, &mode, &cap); } ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink); diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h index 8ea239e..5dd2e80 100644 --- a/adb/file_sync_service.h +++ b/adb/file_sync_service.h @@ -78,7 +78,7 @@ typedef union { void file_sync_service(int fd, void *cookie); int do_sync_ls(const char *path); -int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress); +int do_sync_push(const char *lpath, const char *rpath, int show_progress); int do_sync_sync(const char *lpath, const char *rpath, int listonly); int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int pullTime); diff --git a/adb/remount_service.c b/adb/remount_service.c index 3a4535e..72d15a1 100644 --- a/adb/remount_service.c +++ b/adb/remount_service.c @@ -29,6 +29,7 @@ static int system_ro = 1; +static int vendor_ro = 1; /* Returns the device used to mount a directory in /proc/mounts */ static char *find_mount(const char *dir) @@ -67,18 +68,27 @@ static char *find_mount(const char *dir) return NULL; } +static int hasVendorPartition() +{ + struct stat info; + if (!lstat("/vendor", &info)) + if ((info.st_mode & S_IFMT) == S_IFDIR) + return true; + return false; +} + /* Init mounts /system as read only, remount to enable writes. */ -static int remount_system() +static int remount(const char* dir, int* dir_ro) { char *dev; int fd; int OFF = 0; - if (system_ro == 0) { + if (dir_ro == 0) { return 0; } - dev = find_mount("/system"); + dev = find_mount(dir); if (!dev) return -1; @@ -90,11 +100,11 @@ static int remount_system() ioctl(fd, BLKROSET, &OFF); adb_close(fd); - system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL); + *dir_ro = mount(dev, dir, "none", MS_REMOUNT, NULL); free(dev); - return system_ro; + return *dir_ro; } static void write_string(int fd, const char* str) @@ -104,14 +114,23 @@ static void write_string(int fd, const char* str) void remount_service(int fd, void *cookie) { - int ret = remount_system(); + char buffer[200]; + if (remount("/system", &system_ro)) { + snprintf(buffer, sizeof(buffer), "remount of system failed: %s\n",strerror(errno)); + write_string(fd, buffer); + } + + if (hasVendorPartition()) { + if (remount("/vendor", &vendor_ro)) { + snprintf(buffer, sizeof(buffer), "remount of vendor failed: %s\n",strerror(errno)); + write_string(fd, buffer); + } + } - if (!ret) - write_string(fd, "remount succeeded\n"); + if (!system_ro && (!vendor_ro || !hasVendorPartition())) + write_string(fd, "remount succeeded\n"); else { - char buffer[200]; - snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno)); - write_string(fd, buffer); + write_string(fd, "remount failed\n"); } adb_close(fd); diff --git a/adb/services.c b/adb/services.c index 2c20b81..e61371a 100644 --- a/adb/services.c +++ b/adb/services.c @@ -281,9 +281,10 @@ static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg adb_close(sv[0]); init_subproc_child(); - // Only hook up stdin/stdout; drop stderr dup2(sv[1], STDIN_FILENO); dup2(sv[1], STDOUT_FILENO); + dup2(sv[1], STDERR_FILENO); + adb_close(sv[1]); execl(cmd, cmd, arg0, arg1, NULL); diff --git a/adb/sysdeps.h b/adb/sysdeps.h index ba4306f..cc1f839 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -26,8 +26,8 @@ #ifdef _WIN32 -#include <windows.h> #include <winsock2.h> +#include <windows.h> #include <ws2tcpip.h> #include <process.h> #include <fcntl.h> @@ -35,6 +35,7 @@ #include <sys/stat.h> #include <errno.h> #include <ctype.h> +#include <direct.h> #define OS_PATH_SEPARATOR '\\' #define OS_PATH_SEPARATOR_STR "\\" diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c index 29f58ec..b082c6d 100644 --- a/adb/sysdeps_win32.c +++ b/adb/sysdeps_win32.c @@ -1,6 +1,6 @@ #include "sysdeps.h" -#include <windows.h> #include <winsock2.h> +#include <windows.h> #include <stdio.h> #include <errno.h> #define TRACE_TAG TRACE_SYSDEPS @@ -1549,7 +1549,7 @@ _wait_for_all(HANDLE* handles, int handles_count) * reset" event that will remain set once it was set. */ main_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (main_event == NULL) { - D("Unable to create main event. Error: %d", GetLastError()); + D("Unable to create main event. Error: %d", (int)GetLastError()); free(threads); return (int)WAIT_FAILED; } diff --git a/adb/usb_windows.c b/adb/usb_windows.c index 1309a78..b7ad913 100644 --- a/adb/usb_windows.c +++ b/adb/usb_windows.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <winsock2.h> #include <windows.h> #include <winerror.h> #include <errno.h> |