diff options
author | Elliott Hughes <enh@google.com> | 2015-04-30 17:32:03 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2015-05-01 17:09:34 -0700 |
commit | 92af733ee202caa3b5475fe27fcc81582f11e7c8 (patch) | |
tree | 0e5d4bc49cc6299f80a0cccd4ba205d5dfcbb3cb /adb | |
parent | 5cffd971997ace97ebfd2ecb7d43a64c03cf3169 (diff) | |
download | system_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.zip system_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.tar.gz system_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.tar.bz2 |
More adb buffer fixes.
This patch factors out a lot of the basic protocol code: sending OKAY,
sending FAIL, and sending a length-prefixed string.
ADB_TRACE has been non-optional for a long time, so let's just remove
the #ifs.
Also actually build the device tracker test tool (and remove its duplicate).
Bug: http://b/20666660
Change-Id: I6c7d59f18707bdc62ca69dea45547617f9f31fc6
(cherry picked from commit e67f1f87d9b1188ec8617035db7006c37ee7b21e)
Diffstat (limited to 'adb')
-rw-r--r-- | adb/Android.mk | 15 | ||||
-rw-r--r-- | adb/adb.cpp | 123 | ||||
-rw-r--r-- | adb/adb.h | 3 | ||||
-rw-r--r-- | adb/adb_client.cpp | 10 | ||||
-rw-r--r-- | adb/adb_io.cpp | 35 | ||||
-rw-r--r-- | adb/adb_io.h | 20 | ||||
-rw-r--r-- | adb/adb_io_test.cpp | 4 | ||||
-rw-r--r-- | adb/adb_listeners.cpp | 52 | ||||
-rw-r--r-- | adb/adb_listeners.h | 4 | ||||
-rw-r--r-- | adb/adb_trace.h | 31 | ||||
-rw-r--r-- | adb/adb_utils.cpp | 29 | ||||
-rw-r--r-- | adb/adb_utils.h | 2 | ||||
-rw-r--r-- | adb/commandline.cpp | 13 | ||||
-rw-r--r-- | adb/remount_service.cpp | 17 | ||||
-rw-r--r-- | adb/services.cpp | 135 | ||||
-rw-r--r-- | adb/set_verity_enable_state_service.cpp | 1 | ||||
-rw-r--r-- | adb/sockets.cpp | 37 | ||||
-rw-r--r-- | adb/sysdeps_win32.cpp | 1 | ||||
-rw-r--r-- | adb/test_track_devices.cpp | 65 | ||||
-rw-r--r-- | adb/test_track_jdwp.cpp | 97 | ||||
-rw-r--r-- | adb/transport.cpp | 205 | ||||
-rw-r--r-- | adb/transport.h | 6 |
22 files changed, 306 insertions, 599 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index 9b6e147..dd1343b 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -124,6 +124,21 @@ endif include $(BUILD_HOST_NATIVE_TEST) +# adb device tracker (used by ddms) test tool +# ========================================================= + +ifeq ($(HOST_OS),linux) +include $(CLEAR_VARS) +LOCAL_CLANG := $(adb_host_clang) +LOCAL_MODULE := adb_device_tracker_test +LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS) +LOCAL_SRC_FILES := test_track_devices.cpp +LOCAL_SHARED_LIBRARIES := liblog libbase +LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils +LOCAL_LDLIBS += -lrt -ldl -lpthread +include $(BUILD_HOST_EXECUTABLE) +endif + # adb host tool # ========================================================= include $(CLEAR_VARS) diff --git a/adb/adb.cpp b/adb/adb.cpp index e526914..11c65da 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -48,9 +48,7 @@ #include <sys/mount.h> #endif -#if ADB_TRACE ADB_MUTEX_DEFINE( D_lock ); -#endif int HOST = 0; @@ -322,28 +320,6 @@ static size_t fill_connect_data(char *buf, size_t bufsize) #endif } -#if !ADB_HOST -static void send_msg_with_header(int fd, const char* msg, size_t msglen) { - char header[5]; - if (msglen > 0xffff) - msglen = 0xffff; - snprintf(header, sizeof(header), "%04x", (unsigned)msglen); - WriteFdExactly(fd, header, 4); - WriteFdExactly(fd, msg, msglen); -} -#endif - -#if ADB_HOST -static void send_msg_with_okay(int fd, const char* msg, size_t msglen) { - char header[9]; - if (msglen > 0xffff) - msglen = 0xffff; - snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen); - WriteFdExactly(fd, header, 8); - WriteFdExactly(fd, msg, msglen); -} -#endif // ADB_HOST - void send_connect(atransport *t) { D("Calling send_connect \n"); @@ -356,32 +332,6 @@ void send_connect(atransport *t) send_packet(cp, t); } -#if ADB_HOST -static const char* connection_state_name(atransport *t) -{ - if (t == NULL) { - return "unknown"; - } - - switch(t->connection_state) { - case CS_BOOTLOADER: - return "bootloader"; - case CS_DEVICE: - return "device"; - case CS_RECOVERY: - return "recovery"; - case CS_SIDELOAD: - return "sideload"; - case CS_OFFLINE: - return "offline"; - case CS_UNAUTHORIZED: - return "unauthorized"; - default: - return "unknown"; - } -} -#endif // ADB_HOST - // qual_overwrite is used to overwrite a qualifier string. dst is a // pointer to a char pointer. It is assumed that if *dst is non-NULL, it // was malloc'ed and needs to freed. *dst will be set to a dup of src. @@ -752,20 +702,11 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri { if (!strcmp(service, "list-forward")) { // Create the list of forward redirections. - int buffer_size = format_listeners(NULL, 0); - // Add one byte for the trailing zero. - char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1)); - if (buffer == nullptr) { - sendfailmsg(reply_fd, "not enough memory"); - return 1; - } - (void) format_listeners(buffer, buffer_size + 1); + std::string listeners = format_listeners(); #if ADB_HOST - send_msg_with_okay(reply_fd, buffer, buffer_size); -#else - send_msg_with_header(reply_fd, buffer, buffer_size); + SendOkay(reply_fd); #endif - free(buffer); + SendProtocolString(reply_fd, listeners); return 1; } @@ -773,9 +714,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri remove_all_listeners(); #if ADB_HOST /* On the host: 1st OKAY is connect, 2nd OKAY is status */ - adb_write(reply_fd, "OKAY", 4); + SendOkay(reply_fd); #endif - adb_write(reply_fd, "OKAY", 4); + SendOkay(reply_fd); return 1; } @@ -800,19 +741,19 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri if (createForward) { // Check forward: parameter format: '<local>;<remote>' if(remote == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); + SendFail(reply_fd, "malformed forward spec"); return 1; } *remote++ = 0; if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) { - sendfailmsg(reply_fd, "malformed forward spec"); + SendFail(reply_fd, "malformed forward spec"); return 1; } } else { // Check killforward: parameter format: '<local>' if (local[0] == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); + SendFail(reply_fd, "malformed forward spec"); return 1; } } @@ -820,7 +761,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri std::string error_msg; transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg); if (!transport) { - sendfailmsg(reply_fd, error_msg.c_str()); + SendFail(reply_fd, error_msg); return 1; } @@ -833,9 +774,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri if (r == INSTALL_STATUS_OK) { #if ADB_HOST /* On the host: 1st OKAY is connect, 2nd OKAY is status */ - WriteFdExactly(reply_fd, "OKAY", 4); + SendOkay(reply_fd); #endif - WriteFdExactly(reply_fd, "OKAY", 4); + SendOkay(reply_fd); return 1; } @@ -851,7 +792,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri break; case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break; } - sendfailmsg(reply_fd, message.c_str()); + SendFail(reply_fd, message); return 1; } return 0; @@ -862,7 +803,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if(!strcmp(service, "kill")) { fprintf(stderr,"adb server killed by remote request\n"); fflush(stdout); - adb_write(reply_fd, "OKAY", 4); + SendOkay(reply_fd); usb_cleanup(); exit(0); } @@ -892,25 +833,25 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if (transport) { s->transport = transport; - adb_write(reply_fd, "OKAY", 4); + SendOkay(reply_fd); } else { - sendfailmsg(reply_fd, error_msg.c_str()); + SendFail(reply_fd, error_msg); } return 1; } // return a list of all connected devices if (!strncmp(service, "devices", 7)) { - char buffer[4096]; - int use_long = !strcmp(service+7, "-l"); - if (use_long || service[7] == 0) { - memset(buffer, 0, sizeof(buffer)); - D("Getting device list \n"); - list_transports(buffer, sizeof(buffer), use_long); - D("Wrote device list \n"); - send_msg_with_okay(reply_fd, buffer, strlen(buffer)); + bool long_listing = (strcmp(service+7, "-l") == 0); + if (long_listing || service[7] == 0) { + D("Getting device list...\n"); + std::string device_list = list_transports(long_listing); + D("Sending device list...\n"); + SendOkay(reply_fd); + SendProtocolString(reply_fd, device_list); return 0; } + return 1; } // remove TCP transport @@ -937,15 +878,15 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r } } - send_msg_with_okay(reply_fd, buffer, strlen(buffer)); + SendOkay(reply_fd); + SendProtocolString(reply_fd, buffer); return 0; } // returns our value for ADB_SERVER_VERSION if (!strcmp(service, "version")) { - char version[12]; - snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); - send_msg_with_okay(reply_fd, version, strlen(version)); + SendOkay(reply_fd); + SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION)); return 0; } @@ -955,7 +896,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if (transport && transport->serial) { out = transport->serial; } - send_msg_with_okay(reply_fd, out, strlen(out)); + SendOkay(reply_fd); + SendProtocolString(reply_fd, out); return 0; } if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { @@ -964,7 +906,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if (transport && transport->devpath) { out = transport->devpath; } - send_msg_with_okay(reply_fd, out, strlen(out)); + SendOkay(reply_fd); + SendProtocolString(reply_fd, out); return 0; } // indicates a new emulator instance has started @@ -977,8 +920,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - const char *state = connection_state_name(transport); - send_msg_with_okay(reply_fd, state, strlen(state)); + SendOkay(reply_fd); + SendProtocolString(reply_fd, transport->connection_state_name()); return 0; } #endif // ADB_HOST @@ -209,6 +209,8 @@ struct atransport unsigned char token[TOKEN_SIZE]; fdevent auth_fde; unsigned failed_auth_attempts; + + const char* connection_state_name() const; }; @@ -369,7 +371,6 @@ enum subproc_mode { #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) #endif -int sendfailmsg(int fd, const char *reason); int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s); void handle_online(atransport *t); diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp index 62f79fa..33eee82 100644 --- a/adb/adb_client.cpp +++ b/adb/adb_client.cpp @@ -56,7 +56,7 @@ static bool ReadProtocolString(int fd, std::string* s, std::string* error) { buf[4] = 0; unsigned long len = strtoul(buf, 0, 16); - s->resize(len + 1, '\0'); // Ensure NUL-termination. + s->resize(len, '\0'); if (!ReadFdExactly(fd, &(*s)[0], len)) { *error = perror_str("protocol fault (couldn't read status message)"); return false; @@ -136,9 +136,7 @@ static int switch_socket_transport(int fd, std::string* error) { service += transport_type; } - char tmp[5]; - snprintf(tmp, sizeof(tmp), "%04zx", service.size()); - if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) { + if (!SendProtocolString(fd, service)) { *error = perror_str("write failure during connection"); adb_close(fd); return -1; @@ -199,9 +197,7 @@ int _adb_connect(const std::string& service, std::string* error) { return -1; } - char tmp[5]; - snprintf(tmp, sizeof(tmp), "%04zx", service.size()); - if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) { + if(!SendProtocolString(fd, service)) { *error = perror_str("write failure during connection"); adb_close(fd); return -1; diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp index d89f304..c34daf9 100644 --- a/adb/adb_io.cpp +++ b/adb/adb_io.cpp @@ -22,14 +22,31 @@ #include <unistd.h> #include "adb_trace.h" -#include "transport.h" +#include "adb_utils.h" + +bool SendProtocolString(int fd, const std::string& s) { + int length = s.size(); + if (length > 0xffff) { + length = 0xffff; + } + + char buf[5]; + snprintf(buf, sizeof(buf), "%04x", length); + return WriteFdExactly(fd, buf, 4) && WriteFdExactly(fd, s); +} + +bool SendOkay(int fd) { + return WriteFdExactly(fd, "OKAY", 4); +} + +bool SendFail(int fd, const std::string& reason) { + return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason); +} bool ReadFdExactly(int fd, void* buf, size_t len) { char* p = reinterpret_cast<char*>(buf); -#if ADB_TRACE size_t len0 = len; -#endif D("readx: fd=%d wanted=%zu\n", fd, len); while (len > 0) { @@ -47,12 +64,10 @@ bool ReadFdExactly(int fd, void* buf, size_t len) { } } -#if ADB_TRACE D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len); if (ADB_TRACING) { dump_hex(reinterpret_cast<const unsigned char*>(buf), len0); } -#endif return true; } @@ -61,12 +76,10 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) { const char* p = reinterpret_cast<const char*>(buf); int r; -#if ADB_TRACE D("writex: fd=%d len=%d: ", fd, (int)len); if (ADB_TRACING) { dump_hex(reinterpret_cast<const unsigned char*>(buf), len); } -#endif while (len > 0) { r = adb_write(fd, p, len); @@ -90,6 +103,14 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) { return true; } +bool WriteFdExactly(int fd, const char* str) { + return WriteFdExactly(fd, str, strlen(str)); +} + +bool WriteFdExactly(int fd, const std::string& str) { + return WriteFdExactly(fd, str.c_str(), str.size()); +} + bool WriteStringFully(int fd, const char* str) { return WriteFdExactly(fd, str, strlen(str)); } diff --git a/adb/adb_io.h b/adb/adb_io.h index 8d237ce..3b8b050 100644 --- a/adb/adb_io.h +++ b/adb/adb_io.h @@ -17,9 +17,19 @@ #ifndef ADB_IO_H #define ADB_IO_H -#include <stdbool.h> #include <sys/types.h> +#include <string> + +// Sends the protocol "OKAY" message. +bool SendOkay(int fd); + +// Sends the protocol "FAIL" message, with the given failure reason. +bool SendFail(int fd, const std::string& reason); + +// Writes a protocol-format string; a four hex digit length followed by the string data. +bool SendProtocolString(int fd, const std::string& s); + /* * Reads exactly len bytes from fd into buf. * @@ -37,9 +47,13 @@ bool ReadFdExactly(int fd, void *buf, size_t len); * completed. If the other end of the fd (such as in a socket, pipe, or fifo), * is closed, errno will be set to 0. */ -bool WriteFdExactly(int fd, const void *buf, size_t len); +bool WriteFdExactly(int fd, const void* buf, size_t len); + +/* Same as above, but with an implicit len = strlen(buf). */ +bool WriteFdExactly(int fd, const char* s); +bool WriteFdExactly(int fd, const std::string& s); -/* Same as WriteFdExactly, but with an implicit len = strlen(buf). */ +// TODO: move minadb off this and remove it. bool WriteStringFully(int fd, const char* str); #endif /* ADB_IO_H */ diff --git a/adb/adb_io_test.cpp b/adb/adb_io_test.cpp index da340b2..dd09919 100644 --- a/adb/adb_io_test.cpp +++ b/adb/adb_io_test.cpp @@ -139,13 +139,13 @@ TEST(io, WriteFdExactly_ENOSPC) { ASSERT_EQ(ENOSPC, errno); } -TEST(io, WriteStringFully) { +TEST(io, WriteFdExactly_string) { const char str[] = "Foobar"; TemporaryFile tf; ASSERT_NE(-1, tf.fd); // Test writing a partial string to the file. - ASSERT_TRUE(WriteStringFully(tf.fd, str)) << strerror(errno); + ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno); ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0)); std::string s; diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp index a1a5ddb..71a9321 100644 --- a/adb/adb_listeners.cpp +++ b/adb/adb_listeners.cpp @@ -19,6 +19,8 @@ #include <stdio.h> #include <stdlib.h> +#include <base/stringprintf.h> + #include "sysdeps.h" #include "transport.h" @@ -143,49 +145,17 @@ int local_name_to_fd(const char *name) return -1; } -// Write a single line describing a listener to a user-provided buffer. -// Appends a trailing zero, even in case of truncation, but the function -// returns the full line length. -// If |buffer| is NULL, does not write but returns required size. -static int format_listener(alistener* l, char* buffer, size_t buffer_len) { - // Format is simply: - // - // <device-serial> " " <local-name> " " <remote-name> "\n" - // - int local_len = strlen(l->local_name); - int connect_len = strlen(l->connect_to); - int serial_len = strlen(l->transport->serial); - - if (buffer != NULL) { - snprintf(buffer, buffer_len, "%s %s %s\n", - l->transport->serial, l->local_name, l->connect_to); - } - // NOTE: snprintf() on Windows returns -1 in case of truncation, so - // return the computed line length instead. - return local_len + connect_len + serial_len + 3; -} - -// Write the list of current listeners (network redirections) into a -// user-provided buffer. Appends a trailing zero, even in case of -// trunctaion, but return the full size in bytes. -// If |buffer| is NULL, does not write but returns required size. -int format_listeners(char* buf, size_t buflen) -{ - alistener* l; - int result = 0; - for (l = listener_list.next; l != &listener_list; l = l->next) { +// Write the list of current listeners (network redirections) into a string. +std::string format_listeners() { + std::string result; + for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { // Ignore special listeners like those for *smartsocket* - if (l->connect_to[0] == '*') - continue; - int len = format_listener(l, buf, buflen); - // Ensure there is space for the trailing zero. - result += len; - if (buf != NULL) { - buf += len; - buflen -= len; - if (buflen <= 0) - break; + if (l->connect_to[0] == '*') { + continue; } + // <device-serial> " " <local-name> " " <remote-name> "\n" + android::base::StringAppendF(&result, "%s %s %s\n", + l->transport->serial, l->local_name, l->connect_to); } return result; } diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h index f55fdee..1d4f062 100644 --- a/adb/adb_listeners.h +++ b/adb/adb_listeners.h @@ -19,6 +19,8 @@ #include "adb.h" +#include <string> + // error/status codes for install_listener. enum install_status_t { INSTALL_STATUS_OK = 0, @@ -39,7 +41,7 @@ install_status_t install_listener(const char *local_name, atransport* transport, int no_rebind); -int format_listeners(char* buf, size_t buflen); +std::string format_listeners(); install_status_t remove_listener(const char* local_name, atransport* transport); void remove_all_listeners(void); diff --git a/adb/adb_trace.h b/adb/adb_trace.h index 32b6ae4..63d4151 100644 --- a/adb/adb_trace.h +++ b/adb/adb_trace.h @@ -23,9 +23,6 @@ #include <stdio.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 @@ -45,8 +42,6 @@ enum AdbTrace { TRACE_FDEVENT, } ; -#if ADB_TRACE - #if !ADB_HOST /* * When running inside the emulator, guest's adbd can connect to 'adb-debug' @@ -97,19 +92,6 @@ void adb_trace_init(void); errno = save_errno; \ } \ } while (0) -# define DD(...) \ - do { \ - int save_errno = errno; \ - adb_mutex_lock(&D_lock); \ - fprintf(stderr, "%16s: %5d:%5lu | ", \ - __FUNCTION__, \ - getpid(), adb_thread_id()); \ - errno = save_errno; \ - fprintf(stderr, __VA_ARGS__ ); \ - fflush(stderr); \ - adb_mutex_unlock(&D_lock); \ - errno = save_errno; \ - } while (0) #else # define D(...) \ do { \ @@ -129,19 +111,6 @@ void adb_trace_init(void); __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/adb_utils.cpp b/adb/adb_utils.cpp index f10c143..0ce5ece 100644 --- a/adb/adb_utils.cpp +++ b/adb/adb_utils.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define TRACE_TAG TRACE_ADB + #include "adb_utils.h" #include <stdlib.h> @@ -21,6 +23,11 @@ #include <sys/types.h> #include <unistd.h> +#include <algorithm> + +#include <base/stringprintf.h> + +#include "adb_trace.h" #include "sysdeps.h" bool getcwd(std::string* s) { @@ -50,3 +57,25 @@ std::string escape_arg(const std::string& s) { result.push_back('\''); return result; } + +void dump_hex(const void* data, size_t byte_count) { + byte_count = std::min(byte_count, size_t(16)); + + const uint8_t* p = reinterpret_cast<const uint8_t*>(data); + + std::string line; + for (size_t i = 0; i < byte_count; ++i) { + android::base::StringAppendF(&line, "%02x", p[i]); + } + line.push_back(' '); + + for (size_t i = 0; i < byte_count; ++i) { + int c = p[i]; + if (c < 32 || c > 127) { + c = '.'; + } + line.push_back(c); + } + + DR("%s\n", line.c_str()); +} diff --git a/adb/adb_utils.h b/adb/adb_utils.h index 4b64afa..84f7d0c 100644 --- a/adb/adb_utils.h +++ b/adb/adb_utils.h @@ -24,4 +24,6 @@ bool directory_exists(const std::string& path); std::string escape_arg(const std::string& s); +void dump_hex(const void* ptr, size_t byte_count); + #endif diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 4941689..7964cd3 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -490,17 +490,8 @@ static int adb_download_buffer(const char *service, const char *fn, const void* printf("\n"); } - // TODO: should this be adb_status? - char buf[5]; - if(!ReadFdExactly(fd, buf, 4)){ - fprintf(stderr,"* error reading response *\n"); - adb_close(fd); - return -1; - } - if(memcmp(buf, "OKAY", 4)) { - buf[4] = 0; - fprintf(stderr,"* error response '%s' *\n", buf); - adb_close(fd); + if (!adb_status(fd, &error)) { + fprintf(stderr,"* error response '%s' *\n", error.c_str()); return -1; } diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp index 1eaee73..3fb2fcb 100644 --- a/adb/remount_service.cpp +++ b/adb/remount_service.cpp @@ -92,7 +92,7 @@ static bool remount_partition(int fd, const char* partition, int* ro) { if (remount(partition, ro)) { char buf[200]; snprintf(buf, sizeof(buf), "remount of %s failed: %s\n", partition, strerror(errno)); - WriteStringFully(fd, buf); + WriteFdExactly(fd, buf); return false; } return true; @@ -102,7 +102,7 @@ void remount_service(int fd, void* cookie) { char prop_buf[PROPERTY_VALUE_MAX]; if (getuid() != 0) { - WriteStringFully(fd, "Not running as root. Try \"adb root\" first.\n"); + WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n"); adb_close(fd); return; } @@ -128,12 +128,11 @@ void remount_service(int fd, void* cookie) { both ? " and " : "", vendor_verified ? "vendor" : "", both ? "s" : ""); - WriteStringFully(fd, buffer); - snprintf(buffer, sizeof(buffer), - "Use \"adb disable-verity\" to disable verity.\n" - "If you do not, remount may succeed, however, you will still " - "not be able to write to these volumes.\n"); - WriteStringFully(fd, buffer); + WriteFdExactly(fd, buffer); + WriteFdExactly(fd, + "Use \"adb disable-verity\" to disable verity.\n" + "If you do not, remount may succeed, however, you will still " + "not be able to write to these volumes.\n"); } bool success = true; @@ -141,7 +140,7 @@ void remount_service(int fd, void* cookie) { success &= remount_partition(fd, "/vendor", &vendor_ro); success &= remount_partition(fd, "/oem", &oem_ro); - WriteStringFully(fd, success ? "remount succeeded\n" : "remount failed\n"); + WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n"); adb_close(fd); } diff --git a/adb/services.cpp b/adb/services.cpp index e6c84a4..fa5a1a1 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -31,10 +31,11 @@ #include <unistd.h> #endif +#include <base/file.h> #include <base/stringprintf.h> +#include <base/strings.h> #if !ADB_HOST -#include "base/file.h" #include "cutils/android_reboot.h" #include "cutils/properties.h" #endif @@ -147,8 +148,7 @@ static bool reboot_service_impl(int fd, const char* arg) { // in the command file. if (strcmp(reboot_arg, "sideload") == 0) { if (getuid() != 0) { - snprintf(buf, sizeof(buf), "'adb root' is required for 'adb reboot sideload'.\n"); - WriteStringFully(fd, buf); + WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n"); return false; } @@ -175,14 +175,14 @@ static bool reboot_service_impl(int fd, const char* arg) { int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg); if (ret >= static_cast<int>(sizeof(property_val))) { snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret); - WriteStringFully(fd, buf); + WriteFdExactly(fd, buf); return false; } ret = property_set(ANDROID_RB_PROPERTY, property_val); if (ret < 0) { snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret); - WriteStringFully(fd, buf); + WriteFdExactly(fd, buf); return false; } @@ -208,7 +208,7 @@ void reverse_service(int fd, void* arg) const char* command = reinterpret_cast<const char*>(arg); if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) { - sendfailmsg(fd, "not a reverse forwarding command"); + SendFail(fd, "not a reverse forwarding command"); } free(arg); adb_close(fd); @@ -551,9 +551,9 @@ static void wait_for_state(int fd, void* cookie) std::string error_msg = "unknown error"; atransport* t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &error_msg); if (t != 0) { - WriteFdExactly(fd, "OKAY", 4); + SendOkay(fd); } else { - sendfailmsg(fd, error_msg.c_str()); + SendFail(fd, error_msg); } if (sinfo->serial) @@ -563,35 +563,31 @@ static void wait_for_state(int fd, void* cookie) D("wait_for_state is done\n"); } -static void connect_device(char* host, char* buffer, int buffer_size) -{ - int port, fd; - char* portstr = strchr(host, ':'); - char hostbuf[100]; - char serial[100]; - int ret; - - strncpy(hostbuf, host, sizeof(hostbuf) - 1); - if (portstr) { - if (portstr - host >= (ptrdiff_t)sizeof(hostbuf)) { - snprintf(buffer, buffer_size, "bad host name %s", host); - return; - } - // zero terminate the host at the point we found the colon - hostbuf[portstr - host] = 0; - if (sscanf(portstr + 1, "%d", &port) != 1) { - snprintf(buffer, buffer_size, "bad port number %s", portstr); +static void connect_device(const std::string& host, std::string* response) { + if (host.empty()) { + *response = "empty host name"; + return; + } + + std::vector<std::string> pieces = android::base::Split(host, ":"); + const std::string& hostname = pieces[0]; + + int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; + if (pieces.size() > 1) { + if (sscanf(pieces[1].c_str(), "%d", &port) != 1) { + *response = android::base::StringPrintf("bad port number %s", pieces[1].c_str()); return; } - } else { - port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; } - snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port); + // This may look like we're putting 'host' back together, + // but we're actually inserting the default port if necessary. + std::string serial = android::base::StringPrintf("%s:%d", hostname.c_str(), port); - fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10); + int fd = socket_network_client_timeout(hostname.c_str(), port, SOCK_STREAM, 10); if (fd < 0) { - snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port); + *response = android::base::StringPrintf("unable to connect to %s:%d", + hostname.c_str(), port); return; } @@ -599,85 +595,74 @@ static void connect_device(char* host, char* buffer, int buffer_size) close_on_exec(fd); disable_tcp_nagle(fd); - ret = register_socket_transport(fd, serial, port, 0); + int ret = register_socket_transport(fd, serial.c_str(), port, 0); if (ret < 0) { adb_close(fd); - snprintf(buffer, buffer_size, "already connected to %s", serial); + *response = android::base::StringPrintf("already connected to %s", serial.c_str()); } else { - snprintf(buffer, buffer_size, "connected to %s", serial); + *response = android::base::StringPrintf("connected to %s", serial.c_str()); } } -void connect_emulator(char* port_spec, char* buffer, int buffer_size) -{ - char* port_separator = strchr(port_spec, ','); - if (!port_separator) { - snprintf(buffer, buffer_size, - "unable to parse '%s' as <console port>,<adb port>", - port_spec); +void connect_emulator(const std::string& port_spec, std::string* response) { + std::vector<std::string> pieces = android::base::Split(port_spec, ","); + if (pieces.size() != 2) { + *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>", + port_spec.c_str()); return; } - // Zero-terminate console port and make port_separator point to 2nd port. - *port_separator++ = 0; - int console_port = strtol(port_spec, NULL, 0); - int adb_port = strtol(port_separator, NULL, 0); - if (!(console_port > 0 && adb_port > 0)) { - *(port_separator - 1) = ','; - snprintf(buffer, buffer_size, - "Invalid port numbers: Expected positive numbers, got '%s'", - port_spec); + int console_port = strtol(pieces[0].c_str(), NULL, 0); + int adb_port = strtol(pieces[1].c_str(), NULL, 0); + if (console_port <= 0 || adb_port <= 0) { + *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str()); return; } - /* Check if the emulator is already known. - * Note: There's a small but harmless race condition here: An emulator not - * present just yet could be registered by another invocation right - * after doing this check here. However, local_connect protects - * against double-registration too. From here, a better error message - * can be produced. In the case of the race condition, the very specific - * error message won't be shown, but the data doesn't get corrupted. */ + // Check if the emulator is already known. + // Note: There's a small but harmless race condition here: An emulator not + // present just yet could be registered by another invocation right + // after doing this check here. However, local_connect protects + // against double-registration too. From here, a better error message + // can be produced. In the case of the race condition, the very specific + // error message won't be shown, but the data doesn't get corrupted. atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port); - if (known_emulator != NULL) { - snprintf(buffer, buffer_size, - "Emulator on port %d already registered.", adb_port); + if (known_emulator != nullptr) { + *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port); return; } - /* Check if more emulators can be registered. Similar unproblematic - * race condition as above. */ + // Check if more emulators can be registered. Similar unproblematic + // race condition as above. int candidate_slot = get_available_local_transport_index(); if (candidate_slot < 0) { - snprintf(buffer, buffer_size, "Cannot accept more emulators."); + *response = "Cannot accept more emulators"; return; } - /* Preconditions met, try to connect to the emulator. */ + // Preconditions met, try to connect to the emulator. if (!local_connect_arbitrary_ports(console_port, adb_port)) { - snprintf(buffer, buffer_size, - "Connected to emulator on ports %d,%d", console_port, adb_port); + *response = android::base::StringPrintf("Connected to emulator on ports %d,%d", + console_port, adb_port); } else { - snprintf(buffer, buffer_size, - "Could not connect to emulator on ports %d,%d", - console_port, adb_port); + *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d", + console_port, adb_port); } } static void connect_service(int fd, void* cookie) { - char buf[4096]; - char resp[4096]; char *host = reinterpret_cast<char*>(cookie); + std::string response; if (!strncmp(host, "emu:", 4)) { - connect_emulator(host + 4, buf, sizeof(buf)); + connect_emulator(host + 4, &response); } else { - connect_device(host, buf, sizeof(buf)); + connect_device(host, &response); } // Send response for emulator and device - snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf); - WriteFdExactly(fd, resp, strlen(resp)); + SendProtocolString(fd, response); adb_close(fd); } #endif diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp index b75ed4c..d856d57 100644 --- a/adb/set_verity_enable_state_service.cpp +++ b/adb/set_verity_enable_state_service.cpp @@ -21,7 +21,6 @@ #include <fcntl.h> #include <inttypes.h> #include <stdarg.h> -#include <stdbool.h> #include <stdio.h> #include <sys/stat.h> diff --git a/adb/sockets.cpp b/adb/sockets.cpp index f468029..32ca17d 100644 --- a/adb/sockets.cpp +++ b/adb/sockets.cpp @@ -37,23 +37,6 @@ ADB_MUTEX_DEFINE( socket_list_lock ); static void local_socket_close_locked(asocket *s); -int sendfailmsg(int fd, const char *reason) -{ - char buf[9]; - int len; - len = strlen(reason); - if (len > 0xffff) { - len = 0xffff; - } - - snprintf(buf, sizeof buf, "FAIL%04x", len); - if (!WriteFdExactly(fd, buf, 8)) { - return -1; - } - - return WriteFdExactly(fd, reason, len) ? 0 : -1; -} - static unsigned local_socket_next_id = 1; static asocket local_socket_list = { @@ -608,7 +591,7 @@ static void local_socket_ready_notify(asocket *s) s->ready = local_socket_ready; s->shutdown = NULL; s->close = local_socket_close; - adb_write(s->fd, "OKAY", 4); + SendOkay(s->fd); s->ready(s); } @@ -620,11 +603,11 @@ static void local_socket_close_notify(asocket *s) s->ready = local_socket_ready; s->shutdown = NULL; s->close = local_socket_close; - sendfailmsg(s->fd, "closed"); + SendFail(s->fd, "closed"); s->close(s); } -unsigned unhex(unsigned char *s, int len) +static unsigned unhex(unsigned char *s, int len) { unsigned n = 0, c; @@ -654,6 +637,8 @@ unsigned unhex(unsigned char *s, int len) return n; } +#if ADB_HOST + #define PREFIX(str) { str, sizeof(str) - 1 } static const struct prefix_struct { const char *str; @@ -670,7 +655,7 @@ static const int num_prefixes = (sizeof(prefixes) / sizeof(prefixes[0])); skipping over the 'serial' parameter in the ADB protocol, where parameter string may be a host:port string containing the protocol delimiter (colon). */ -char *skip_host_serial(char *service) { +static char *skip_host_serial(char *service) { char *first_colon, *serial_end; int i; @@ -698,6 +683,8 @@ char *skip_host_serial(char *service) { return serial_end; } +#endif // ADB_HOST + static int smart_socket_enqueue(asocket *s, apacket *p) { unsigned len; @@ -799,7 +786,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p) s2 = create_host_service_socket(service, serial); if(s2 == 0) { D( "SS(%d): couldn't create host service '%s'\n", s->id, service ); - sendfailmsg(s->peer->fd, "unknown host service"); + SendFail(s->peer->fd, "unknown host service"); goto fail; } @@ -810,7 +797,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p) ** connection, and close this smart socket now ** that its work is done. */ - adb_write(s->peer->fd, "OKAY", 4); + SendOkay(s->peer->fd); s->peer->ready = local_socket_ready; s->peer->shutdown = NULL; @@ -831,7 +818,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p) s->transport = acquire_one_transport(CS_ANY, kTransportAny, NULL, &error_msg); if (s->transport == NULL) { - sendfailmsg(s->peer->fd, error_msg.c_str()); + SendFail(s->peer->fd, error_msg); goto fail; } } @@ -841,7 +828,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p) /* if there's no remote we fail the connection ** right here and terminate it */ - sendfailmsg(s->peer->fd, "device offline (x)"); + SendFail(s->peer->fd, "device offline (x)"); goto fail; } diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp index 633f6f5..a21272f 100644 --- a/adb/sysdeps_win32.cpp +++ b/adb/sysdeps_win32.cpp @@ -22,7 +22,6 @@ #include <windows.h> #include <errno.h> -#include <stdbool.h> #include <stdio.h> #include <stdlib.h> diff --git a/adb/test_track_devices.cpp b/adb/test_track_devices.cpp index 77b3ad9..3e823e9 100644 --- a/adb/test_track_devices.cpp +++ b/adb/test_track_devices.cpp @@ -1,3 +1,5 @@ +// TODO: replace this with a shell/python script. + /* a simple test program, connects to ADB server, and opens a track-devices session */ #include <netdb.h> #include <sys/socket.h> @@ -6,6 +8,8 @@ #include <errno.h> #include <memory.h> +#include <base/file.h> + static void panic( const char* msg ) { @@ -13,82 +17,49 @@ panic( const char* msg ) exit(1); } -static int -unix_write( int fd, const char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = write(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} +int main(int argc, char* argv[]) { + const char* request = "host:track-devices"; -static int -unix_read( int fd, char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = read(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; + if (argv[1] && strcmp(argv[1], "--jdwp") == 0) { + request = "track-jdwp"; } - return result; -} - -int main( void ) -{ - int ret, s; + int ret; struct sockaddr_in server; char buffer[1024]; - const char* request = "host:track-devices"; - int len; memset( &server, 0, sizeof(server) ); server.sin_family = AF_INET; server.sin_port = htons(5037); server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - s = socket( PF_INET, SOCK_STREAM, 0 ); + int s = socket( PF_INET, SOCK_STREAM, 0 ); ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); if (ret < 0) panic( "could not connect to server" ); /* send the request */ - len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); - if (unix_write(s, buffer, len) < 0) + int len = snprintf(buffer, sizeof(buffer), "%04zx%s", strlen(request), request); + if (!android::base::WriteFully(s, buffer, len)) panic( "could not send request" ); /* read the OKAY answer */ - if (unix_read(s, buffer, 4) != 4) + if (!android::base::ReadFully(s, buffer, 4)) panic( "could not read request" ); printf( "server answer: %.*s\n", 4, buffer ); /* now loop */ - for (;;) { + while (true) { char head[5] = "0000"; - if (unix_read(s, head, 4) < 0) + if (!android::base::ReadFully(s, head, 4)) panic("could not read length"); - if ( sscanf( head, "%04x", &len ) != 1 ) + int len; + if (sscanf(head, "%04x", &len) != 1 ) panic("could not decode length"); - if (unix_read(s, buffer, len) != len) + if (!android::base::ReadFully(s, buffer, len)) panic("could not read data"); printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); diff --git a/adb/test_track_jdwp.cpp b/adb/test_track_jdwp.cpp deleted file mode 100644 index 8ecc6b8..0000000 --- a/adb/test_track_jdwp.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* a simple test program, connects to ADB server, and opens a track-devices session */ -#include <netdb.h> -#include <sys/socket.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <memory.h> - -static void -panic( const char* msg ) -{ - fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno)); - exit(1); -} - -static int -unix_write( int fd, const char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = write(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - -static int -unix_read( int fd, char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = read(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - - -int main( void ) -{ - int ret, s; - struct sockaddr_in server; - char buffer[1024]; - const char* request = "track-jdwp"; - int len; - - memset( &server, 0, sizeof(server) ); - server.sin_family = AF_INET; - server.sin_port = htons(5037); - server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket( PF_INET, SOCK_STREAM, 0 ); - ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); - if (ret < 0) panic( "could not connect to server" ); - - /* send the request */ - len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); - if (unix_write(s, buffer, len) < 0) - panic( "could not send request" ); - - /* read the OKAY answer */ - if (unix_read(s, buffer, 4) != 4) - panic( "could not read request" ); - - printf( "server answer: %.*s\n", 4, buffer ); - - /* now loop */ - for (;;) { - char head[5] = "0000"; - - if (unix_read(s, head, 4) < 0) - panic("could not read length"); - - if ( sscanf( head, "%04x", &len ) != 1 ) - panic("could not decode length"); - - if (unix_read(s, buffer, len) != len) - panic("could not read data"); - - printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); - } - close(s); -} diff --git a/adb/transport.cpp b/adb/transport.cpp index 45740a8..b7f30ea 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -26,7 +26,10 @@ #include <string.h> #include <unistd.h> +#include <base/stringprintf.h> + #include "adb.h" +#include "adb_utils.h" static void transport_unref(atransport *t); @@ -42,34 +45,6 @@ static atransport pending_list = { ADB_MUTEX_DEFINE( transport_lock ); -#if ADB_TRACE -#define MAX_DUMP_HEX_LEN 16 -void dump_hex(const unsigned char* ptr, size_t len) -{ - int nn, len2 = len; - // Build a string instead of logging each character. - // MAX chars in 2 digit hex, one space, MAX chars, one '\0'. - char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer; - - if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN; - - for (nn = 0; nn < len2; nn++) { - sprintf(pb, "%02x", ptr[nn]); - pb += 2; - } - sprintf(pb++, " "); - - for (nn = 0; nn < len2; nn++) { - int c = ptr[nn]; - if (c < 32 || c > 127) - c = '.'; - *pb++ = c; - } - *pb++ = '\0'; - DR("%s\n", buffer); -} -#endif - void kick_transport(atransport* t) { if (t && !t->kicked) @@ -117,10 +92,7 @@ void run_transport_disconnects(atransport* t) } } -#if ADB_TRACE -static void -dump_packet(const char* name, const char* func, apacket* p) -{ +static void dump_packet(const char* name, const char* func, apacket* p) { unsigned command = p->msg.command; int len = p->msg.data_length; char cmd[9]; @@ -155,7 +127,6 @@ dump_packet(const char* name, const char* func, apacket* p) name, func, cmd, arg0, arg1, len); dump_hex(p->data, len); } -#endif /* ADB_TRACE */ static int read_packet(int fd, const char* name, apacket** ppacket) @@ -180,11 +151,9 @@ read_packet(int fd, const char* name, apacket** ppacket) } } -#if ADB_TRACE if (ADB_TRACING) { dump_packet(name, "from remote", *ppacket); } -#endif return 0; } @@ -199,11 +168,9 @@ write_packet(int fd, const char* name, apacket** ppacket) name = buff; } -#if ADB_TRACE if (ADB_TRACING) { dump_packet(name, "to remote", *ppacket); } -#endif len = sizeof(ppacket); while(len > 0) { r = adb_write(fd, p, len); @@ -389,17 +356,6 @@ static fdevent transport_registration_fde; #if ADB_HOST -static int list_transports_msg(char* buffer, size_t bufferlen) -{ - char head[5]; - int len; - - len = list_transports(buffer+4, bufferlen-4, 0); - snprintf(head, sizeof(head), "%04x", len); - memcpy(buffer, head, 4); - len += 4; - return len; -} /* this adds support required by the 'track-devices' service. * this is used to send the content of "list_transport" to any @@ -457,39 +413,29 @@ device_tracker_enqueue( asocket* socket, apacket* p ) return -1; } -static int -device_tracker_send( device_tracker* tracker, - const char* buffer, - int len ) -{ - apacket* p = get_apacket(); - asocket* peer = tracker->socket.peer; +static int device_tracker_send(device_tracker* tracker, const std::string& string) { + apacket* p = get_apacket(); + asocket* peer = tracker->socket.peer; - memcpy(p->data, buffer, len); - p->len = len; - return peer->enqueue( peer, p ); + snprintf(reinterpret_cast<char*>(p->data), 5, "%04x", static_cast<int>(string.size())); + memcpy(&p->data[4], string.data(), string.size()); + p->len = 4 + string.size(); + return peer->enqueue(peer, p); } +static void device_tracker_ready(asocket* socket) { + device_tracker* tracker = reinterpret_cast<device_tracker*>(socket); -static void -device_tracker_ready( asocket* socket ) -{ - device_tracker* tracker = (device_tracker*) socket; - - /* we want to send the device list when the tracker connects - * for the first time, even if no update occured */ + // We want to send the device list when the tracker connects + // for the first time, even if no update occurred. if (tracker->update_needed > 0) { - char buffer[1024]; - int len; - tracker->update_needed = 0; - len = list_transports_msg(buffer, sizeof(buffer)); - device_tracker_send(tracker, buffer, len); + std::string transports = list_transports(false); + device_tracker_send(tracker, transports); } } - asocket* create_device_tracker(void) { @@ -510,27 +456,25 @@ create_device_tracker(void) } -/* call this function each time the transport list has changed */ -void update_transports(void) { - char buffer[1024]; - int len; - device_tracker* tracker; - - len = list_transports_msg(buffer, sizeof(buffer)); +// Call this function each time the transport list has changed. +void update_transports() { + std::string transports = list_transports(false); - tracker = device_tracker_list; - while (tracker != NULL) { - device_tracker* next = tracker->next; - /* note: this may destroy the tracker if the connection is closed */ - device_tracker_send(tracker, buffer, len); + device_tracker* tracker = device_tracker_list; + while (tracker != nullptr) { + device_tracker* next = tracker->next; + // This may destroy the tracker if the connection is closed. + device_tracker_send(tracker, transports); tracker = next; } } + #else -void update_transports(void) -{ - // nothing to do on the device side + +void update_transports() { + // Nothing to do on the device side. } + #endif // ADB_HOST struct tmsg @@ -895,100 +839,71 @@ retry: return result; } -#if ADB_HOST -static const char *statename(atransport *t) -{ - switch(t->connection_state){ +const char* atransport::connection_state_name() const { + switch (connection_state) { case CS_OFFLINE: return "offline"; case CS_BOOTLOADER: return "bootloader"; case CS_DEVICE: return "device"; case CS_HOST: return "host"; case CS_RECOVERY: return "recovery"; - case CS_SIDELOAD: return "sideload"; case CS_NOPERM: return "no permissions"; + case CS_SIDELOAD: return "sideload"; case CS_UNAUTHORIZED: return "unauthorized"; default: return "unknown"; } } -static void add_qual(char **buf, size_t *buf_size, - const char *prefix, const char *qual, bool sanitize_qual) -{ - if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual) +#if ADB_HOST + +static void append_transport_info(std::string* result, const char* key, const char* value, bool sanitize) { + if (value == nullptr || *value == '\0') { return; + } - int prefix_len; - size_t len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual); + *result += ' '; + *result += key; - if (sanitize_qual) { - for (char* cp = *buf + prefix_len; cp < *buf + len; cp++) { - if (!isalnum(*cp)) - *cp = '_'; - } + for (const char* p = value; *p; ++p) { + result->push_back((!sanitize || isalnum(*p)) ? *p : '_'); } - - *buf_size -= len; - *buf += len; } -static size_t format_transport(atransport *t, char *buf, size_t bufsize, - int long_listing) -{ +static void append_transport(atransport* t, std::string* result, bool long_listing) { const char* serial = t->serial; - if (!serial || !serial[0]) + if (!serial || !serial[0]) { serial = "????????????"; + } if (!long_listing) { - return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t)); + *result += serial; + *result += '\t'; + *result += t->connection_state_name(); } else { - size_t len, remaining = bufsize; - - len = snprintf(buf, remaining, "%-22s %s", serial, statename(t)); - remaining -= len; - buf += len; + android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name()); - add_qual(&buf, &remaining, " ", t->devpath, false); - add_qual(&buf, &remaining, " product:", t->product, false); - add_qual(&buf, &remaining, " model:", t->model, true); - add_qual(&buf, &remaining, " device:", t->device, false); - - len = snprintf(buf, remaining, "\n"); - remaining -= len; - - return bufsize - remaining; + append_transport_info(result, "", t->devpath, false); + append_transport_info(result, "product:", t->product, false); + append_transport_info(result, "model:", t->model, true); + append_transport_info(result, "device:", t->device, false); } + *result += '\n'; } -int list_transports(char *buf, size_t bufsize, int long_listing) -{ - char* p = buf; - char* end = buf + bufsize; - int len; - atransport *t; - - /* XXX OVERRUN PROBLEMS XXX */ +std::string list_transports(bool long_listing) { + std::string result; adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - len = format_transport(t, p, end - p, long_listing); - if (p + len >= end) { - /* discard last line if buffer is too short */ - break; - } - p += len; + for (atransport* t = transport_list.next; t != &transport_list; t = t->next) { + append_transport(t, &result, long_listing); } - p[0] = 0; adb_mutex_unlock(&transport_lock); - return p - buf; + return result; } - /* hack for osx */ void close_usb_devices() { - atransport *t; - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { + for (atransport* t = transport_list.next; t != &transport_list; t = t->next) { if ( !t->kicked ) { t->kicked = 1; t->kick(t); diff --git a/adb/transport.h b/adb/transport.h index a2077e8..5b6fdac 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -23,10 +23,6 @@ #include "adb.h" -#if ADB_TRACE -void dump_hex(const unsigned char* ptr, size_t len); -#endif - /* * Obtain a transport from the available transports. * If state is != CS_ANY, only transports in that state are considered. @@ -45,7 +41,7 @@ void update_transports(void); ** get_device_transport does an acquire on your behalf before returning */ void init_transport_registration(void); -int list_transports(char* buf, size_t bufsize, int long_listing); +std::string list_transports(bool long_listing); atransport* find_transport(const char* serial); void register_usb_transport(usb_handle* h, const char* serial, |