summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
Diffstat (limited to 'adb')
-rw-r--r--adb/Android.mk5
-rw-r--r--adb/SERVICES.TXT21
-rw-r--r--adb/adb.c134
-rw-r--r--adb/adb.h7
-rw-r--r--adb/adb_auth_client.c3
-rw-r--r--adb/mutex_list.h1
-rw-r--r--adb/remount_service.c9
-rw-r--r--adb/services.c240
-rw-r--r--adb/sockets.c12
-rw-r--r--adb/sysdeps.h1
-rw-r--r--adb/transport.c53
-rw-r--r--adb/transport_local.c3
-rw-r--r--adb/utils.c106
-rw-r--r--adb/utils.h68
14 files changed, 205 insertions, 458 deletions
diff --git a/adb/Android.mk b/adb/Android.mk
index a80397875..36f595b50 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -64,7 +64,6 @@ LOCAL_SRC_FILES := \
file_sync_client.c \
$(EXTRA_SRCS) \
$(USB_SRCS) \
- utils.c \
usb_vendors.c
LOCAL_C_INCLUDES += external/openssl/include
@@ -116,8 +115,7 @@ LOCAL_SRC_FILES := \
framebuffer_service.c \
remount_service.c \
usb_linux_client.c \
- log_service.c \
- utils.c
+ log_service.c
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
@@ -157,7 +155,6 @@ LOCAL_SRC_FILES := \
file_sync_client.c \
get_my_path_linux.c \
usb_linux.c \
- utils.c \
usb_vendors.c \
fdevent.c
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index b53bc444c..5966686de 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -225,27 +225,6 @@ framebuffer:
If the adbd daemon doesn't have sufficient privileges to open
the framebuffer device, the connection is simply closed immediately.
-dns:<server-name>
- This service is an exception because it only runs within the ADB server.
- It is used to implement USB networking, i.e. to provide a network connection
- to the device through the host machine (note: this is the exact opposite of
- network tethering).
-
- It is used to perform a gethostbyname(<address>) on the host and return
- the corresponding IP address as a 4-byte string.
-
-recover:<size>
- This service is used to upload a recovery image to the device. <size>
- must be a number corresponding to the size of the file. The service works
- by:
-
- - creating a file named /tmp/update
- - reading 'size' bytes from the client and writing them to /tmp/update
- - when everything is read successfully, create a file named /tmp/update.start
-
- This service can only work when the device is in recovery mode. Otherwise,
- the /tmp directory doesn't exist and the connection will be closed immediately.
-
jdwp:<pid>
Connects to the JDWP thread running in the VM of process <pid>.
diff --git a/adb/adb.c b/adb/adb.c
index ec74b49d4..72b7484af 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -34,6 +34,7 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#if !ADB_HOST
+#include <cutils/properties.h>
#include <private/android_filesystem_config.h>
#include <sys/capability.h>
#include <linux/prctl.h>
@@ -1199,7 +1200,7 @@ static void drop_capabilities_bounding_set_if_needed() {
#endif
int i;
for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
- if ((i == CAP_SETUID) || (i == CAP_SETGID)) {
+ if (i == CAP_SETUID || i == CAP_SETGID) {
// CAP_SETUID CAP_SETGID needed by /system/bin/run-as
continue;
}
@@ -1301,13 +1302,6 @@ int adb_main(int is_daemon, int server_port)
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (should_drop_privileges()) {
- struct __user_cap_header_struct header;
- struct __user_cap_data_struct cap[2];
-
- if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
- exit(1);
- }
-
drop_capabilities_bounding_set_if_needed();
/* add extra groups:
@@ -1337,16 +1331,6 @@ int adb_main(int is_daemon, int server_port)
exit(1);
}
- memset(&header, 0, sizeof(header));
- memset(cap, 0, sizeof(cap));
-
- /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
- header.version = _LINUX_CAPABILITY_VERSION_3;
- header.pid = 0;
- cap[CAP_TO_INDEX(CAP_SYS_BOOT)].effective |= CAP_TO_MASK(CAP_SYS_BOOT);
- cap[CAP_TO_INDEX(CAP_SYS_BOOT)].permitted |= CAP_TO_MASK(CAP_SYS_BOOT);
- capset(&header, cap);
-
D("Local port disabled\n");
} else {
char local_name[30];
@@ -1404,105 +1388,6 @@ int adb_main(int is_daemon, int server_port)
return 0;
}
-#if ADB_HOST
-void connect_device(char* host, char* buffer, int buffer_size)
-{
- int port, fd;
- char* portstr = strchr(host, ':');
- char hostbuf[100];
- char serial[100];
-
- 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) == 0) {
- snprintf(buffer, buffer_size, "bad port number %s", portstr);
- return;
- }
- } else {
- port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
- }
-
- snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
- if (find_transport(serial)) {
- snprintf(buffer, buffer_size, "already connected to %s", serial);
- return;
- }
-
- fd = socket_network_client(hostbuf, port, SOCK_STREAM);
- if (fd < 0) {
- snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
- return;
- }
-
- D("client: connected on remote on fd %d\n", fd);
- close_on_exec(fd);
- disable_tcp_nagle(fd);
- register_socket_transport(fd, serial, port, 0);
- snprintf(buffer, buffer_size, "connected to %s", serial);
-}
-
-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);
- 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);
- 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. */
- 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);
- return;
- }
-
- /* 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.");
- return;
- }
-
- /* 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);
- } else {
- snprintf(buffer, buffer_size,
- "Could not connect to emulator on ports %d,%d",
- console_port, adb_port);
- }
-}
-#endif
-
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
{
atransport *transport = NULL;
@@ -1563,21 +1448,6 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
}
- // add a new TCP transport, device or emulator
- if (!strncmp(service, "connect:", 8)) {
- char buffer[4096];
- char* host = service + 8;
- if (!strncmp(host, "emu:", 4)) {
- connect_emulator(host + 4, buffer, sizeof(buffer));
- } else {
- connect_device(host, buffer, sizeof(buffer));
- }
- // Send response for emulator and device
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
- writex(reply_fd, buf, strlen(buf));
- return 0;
- }
-
// remove TCP transport
if (!strncmp(service, "disconnect:", 11)) {
char buffer[4096];
diff --git a/adb/adb.h b/adb/adb.h
index a01d460e4..622ca7099 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -128,10 +128,7 @@ struct asocket {
*/
void (*close)(asocket *s);
- /* socket-type-specific extradata */
- void *extra;
-
- /* A socket is bound to atransport */
+ /* A socket is bound to atransport */
atransport *transport;
};
@@ -292,7 +289,7 @@ void init_usb_transport(atransport *t, usb_handle *usb, int state);
void close_usb_devices();
/* cause new transports to be init'd and added to the list */
-void register_socket_transport(int s, const char *serial, int port, int local);
+int register_socket_transport(int s, const char *serial, int port, int local);
/* these should only be used for the "adb disconnect" command */
void unregister_transport(atransport *t);
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c
index 763b448d7..f8d730645 100644
--- a/adb/adb_auth_client.c
+++ b/adb/adb_auth_client.c
@@ -25,6 +25,7 @@
#include "adb_auth.h"
#include "fdevent.h"
#include "mincrypt/rsa.h"
+#include "mincrypt/sha.h"
#define TRACE_TAG TRACE_AUTH
@@ -149,7 +150,7 @@ int adb_auth_verify(void *token, void *sig, int siglen)
list_for_each(item, &key_list) {
key = node_to_item(item, struct adb_public_key, node);
- ret = RSA_verify(&key->key, sig, siglen, token);
+ ret = RSA_verify(&key->key, sig, siglen, token, SHA_DIGEST_SIZE);
if (ret)
break;
}
diff --git a/adb/mutex_list.h b/adb/mutex_list.h
index 652dd7341..ff7275129 100644
--- a/adb/mutex_list.h
+++ b/adb/mutex_list.h
@@ -6,7 +6,6 @@
#ifndef ADB_MUTEX
#error ADB_MUTEX not defined when including this file
#endif
-ADB_MUTEX(dns_lock)
ADB_MUTEX(socket_list_lock)
ADB_MUTEX(transport_lock)
#if ADB_HOST
diff --git a/adb/remount_service.c b/adb/remount_service.c
index 4cb41e7d1..ad61284b6 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -72,6 +72,8 @@ static char *find_mount(const char *dir)
static int remount_system()
{
char *dev;
+ int fd;
+ int OFF = 0;
if (system_ro == 0) {
return 0;
@@ -82,6 +84,13 @@ static int remount_system()
if (!dev)
return -1;
+ fd = unix_open(dev, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ ioctl(fd, BLKROSET, &OFF);
+ adb_close(fd);
+
system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL);
free(dev);
diff --git a/adb/services.c b/adb/services.c
index 54d21a8b7..f0d587817 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
@@ -34,6 +35,7 @@
# endif
#else
# include <cutils/android_reboot.h>
+# include <cutils/properties.h>
#endif
typedef struct stinfo stinfo;
@@ -53,59 +55,7 @@ void *service_bootstrap_func(void *x)
return 0;
}
-#if ADB_HOST
-ADB_MUTEX_DEFINE( dns_lock );
-
-static void dns_service(int fd, void *cookie)
-{
- char *hostname = cookie;
- struct hostent *hp;
- unsigned zero = 0;
-
- adb_mutex_lock(&dns_lock);
- hp = gethostbyname(hostname);
- free(cookie);
- if(hp == 0) {
- writex(fd, &zero, 4);
- } else {
- writex(fd, hp->h_addr, 4);
- }
- adb_mutex_unlock(&dns_lock);
- adb_close(fd);
-}
-#else
-extern int recovery_mode;
-
-static void recover_service(int s, void *cookie)
-{
- unsigned char buf[4096];
- unsigned count = (unsigned) cookie;
- int fd;
-
- fd = adb_creat("/tmp/update", 0644);
- if(fd < 0) {
- adb_close(s);
- return;
- }
-
- while(count > 0) {
- unsigned xfer = (count > 4096) ? 4096 : count;
- if(readx(s, buf, xfer)) break;
- if(writex(fd, buf, xfer)) break;
- count -= xfer;
- }
-
- if(count == 0) {
- writex(s, "OKAY", 4);
- } else {
- writex(s, "FAIL", 4);
- }
- adb_close(fd);
- adb_close(s);
-
- fd = adb_creat("/tmp/update.begin", 0644);
- adb_close(fd);
-}
+#if !ADB_HOST
void restart_root_service(int fd, void *cookie)
{
@@ -165,6 +115,7 @@ void restart_usb_service(int fd, void *cookie)
void reboot_service(int fd, void *arg)
{
char buf[100];
+ char property_val[PROPERTY_VALUE_MAX];
int pid, ret;
sync();
@@ -182,51 +133,25 @@ void reboot_service(int fd, void *arg)
waitpid(pid, &ret, 0);
}
- ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
+ ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg);
+ if (ret >= (int) sizeof(property_val)) {
+ snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
+ writex(fd, buf, strlen(buf));
+ goto cleanup;
+ }
+
+ ret = property_set(ANDROID_RB_PROPERTY, property_val);
if (ret < 0) {
- snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+ snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
writex(fd, buf, strlen(buf));
}
+cleanup:
free(arg);
adb_close(fd);
}
#endif
-#if 0
-static void echo_service(int fd, void *cookie)
-{
- char buf[4096];
- int r;
- char *p;
- int c;
-
- for(;;) {
- r = adb_read(fd, buf, 4096);
- if(r == 0) goto done;
- if(r < 0) {
- if(errno == EINTR) continue;
- else goto done;
- }
-
- c = r;
- p = buf;
- while(c > 0) {
- r = write(fd, p, c);
- if(r > 0) {
- c -= r;
- p += r;
- continue;
- }
- if((r < 0) && (errno == EINTR)) continue;
- goto done;
- }
- }
-done:
- close(fd);
-}
-#endif
-
static int create_service_thread(void (*func)(int, void *), void *cookie)
{
stinfo *sti;
@@ -413,9 +338,7 @@ int service_to_fd(const char *name)
disable_tcp_nagle(ret);
} else {
#if ADB_HOST
- adb_mutex_lock(&dns_lock);
ret = socket_network_client(name + 1, port, SOCK_STREAM);
- adb_mutex_unlock(&dns_lock);
#else
return -1;
#endif
@@ -434,18 +357,11 @@ int service_to_fd(const char *name)
ret = socket_local_client(name + 16,
ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
-#if ADB_HOST
- } else if(!strncmp("dns:", name, 4)){
- char *n = strdup(name + 4);
- if(n == 0) return -1;
- ret = create_service_thread(dns_service, n);
-#else /* !ADB_HOST */
+#if !ADB_HOST
} else if(!strncmp("dev:", name, 4)) {
ret = unix_open(name + 4, O_RDWR);
} else if(!strncmp(name, "framebuffer:", 12)) {
ret = create_service_thread(framebuffer_service, 0);
- } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
- ret = create_service_thread(recover_service, (void*) atoi(name + 8));
} else if (!strncmp(name, "jdwp:", 5)) {
ret = create_jdwp_connection_fd(atoi(name+5));
} else if (!strncmp(name, "log:", 4)) {
@@ -481,10 +397,6 @@ int service_to_fd(const char *name)
} else if(!strncmp(name, "usb:", 4)) {
ret = create_service_thread(restart_usb_service, NULL);
#endif
-#if 0
- } else if(!strncmp(name, "echo:", 5)){
- ret = create_service_thread(echo_service, 0);
-#endif
}
if (ret >= 0) {
close_on_exec(ret);
@@ -519,6 +431,124 @@ static void wait_for_state(int fd, void* cookie)
adb_close(fd);
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) == 0) {
+ snprintf(buffer, buffer_size, "bad port number %s", portstr);
+ return;
+ }
+ } else {
+ port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
+ }
+
+ snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
+
+ fd = socket_network_client(hostbuf, port, SOCK_STREAM);
+ if (fd < 0) {
+ snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
+ return;
+ }
+
+ D("client: connected on remote on fd %d\n", fd);
+ close_on_exec(fd);
+ disable_tcp_nagle(fd);
+
+ ret = register_socket_transport(fd, serial, port, 0);
+ if (ret < 0) {
+ adb_close(fd);
+ snprintf(buffer, buffer_size, "already connected to %s", serial);
+ } else {
+ snprintf(buffer, buffer_size, "connected to %s", serial);
+ }
+}
+
+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);
+ 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);
+ 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. */
+ 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);
+ return;
+ }
+
+ /* 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.");
+ return;
+ }
+
+ /* 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);
+ } else {
+ snprintf(buffer, buffer_size,
+ "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 = cookie;
+
+ if (!strncmp(host, "emu:", 4)) {
+ connect_emulator(host + 4, buf, sizeof(buf));
+ } else {
+ connect_device(host, buf, sizeof(buf));
+ }
+
+ // Send response for emulator and device
+ snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf);
+ writex(fd, resp, strlen(resp));
+ adb_close(fd);
+}
#endif
#if ADB_HOST
@@ -552,6 +582,10 @@ asocket* host_service_to_socket(const char* name, const char *serial)
int fd = create_service_thread(wait_for_state, sinfo);
return create_local_socket(fd);
+ } else if (!strncmp(name, "connect:", 8)) {
+ const char *host = name + 8;
+ int fd = create_service_thread(connect_service, (void *)host);
+ return create_local_socket(fd);
}
return NULL;
}
diff --git a/adb/sockets.c b/adb/sockets.c
index 305cb4429..f17608b62 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -844,7 +844,7 @@ static void smart_socket_close(asocket *s)
free(s);
}
-asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act))
+static asocket *create_smart_socket(void)
{
D("Creating smart socket \n");
asocket *s = calloc(1, sizeof(asocket));
@@ -852,21 +852,15 @@ asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act))
s->enqueue = smart_socket_enqueue;
s->ready = smart_socket_ready;
s->close = smart_socket_close;
- s->extra = action_cb;
- D("SS(%d): created %p\n", s->id, action_cb);
+ D("SS(%d)\n", s->id);
return s;
}
-void smart_socket_action(asocket *s, const char *act)
-{
-
-}
-
void connect_to_smartsocket(asocket *s)
{
D("Connecting to smart socket \n");
- asocket *ss = create_smart_socket(smart_socket_action);
+ asocket *ss = create_smart_socket();
s->peer = ss;
ss->peer = s;
s->ready(s);
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 0252ef3b8..4033b7220 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -261,7 +261,6 @@ extern char* adb_strtok_r(char *str, const char *delim, char **saveptr);
#include "fdevent.h"
#include <cutils/sockets.h>
-#include <cutils/properties.h>
#include <cutils/misc.h>
#include <signal.h>
#include <sys/wait.h>
diff --git a/adb/transport.c b/adb/transport.c
index b4abb66ec..224fe556b 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -32,6 +32,11 @@ static atransport transport_list = {
.prev = &transport_list,
};
+static atransport pending_list = {
+ .next = &pending_list,
+ .prev = &pending_list,
+};
+
ADB_MUTEX_DEFINE( transport_lock );
#if ADB_TRACE
@@ -645,8 +650,11 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
}
}
- /* put us on the master device list */
adb_mutex_lock(&transport_lock);
+ /* remove from pending list */
+ t->next->prev = t->prev;
+ t->prev->next = t->next;
+ /* put us on the master device list */
t->next = &transport_list;
t->prev = transport_list.prev;
t->next->prev = t;
@@ -989,9 +997,10 @@ void close_usb_devices()
}
#endif // ADB_HOST
-void register_socket_transport(int s, const char *serial, int port, int local)
+int register_socket_transport(int s, const char *serial, int port, int local)
{
atransport *t = calloc(1, sizeof(atransport));
+ atransport *n;
char buff[32];
if (!serial) {
@@ -999,15 +1008,37 @@ void register_socket_transport(int s, const char *serial, int port, int local)
serial = buff;
}
D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port);
- if ( init_socket_transport(t, s, port, local) < 0 ) {
- adb_close(s);
+ if (init_socket_transport(t, s, port, local) < 0) {
free(t);
- return;
+ return -1;
}
- if(serial) {
- t->serial = strdup(serial);
+
+ adb_mutex_lock(&transport_lock);
+ for (n = pending_list.next; n != &pending_list; n = n->next) {
+ if (n->serial && !strcmp(serial, n->serial)) {
+ adb_mutex_unlock(&transport_lock);
+ free(t);
+ return -1;
+ }
+ }
+
+ for (n = transport_list.next; n != &transport_list; n = n->next) {
+ if (n->serial && !strcmp(serial, n->serial)) {
+ adb_mutex_unlock(&transport_lock);
+ free(t);
+ return -1;
+ }
}
+
+ t->next = &pending_list;
+ t->prev = pending_list.prev;
+ t->next->prev = t;
+ t->prev->next = t;
+ t->serial = strdup(serial);
+ adb_mutex_unlock(&transport_lock);
+
register_transport(t);
+ return 0;
}
#if ADB_HOST
@@ -1077,6 +1108,14 @@ void register_usb_transport(usb_handle *usb, const char *serial, const char *dev
if(devpath) {
t->devpath = strdup(devpath);
}
+
+ adb_mutex_lock(&transport_lock);
+ t->next = &pending_list;
+ t->prev = pending_list.prev;
+ t->next->prev = t;
+ t->prev->next = t;
+ adb_mutex_unlock(&transport_lock);
+
register_transport(t);
}
diff --git a/adb/transport_local.c b/adb/transport_local.c
index 96a24ba50..1cfa24d7f 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -21,6 +21,9 @@
#include "sysdeps.h"
#include <sys/types.h>
+#if !ADB_HOST
+#include <cutils/properties.h>
+#endif
#define TRACE_TAG TRACE_TRANSPORT
#include "adb.h"
diff --git a/adb/utils.c b/adb/utils.c
deleted file mode 100644
index 91518bab6..000000000
--- a/adb/utils.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-#include "utils.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-char*
-buff_addc (char* buff, char* buffEnd, int c)
-{
- int avail = buffEnd - buff;
-
- if (avail <= 0) /* already in overflow mode */
- return buff;
-
- if (avail == 1) { /* overflowing, the last byte is reserved for zero */
- buff[0] = 0;
- return buff + 1;
- }
-
- buff[0] = (char) c; /* add char and terminating zero */
- buff[1] = 0;
- return buff + 1;
-}
-
-char*
-buff_adds (char* buff, char* buffEnd, const char* s)
-{
- int slen = strlen(s);
-
- return buff_addb(buff, buffEnd, s, slen);
-}
-
-char*
-buff_addb (char* buff, char* buffEnd, const void* data, int len)
-{
- int avail = (buffEnd - buff);
-
- if (avail <= 0 || len <= 0) /* already overflowing */
- return buff;
-
- if (len > avail)
- len = avail;
-
- memcpy(buff, data, len);
-
- buff += len;
-
- /* ensure there is a terminating zero */
- if (buff >= buffEnd) { /* overflow */
- buff[-1] = 0;
- } else
- buff[0] = 0;
-
- return buff;
-}
-
-char*
-buff_add (char* buff, char* buffEnd, const char* format, ... )
-{
- int avail;
-
- avail = (buffEnd - buff);
-
- if (avail > 0) {
- va_list args;
- int nn;
-
- va_start(args, format);
- nn = vsnprintf( buff, avail, format, args);
- va_end(args);
-
- if (nn < 0) {
- /* some C libraries return -1 in case of overflow,
- * but they will also do that if the format spec is
- * invalid. We assume ADB is not buggy enough to
- * trigger that last case. */
- nn = avail;
- }
- else if (nn > avail) {
- nn = avail;
- }
-
- buff += nn;
-
- /* ensure that there is a terminating zero */
- if (buff >= buffEnd)
- buff[-1] = 0;
- else
- buff[0] = 0;
- }
- return buff;
-}
diff --git a/adb/utils.h b/adb/utils.h
deleted file mode 100644
index f70ecd24d..000000000
--- a/adb/utils.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 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_UTILS_H
-#define _ADB_UTILS_H
-
-/* bounded buffer functions */
-
-/* all these functions are used to append data to a bounded buffer.
- *
- * after each operation, the buffer is guaranteed to be zero-terminated,
- * even in the case of an overflow. they all return the new buffer position
- * which allows one to use them in succession, only checking for overflows
- * at the end. For example:
- *
- * BUFF_DECL(temp,p,end,1024);
- * char* p;
- *
- * p = buff_addc(temp, end, '"');
- * p = buff_adds(temp, end, string);
- * p = buff_addc(temp, end, '"');
- *
- * if (p >= end) {
- * overflow detected. note that 'temp' is
- * zero-terminated for safety.
- * }
- * return strdup(temp);
- */
-
-/* tries to add a character to the buffer, in case of overflow
- * this will only write a terminating zero and return buffEnd.
- */
-char* buff_addc (char* buff, char* buffEnd, int c);
-
-/* tries to add a string to the buffer */
-char* buff_adds (char* buff, char* buffEnd, const char* s);
-
-/* tries to add a bytes to the buffer. the input can contain zero bytes,
- * but a terminating zero will always be appended at the end anyway
- */
-char* buff_addb (char* buff, char* buffEnd, const void* data, int len);
-
-/* tries to add a formatted string to a bounded buffer */
-char* buff_add (char* buff, char* buffEnd, const char* format, ... );
-
-/* convenience macro used to define a bounded buffer, as well as
- * a 'cursor' and 'end' variables all in one go.
- *
- * note: this doesn't place an initial terminating zero in the buffer,
- * you need to use one of the buff_ functions for this. or simply
- * do _cursor[0] = 0 manually.
- */
-#define BUFF_DECL(_buff,_cursor,_end,_size) \
- char _buff[_size], *_cursor=_buff, *_end = _cursor + (_size)
-
-#endif /* _ADB_UTILS_H */