summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk16
-rw-r--r--adb_install.cpp4
-rw-r--r--applypatch/bspatch.c1
-rw-r--r--applypatch/imgpatch.c1
-rw-r--r--asn1_decoder.cpp1
-rw-r--r--common.h3
-rw-r--r--edify/Android.mk7
-rw-r--r--edify/main.c3
-rw-r--r--fuse_sdcard_provider.c1
-rw-r--r--install.cpp1
-rw-r--r--minadbd/Android.mk44
-rw-r--r--minadbd/README.txt37
-rw-r--r--minadbd/adb.c402
-rw-r--r--minadbd/adb.h424
-rw-r--r--minadbd/adb_main.c (renamed from minadbd/transport.h)39
-rw-r--r--minadbd/fdevent.c695
-rw-r--r--minadbd/fdevent.h83
-rw-r--r--minadbd/fuse_adb_provider.c21
-rw-r--r--minadbd/fuse_adb_provider.h19
-rw-r--r--minadbd/fuse_adb_provider_test.cpp89
-rw-r--r--minadbd/mutex_list.h26
-rw-r--r--minadbd/services.c56
-rw-r--r--minadbd/sockets.c731
-rw-r--r--minadbd/sysdeps.h494
-rw-r--r--minadbd/transport.c803
-rw-r--r--minadbd/transport_usb.c121
-rw-r--r--minadbd/usb_linux_client.c493
-rw-r--r--minadbd/utils.c106
-rw-r--r--minadbd/utils.h68
-rw-r--r--minui/Android.mk15
-rw-r--r--minui/events.c6
-rw-r--r--minui/graphics.c8
-rw-r--r--minui/graphics_adf.c5
-rw-r--r--minui/graphics_fbdev.c14
-rw-r--r--minui/resources.c13
-rw-r--r--minzip/DirUtil.c4
-rw-r--r--minzip/Hash.c11
-rw-r--r--minzip/Zip.c59
-rw-r--r--minzip/Zip.h51
-rw-r--r--mtdutils/mounts.c89
-rw-r--r--recovery.cpp13
-rw-r--r--tests/Android.mk47
-rw-r--r--tools/ota/check-lost+found.c1
-rw-r--r--uncrypt/uncrypt.c2
-rw-r--r--updater/Android.mk2
-rw-r--r--updater/MODULE_LICENSE_GPL0
-rw-r--r--updater/NOTICE339
-rw-r--r--updater/updater.c1
-rw-r--r--verifier.cpp5
-rw-r--r--verifier_test.cpp6
50 files changed, 312 insertions, 5168 deletions
diff --git a/Android.mk b/Android.mk
index 1a91f0029..dd1e96e7a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -54,6 +54,11 @@ RECOVERY_FSTAB_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_C_INCLUDES += \
+ system/vold \
+ system/extras/ext4_utils \
+ system/core/adb \
+
LOCAL_STATIC_LIBRARIES := \
libext4_utils_static \
libsparse_static \
@@ -75,15 +80,11 @@ LOCAL_STATIC_LIBRARIES := \
ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_CFLAGS += -DUSE_EXT4
- LOCAL_C_INCLUDES += system/extras/ext4_utils system/vold
+ LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_STATIC_LIBRARIES += libext4_utils_static libz
endif
-# This binary is in the recovery ramdisk, which is otherwise a copy of root.
-# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
-# a (redundant) copy of the binary in /system/bin for user builds.
-# TODO: Build the ramdisk image in a more principled way.
-LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
ifeq ($(TARGET_RECOVERY_UI_LIB),)
LOCAL_SRC_FILES += default_device.cpp
@@ -91,9 +92,6 @@ else
LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
endif
-LOCAL_C_INCLUDES += system/extras/ext4_utils
-LOCAL_C_INCLUDES += external/openssl/include
-
include $(BUILD_EXECUTABLE)
# All the APIs for testing
diff --git a/adb_install.cpp b/adb_install.cpp
index be3b9a063..e3289608f 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -61,9 +61,7 @@ stop_adbd() {
static void
maybe_restart_adbd() {
- char value[PROPERTY_VALUE_MAX+1];
- int len = property_get("ro.debuggable", value, NULL);
- if (len == 1 && value[0] == '1') {
+ if (is_ro_debuggable()) {
ui->Print("Restarting adbd...\n");
set_usb_driver(true);
property_set("ctl.start", "adbd");
diff --git a/applypatch/bspatch.c b/applypatch/bspatch.c
index b34ec2a88..b57760eda 100644
--- a/applypatch/bspatch.c
+++ b/applypatch/bspatch.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
+#include <malloc.h>
#include <unistd.h>
#include <string.h>
diff --git a/applypatch/imgpatch.c b/applypatch/imgpatch.c
index 33c448762..09b0a7397 100644
--- a/applypatch/imgpatch.c
+++ b/applypatch/imgpatch.c
@@ -21,6 +21,7 @@
#include <sys/cdefs.h>
#include <sys/stat.h>
#include <errno.h>
+#include <malloc.h>
#include <unistd.h>
#include <string.h>
diff --git a/asn1_decoder.cpp b/asn1_decoder.cpp
index 7280f7480..e7aef781c 100644
--- a/asn1_decoder.cpp
+++ b/asn1_decoder.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <malloc.h>
#include <stdint.h>
#include <string.h>
diff --git a/common.h b/common.h
index 768f499f9..4f1c099df 100644
--- a/common.h
+++ b/common.h
@@ -17,6 +17,7 @@
#ifndef RECOVERY_COMMON_H
#define RECOVERY_COMMON_H
+#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
@@ -46,6 +47,8 @@ FILE* fopen_path(const char *path, const char *mode);
void ui_print(const char* format, ...);
+bool is_ro_debuggable();
+
#ifdef __cplusplus
}
#endif
diff --git a/edify/Android.mk b/edify/Android.mk
index 61ed6fa17..03c04e432 100644
--- a/edify/Android.mk
+++ b/edify/Android.mk
@@ -7,9 +7,10 @@ edify_src_files := \
parser.y \
expr.c
-# "-x c" forces the lex/yacc files to be compiled as c;
-# the build system otherwise forces them to be c++.
-edify_cflags := -x c
+# "-x c" forces the lex/yacc files to be compiled as c the build system
+# otherwise forces them to be c++. Need to also add an explicit -std because the
+# build system will soon default C++ to -std=c++11.
+edify_cflags := -x c -std=gnu89
#
# Build the host-side command line tool
diff --git a/edify/main.c b/edify/main.c
index b3fad53b8..b1baa0b13 100644
--- a/edify/main.c
+++ b/edify/main.c
@@ -25,13 +25,12 @@ extern int yyparse(Expr** root, int* error_count);
int expect(const char* expr_str, const char* expected, int* errors) {
Expr* e;
- int error;
char* result;
printf(".");
int error_count = parse_string(expr_str, &e, &error_count);
- if (error > 0 || error_count > 0) {
+ if (error_count > 0) {
printf("error parsing \"%s\" (%d errors)\n",
expr_str, error_count);
++*errors;
diff --git a/fuse_sdcard_provider.c b/fuse_sdcard_provider.c
index 19fb52df0..ca8c914f9 100644
--- a/fuse_sdcard_provider.c
+++ b/fuse_sdcard_provider.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/mount.h>
diff --git a/install.cpp b/install.cpp
index 9db5640a0..31606bb1a 100644
--- a/install.cpp
+++ b/install.cpp
@@ -18,6 +18,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index 04956d870..79fe96b93 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -1,32 +1,36 @@
# Copyright 2005 The Android Open Source Project
-#
-# Android.mk for adb
-#
LOCAL_PATH:= $(call my-dir)
-# minadbd library
-# =========================================================
+minadbd_cflags := \
+ -Wall -Werror \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -DADB_HOST=0 \
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- adb.c \
- fdevent.c \
- fuse_adb_provider.c \
- transport.c \
- transport_usb.c \
- sockets.c \
- services.c \
- usb_linux_client.c \
- utils.c
-
-LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
-LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-LOCAL_C_INCLUDES += bootable/recovery
+ adb_main.c \
+ fuse_adb_provider.c \
+ services.c \
LOCAL_MODULE := libminadbd
-
-LOCAL_STATIC_LIBRARIES := libfusesideload libcutils libc
+LOCAL_CFLAGS := $(minadbd_cflags)
+LOCAL_CONLY_FLAGS := -Wimplicit-function-declaration
+LOCAL_C_INCLUDES := bootable/recovery system/core/adb
+LOCAL_WHOLE_STATIC_LIBRARIES := libadbd
include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_CLANG := true
+LOCAL_MODULE := minadbd_test
+LOCAL_SRC_FILES := fuse_adb_provider_test.cpp
+LOCAL_CFLAGS := $(minadbd_cflags)
+LOCAL_C_INCLUDES := $(LOCAL_PATH) system/core/adb
+LOCAL_STATIC_LIBRARIES := libminadbd
+LOCAL_SHARED_LIBRARIES := liblog libutils
+
+include $(BUILD_NATIVE_TEST)
diff --git a/minadbd/README.txt b/minadbd/README.txt
index c9df484c3..e69dc87c6 100644
--- a/minadbd/README.txt
+++ b/minadbd/README.txt
@@ -1,39 +1,8 @@
-The contents of this directory are copied from system/core/adb, with
-the following changes:
+minadbd is now mostly built from libadbd. The fuse features are unique to
+minadbd, and services.c has been modified as follows:
-adb.c
- - much support for host mode and non-linux OS's stripped out; this
- version only runs as adbd on the device.
- - always setuid/setgid's itself to the shell user
- - only uses USB transport
- - references to JDWP removed
- - main() removed
- - all ADB_HOST and win32 code removed
- - removed listeners, logging code, background server (for host)
-
-adb.h
- - minor changes to match adb.c changes
-
-sockets.c
- - references to JDWP removed
- - ADB_HOST code removed
-
-services.c
- - all services except echo_service (which is commented out) removed
+ - all services removed
- all host mode support removed
- sideload_service() added; this is the only service supported. It
receives a single blob of data, writes it to a fixed filename, and
makes the process exit.
-
-Android.mk
- - only builds in adbd mode; builds as static library instead of a
- standalone executable.
-
-sysdeps.h
- - changes adb_creat() to use O_NOFOLLOW
-
-transport.c
- - removed ADB_HOST code
-
-transport_usb.c
- - removed ADB_HOST code
diff --git a/minadbd/adb.c b/minadbd/adb.c
deleted file mode 100644
index 127d072be..000000000
--- a/minadbd/adb.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#define TRACE_TAG TRACE_ADB
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include "sysdeps.h"
-#include "adb.h"
-
-#include <private/android_filesystem_config.h>
-
-#if ADB_TRACE
-ADB_MUTEX_DEFINE( D_lock );
-#endif
-
-int HOST = 0;
-
-static const char *adb_device_banner = "sideload";
-
-void fatal(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(-1);
-}
-
-void fatal_errno(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "error: %s: ", strerror(errno));
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(-1);
-}
-
-int adb_trace_mask;
-
-/* read a comma/space/colum/semi-column separated list of tags
- * from the ADB_TRACE environment variable and build the trace
- * mask from it. note that '1' and 'all' are special cases to
- * enable all tracing
- */
-void adb_trace_init(void)
-{
- const char* p = getenv("ADB_TRACE");
- const char* q;
-
- static const struct {
- const char* tag;
- int flag;
- } tags[] = {
- { "1", 0 },
- { "all", 0 },
- { "adb", TRACE_ADB },
- { "sockets", TRACE_SOCKETS },
- { "packets", TRACE_PACKETS },
- { "rwx", TRACE_RWX },
- { "usb", TRACE_USB },
- { "sync", TRACE_SYNC },
- { "sysdeps", TRACE_SYSDEPS },
- { "transport", TRACE_TRANSPORT },
- { "jdwp", TRACE_JDWP },
- { "services", TRACE_SERVICES },
- { NULL, 0 }
- };
-
- if (p == NULL)
- return;
-
- /* use a comma/column/semi-colum/space separated list */
- while (*p) {
- int len, tagn;
-
- q = strpbrk(p, " ,:;");
- if (q == NULL) {
- q = p + strlen(p);
- }
- len = q - p;
-
- for (tagn = 0; tags[tagn].tag != NULL; tagn++)
- {
- int taglen = strlen(tags[tagn].tag);
-
- if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
- {
- int flag = tags[tagn].flag;
- if (flag == 0) {
- adb_trace_mask = ~0;
- return;
- }
- adb_trace_mask |= (1 << flag);
- break;
- }
- }
- p = q;
- if (*p)
- p++;
- }
-}
-
-
-apacket *get_apacket(void)
-{
- apacket *p = malloc(sizeof(apacket));
- if(p == 0) fatal("failed to allocate an apacket");
- memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
- return p;
-}
-
-void put_apacket(apacket *p)
-{
- free(p);
-}
-
-void handle_online(void)
-{
- D("adb: online\n");
-}
-
-void handle_offline(atransport *t)
-{
- D("adb: offline\n");
- //Close the associated usb
- run_transport_disconnects(t);
-}
-
-#if TRACE_PACKETS
-#define DUMPMAX 32
-void print_packet(const char *label, apacket *p)
-{
- char *tag;
- char *x;
- unsigned count;
-
- switch(p->msg.command){
- case A_SYNC: tag = "SYNC"; break;
- case A_CNXN: tag = "CNXN" ; break;
- case A_OPEN: tag = "OPEN"; break;
- case A_OKAY: tag = "OKAY"; break;
- case A_CLSE: tag = "CLSE"; break;
- case A_WRTE: tag = "WRTE"; break;
- default: tag = "????"; break;
- }
-
- fprintf(stderr, "%s: %s %08x %08x %04x \"",
- label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
- count = p->msg.data_length;
- x = (char*) p->data;
- if(count > DUMPMAX) {
- count = DUMPMAX;
- tag = "\n";
- } else {
- tag = "\"\n";
- }
- while(count-- > 0){
- if((*x >= ' ') && (*x < 127)) {
- fputc(*x, stderr);
- } else {
- fputc('.', stderr);
- }
- x++;
- }
- fprintf(stderr, tag);
-}
-#endif
-
-static void send_ready(unsigned local, unsigned remote, atransport *t)
-{
- D("Calling send_ready \n");
- apacket *p = get_apacket();
- p->msg.command = A_OKAY;
- p->msg.arg0 = local;
- p->msg.arg1 = remote;
- send_packet(p, t);
-}
-
-static void send_close(unsigned local, unsigned remote, atransport *t)
-{
- D("Calling send_close \n");
- apacket *p = get_apacket();
- p->msg.command = A_CLSE;
- p->msg.arg0 = local;
- p->msg.arg1 = remote;
- send_packet(p, t);
-}
-
-static void send_connect(atransport *t)
-{
- D("Calling send_connect \n");
- apacket *cp = get_apacket();
- cp->msg.command = A_CNXN;
- cp->msg.arg0 = A_VERSION;
- cp->msg.arg1 = MAX_PAYLOAD;
- snprintf((char*) cp->data, sizeof cp->data, "%s::",
- HOST ? "host" : adb_device_banner);
- cp->msg.data_length = strlen((char*) cp->data) + 1;
- send_packet(cp, t);
-}
-
-void parse_banner(char *banner, atransport *t)
-{
- char *type, *product, *end;
-
- D("parse_banner: %s\n", banner);
- type = banner;
- product = strchr(type, ':');
- if(product) {
- *product++ = 0;
- } else {
- product = "";
- }
-
- /* remove trailing ':' */
- end = strchr(product, ':');
- if(end) *end = 0;
-
- /* save product name in device structure */
- if (t->product == NULL) {
- t->product = strdup(product);
- } else if (strcmp(product, t->product) != 0) {
- free(t->product);
- t->product = strdup(product);
- }
-
- if(!strcmp(type, "bootloader")){
- D("setting connection_state to CS_BOOTLOADER\n");
- t->connection_state = CS_BOOTLOADER;
- update_transports();
- return;
- }
-
- if(!strcmp(type, "device")) {
- D("setting connection_state to CS_DEVICE\n");
- t->connection_state = CS_DEVICE;
- update_transports();
- return;
- }
-
- if(!strcmp(type, "recovery")) {
- D("setting connection_state to CS_RECOVERY\n");
- t->connection_state = CS_RECOVERY;
- update_transports();
- return;
- }
-
- if(!strcmp(type, "sideload")) {
- D("setting connection_state to CS_SIDELOAD\n");
- t->connection_state = CS_SIDELOAD;
- update_transports();
- return;
- }
-
- t->connection_state = CS_HOST;
-}
-
-void handle_packet(apacket *p, atransport *t)
-{
- asocket *s;
-
- D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
- ((char*) (&(p->msg.command)))[1],
- ((char*) (&(p->msg.command)))[2],
- ((char*) (&(p->msg.command)))[3]);
- print_packet("recv", p);
-
- switch(p->msg.command){
- case A_SYNC:
- if(p->msg.arg0){
- send_packet(p, t);
- if(HOST) send_connect(t);
- } else {
- t->connection_state = CS_OFFLINE;
- handle_offline(t);
- send_packet(p, t);
- }
- return;
-
- case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
- /* XXX verify version, etc */
- if(t->connection_state != CS_OFFLINE) {
- t->connection_state = CS_OFFLINE;
- handle_offline(t);
- }
- parse_banner((char*) p->data, t);
- handle_online();
- if(!HOST) send_connect(t);
- break;
-
- case A_OPEN: /* OPEN(local-id, 0, "destination") */
- if(t->connection_state != CS_OFFLINE) {
- char *name = (char*) p->data;
- name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
- s = create_local_service_socket(name);
- if(s == 0) {
- send_close(0, p->msg.arg0, t);
- } else {
- s->peer = create_remote_socket(p->msg.arg0, t);
- s->peer->peer = s;
- send_ready(s->id, s->peer->id, t);
- s->ready(s);
- }
- }
- break;
-
- case A_OKAY: /* READY(local-id, remote-id, "") */
- if(t->connection_state != CS_OFFLINE) {
- if((s = find_local_socket(p->msg.arg1))) {
- if(s->peer == 0) {
- s->peer = create_remote_socket(p->msg.arg0, t);
- s->peer->peer = s;
- }
- s->ready(s);
- }
- }
- break;
-
- case A_CLSE: /* CLOSE(local-id, remote-id, "") */
- if(t->connection_state != CS_OFFLINE) {
- if((s = find_local_socket(p->msg.arg1))) {
- s->close(s);
- }
- }
- break;
-
- case A_WRTE:
- if(t->connection_state != CS_OFFLINE) {
- if((s = find_local_socket(p->msg.arg1))) {
- unsigned rid = p->msg.arg0;
- p->len = p->msg.data_length;
-
- if(s->enqueue(s, p) == 0) {
- D("Enqueue the socket\n");
- send_ready(s->id, rid, t);
- }
- return;
- }
- }
- break;
-
- default:
- printf("handle_packet: what is %08x?!\n", p->msg.command);
- }
-
- put_apacket(p);
-}
-
-static void adb_cleanup(void)
-{
- usb_cleanup();
-}
-
-int adb_main()
-{
- atexit(adb_cleanup);
-#if defined(HAVE_FORKEXEC)
- // No SIGCHLD. Let the service subproc handle its children.
- signal(SIGPIPE, SIG_IGN);
-#endif
-
- init_transport_registration();
-
- // The minimal version of adbd only uses USB.
- if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
- // listen on USB
- usb_init();
- }
-
- D("Event loop starting\n");
-
- fdevent_loop();
-
- usb_cleanup();
-
- return 0;
-}
diff --git a/minadbd/adb.h b/minadbd/adb.h
deleted file mode 100644
index 714868f5c..000000000
--- a/minadbd/adb.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2007 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_H
-#define __ADB_H
-
-#include <limits.h>
-
-#include "transport.h" /* readx(), writex() */
-#include "fdevent.h"
-
-#define MAX_PAYLOAD 4096
-
-#define A_SYNC 0x434e5953
-#define A_CNXN 0x4e584e43
-#define A_OPEN 0x4e45504f
-#define A_OKAY 0x59414b4f
-#define A_CLSE 0x45534c43
-#define A_WRTE 0x45545257
-
-#define A_VERSION 0x01000000 // ADB protocol version
-
-#define ADB_VERSION_MAJOR 1 // Used for help/version information
-#define ADB_VERSION_MINOR 0 // Used for help/version information
-
-#define ADB_SERVER_VERSION 29 // Increment this when we want to force users to start a new adb server
-
-typedef struct amessage amessage;
-typedef struct apacket apacket;
-typedef struct asocket asocket;
-typedef struct aservice aservice;
-typedef struct atransport atransport;
-typedef struct adisconnect adisconnect;
-typedef struct usb_handle usb_handle;
-
-struct amessage {
- unsigned command; /* command identifier constant */
- unsigned arg0; /* first argument */
- unsigned arg1; /* second argument */
- unsigned data_length; /* length of payload (0 is allowed) */
- unsigned data_check; /* checksum of data payload */
- unsigned magic; /* command ^ 0xffffffff */
-};
-
-struct apacket
-{
- apacket *next;
-
- unsigned len;
- unsigned char *ptr;
-
- amessage msg;
- unsigned char data[MAX_PAYLOAD];
-};
-
-/* An asocket represents one half of a connection between a local and
-** remote entity. A local asocket is bound to a file descriptor. A
-** remote asocket is bound to the protocol engine.
-*/
-struct asocket {
- /* chain pointers for the local/remote list of
- ** asockets that this asocket lives in
- */
- asocket *next;
- asocket *prev;
-
- /* the unique identifier for this asocket
- */
- unsigned id;
-
- /* flag: set when the socket's peer has closed
- ** but packets are still queued for delivery
- */
- int closing;
-
- /* the asocket we are connected to
- */
-
- asocket *peer;
-
- /* For local asockets, the fde is used to bind
- ** us to our fd event system. For remote asockets
- ** these fields are not used.
- */
- fdevent fde;
- int fd;
-
- /* queue of apackets waiting to be written
- */
- apacket *pkt_first;
- apacket *pkt_last;
-
- /* enqueue is called by our peer when it has data
- ** for us. It should return 0 if we can accept more
- ** data or 1 if not. If we return 1, we must call
- ** peer->ready() when we once again are ready to
- ** receive data.
- */
- int (*enqueue)(asocket *s, apacket *pkt);
-
- /* ready is called by the peer when it is ready for
- ** us to send data via enqueue again
- */
- void (*ready)(asocket *s);
-
- /* close is called by the peer when it has gone away.
- ** we are not allowed to make any further calls on the
- ** peer once our close method is called.
- */
- void (*close)(asocket *s);
-
- /* socket-type-specific extradata */
- void *extra;
-
- /* A socket is bound to atransport */
- atransport *transport;
-};
-
-
-/* the adisconnect structure is used to record a callback that
-** will be called whenever a transport is disconnected (e.g. by the user)
-** this should be used to cleanup objects that depend on the
-** transport (e.g. remote sockets, etc...)
-*/
-struct adisconnect
-{
- void (*func)(void* opaque, atransport* t);
- void* opaque;
- adisconnect* next;
- adisconnect* prev;
-};
-
-
-/* a transport object models the connection to a remote device or emulator
-** there is one transport per connected device/emulator. a "local transport"
-** connects through TCP (for the emulator), while a "usb transport" through
-** USB (for real devices)
-**
-** note that kTransportHost doesn't really correspond to a real transport
-** object, it's a special value used to indicate that a client wants to
-** connect to a service implemented within the ADB server itself.
-*/
-typedef enum transport_type {
- kTransportUsb,
- kTransportLocal,
- kTransportAny,
- kTransportHost,
-} transport_type;
-
-struct atransport
-{
- atransport *next;
- atransport *prev;
-
- int (*read_from_remote)(apacket *p, atransport *t);
- int (*write_to_remote)(apacket *p, atransport *t);
- void (*close)(atransport *t);
- void (*kick)(atransport *t);
-
- int fd;
- int transport_socket;
- fdevent transport_fde;
- int ref_count;
- unsigned sync_token;
- int connection_state;
- transport_type type;
-
- /* usb handle or socket fd as needed */
- usb_handle *usb;
- int sfd;
-
- /* used to identify transports for clients */
- char *serial;
- char *product;
- int adb_port; // Use for emulators (local transport)
-
- /* a list of adisconnect callbacks called when the transport is kicked */
- int kicked;
- adisconnect disconnects;
-};
-
-
-void print_packet(const char *label, apacket *p);
-
-asocket *find_local_socket(unsigned id);
-void install_local_socket(asocket *s);
-void remove_socket(asocket *s);
-void close_all_sockets(atransport *t);
-
-#define LOCAL_CLIENT_PREFIX "emulator-"
-
-asocket *create_local_socket(int fd);
-asocket *create_local_service_socket(const char *destination);
-
-asocket *create_remote_socket(unsigned id, atransport *t);
-void connect_to_remote(asocket *s, const char *destination);
-void connect_to_smartsocket(asocket *s);
-
-void fatal(const char *fmt, ...);
-void fatal_errno(const char *fmt, ...);
-
-void handle_packet(apacket *p, atransport *t);
-void send_packet(apacket *p, atransport *t);
-
-void get_my_path(char *s, size_t maxLen);
-int launch_server(int server_port);
-int adb_main();
-
-
-/* transports are ref-counted
-** get_device_transport does an acquire on your behalf before returning
-*/
-void init_transport_registration(void);
-int list_transports(char *buf, size_t bufsize);
-void update_transports(void);
-
-asocket* create_device_tracker(void);
-
-/* Obtain a transport from the available transports.
-** If state is != CS_ANY, only transports in that state are considered.
-** If serial is non-NULL then only the device with that serial will be chosen.
-** If no suitable transport is found, error is set.
-*/
-atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out);
-void add_transport_disconnect( atransport* t, adisconnect* dis );
-void remove_transport_disconnect( atransport* t, adisconnect* dis );
-void run_transport_disconnects( atransport* t );
-void kick_transport( atransport* t );
-
-/* initialize a transport object's func pointers and state */
-#if ADB_HOST
-int get_available_local_transport_index();
-#endif
-void init_usb_transport(atransport *t, usb_handle *usb, int state);
-
-/* for MacOS X cleanup */
-void close_usb_devices();
-
-/* these should only be used for the "adb disconnect" command */
-void unregister_transport(atransport *t);
-void unregister_all_tcp_transports();
-
-void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);
-
-/* this should only be used for transports with connection_state == CS_NOPERM */
-void unregister_usb_transport(usb_handle *usb);
-
-atransport *find_transport(const char *serial);
-#if ADB_HOST
-atransport* find_emulator_transport_by_adb_port(int adb_port);
-#endif
-
-int service_to_fd(const char *name);
-#if ADB_HOST
-asocket *host_service_to_socket(const char* name, const char *serial);
-#endif
-
-#if !ADB_HOST
-typedef enum {
- BACKUP,
- RESTORE
-} BackupOperation;
-int backup_service(BackupOperation operation, char* args);
-void framebuffer_service(int fd, void *cookie);
-void log_service(int fd, void *cookie);
-void remount_service(int fd, void *cookie);
-char * get_log_file_path(const char * log_name);
-#endif
-
-/* packet allocator */
-apacket *get_apacket(void);
-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,
-} AdbTrace;
-
-#if ADB_TRACE
-
- 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
-
-
-#if !TRACE_PACKETS
-#define print_packet(tag,p) do {} while (0)
-#endif
-
-#if ADB_HOST_ON_TARGET
-/* adb and adbd are coexisting on the target, so use 5038 for adb
- * to avoid conflicting with adbd's usage of 5037
- */
-# define DEFAULT_ADB_PORT 5038
-#else
-# define DEFAULT_ADB_PORT 5037
-#endif
-
-#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555
-
-#define ADB_CLASS 0xff
-#define ADB_SUBCLASS 0x42
-#define ADB_PROTOCOL 0x1
-
-
-void local_init(int port);
-int local_connect(int port);
-int local_connect_arbitrary_ports(int console_port, int adb_port);
-
-/* usb host/client interface */
-void usb_init();
-void usb_cleanup();
-int usb_write(usb_handle *h, const void *data, int len);
-int usb_read(usb_handle *h, void *data, int len);
-int usb_close(usb_handle *h);
-void usb_kick(usb_handle *h);
-
-/* used for USB device detection */
-#if ADB_HOST
-int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
-#endif
-
-unsigned host_to_le32(unsigned n);
-int adb_commandline(int argc, char **argv);
-
-int connection_state(atransport *t);
-
-#define CS_ANY -1
-#define CS_OFFLINE 0
-#define CS_BOOTLOADER 1
-#define CS_DEVICE 2
-#define CS_HOST 3
-#define CS_RECOVERY 4
-#define CS_NOPERM 5 /* Insufficient permissions to communicate with the device */
-#define CS_SIDELOAD 6
-#define CS_UNAUTHORIZED 7
-
-extern int HOST;
-extern int SHELL_EXIT_NOTIFY_FD;
-
-#define CHUNK_SIZE (64*1024)
-
-#if !ADB_HOST
-#define USB_ADB_PATH "/dev/android_adb"
-
-#define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/"
-#define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH#x
-
-#define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0)
-#define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1)
-#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);
-
-#endif
diff --git a/minadbd/transport.h b/minadbd/adb_main.c
index 992e05285..f6e240108 100644
--- a/minadbd/transport.h
+++ b/minadbd/adb_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 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.
@@ -14,13 +14,32 @@
* limitations under the License.
*/
-#ifndef __TRANSPORT_H
-#define __TRANSPORT_H
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
-/* convenience wrappers around read/write that will retry on
-** EINTR and/or short read/write. Returns 0 on success, -1
-** on error or EOF.
-*/
-int readx(int fd, void *ptr, size_t len);
-int writex(int fd, const void *ptr, size_t len);
-#endif /* __TRANSPORT_H */
+#define TRACE_TAG TRACE_ADB
+
+#include "sysdeps.h"
+
+#include "adb.h"
+#include "transport.h"
+
+int adb_main(int is_daemon, int server_port)
+{
+ atexit(usb_cleanup);
+
+ adb_device_banner = "sideload";
+
+ // No SIGCHLD. Let the service subproc handle its children.
+ signal(SIGPIPE, SIG_IGN);
+
+ init_transport_registration();
+ usb_init();
+
+ D("Event loop starting\n");
+ fdevent_loop();
+
+ return 0;
+}
diff --git a/minadbd/fdevent.c b/minadbd/fdevent.c
deleted file mode 100644
index 5c374a71b..000000000
--- a/minadbd/fdevent.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c
-**
-** Copyright 2006, Brian Swetland <swetland@frotz.net>
-**
-** 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 <sys/ioctl.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <fcntl.h>
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#include "fdevent.h"
-#include "transport.h"
-#include "sysdeps.h"
-
-
-/* !!! Do not enable DEBUG for the adb that will run as the server:
-** both stdout and stderr are used to communicate between the client
-** and server. Any extra output will cause failures.
-*/
-#define DEBUG 0 /* non-0 will break adb server */
-
-// This socket is used when a subproc shell service exists.
-// It wakes up the fdevent_loop() and cause the correct handling
-// of the shell's pseudo-tty master. I.e. force close it.
-int SHELL_EXIT_NOTIFY_FD = -1;
-
-static void fatal(const char *fn, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "%s:", fn);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- abort();
-}
-
-#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);
- fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
- fde->state & FDE_READ ? 'R' : ' ',
- fde->state & FDE_WRITE ? 'W' : ' ',
- fde->state & FDE_ERROR ? 'E' : ' ',
- info);
- adb_mutex_unlock(&D_lock);
-}
-#else
-#define D(...) ((void)0)
-#define dump_fde(fde, info) do { } while(0)
-#endif
-
-#define FDE_EVENTMASK 0x00ff
-#define FDE_STATEMASK 0xff00
-
-#define FDE_ACTIVE 0x0100
-#define FDE_PENDING 0x0200
-#define FDE_CREATED 0x0400
-
-static void fdevent_plist_enqueue(fdevent *node);
-static void fdevent_plist_remove(fdevent *node);
-static fdevent *fdevent_plist_dequeue(void);
-static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata);
-
-static fdevent list_pending = {
- .next = &list_pending,
- .prev = &list_pending,
-};
-
-static fdevent **fd_table = 0;
-static int fd_table_max = 0;
-
-#ifdef CRAPTASTIC
-//HAVE_EPOLL
-
-#include <sys/epoll.h>
-
-static int epoll_fd = -1;
-
-static void fdevent_init()
-{
- /* XXX: what's a good size for the passed in hint? */
- epoll_fd = epoll_create(256);
-
- if(epoll_fd < 0) {
- perror("epoll_create() failed");
- exit(1);
- }
-
- /* mark for close-on-exec */
- fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
- struct epoll_event ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
-#if 0
- if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
-#endif
-}
-
-static void fdevent_disconnect(fdevent *fde)
-{
- struct epoll_event ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
- /* technically we only need to delete if we
- ** were actively monitoring events, but let's
- ** be aggressive and do it anyway, just in case
- ** something's out of sync
- */
- epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev);
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
- struct epoll_event ev;
- int active;
-
- active = (fde->state & FDE_EVENTMASK) != 0;
-
- memset(&ev, 0, sizeof(ev));
- ev.events = 0;
- ev.data.ptr = fde;
-
- if(events & FDE_READ) ev.events |= EPOLLIN;
- if(events & FDE_WRITE) ev.events |= EPOLLOUT;
- if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-
- if(active) {
- /* we're already active. if we're changing to *no*
- ** events being monitored, we need to delete, otherwise
- ** we need to just modify
- */
- if(ev.events) {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- } else {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- }
- } else {
- /* we're not active. if we're watching events, we need
- ** to add, otherwise we can just do nothing
- */
- if(ev.events) {
- if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
- perror("epoll_ctl() failed\n");
- exit(1);
- }
- }
- }
-}
-
-static void fdevent_process()
-{
- struct epoll_event events[256];
- fdevent *fde;
- int i, n;
-
- n = epoll_wait(epoll_fd, events, 256, -1);
-
- if(n < 0) {
- if(errno == EINTR) return;
- perror("epoll_wait");
- exit(1);
- }
-
- for(i = 0; i < n; i++) {
- struct epoll_event *ev = events + i;
- fde = ev->data.ptr;
-
- if(ev->events & EPOLLIN) {
- fde->events |= FDE_READ;
- }
- if(ev->events & EPOLLOUT) {
- fde->events |= FDE_WRITE;
- }
- if(ev->events & (EPOLLERR | EPOLLHUP)) {
- fde->events |= FDE_ERROR;
- }
- if(fde->events) {
- if(fde->state & FDE_PENDING) continue;
- fde->state |= FDE_PENDING;
- fdevent_plist_enqueue(fde);
- }
- }
-}
-
-#else /* USE_SELECT */
-
-#ifdef HAVE_WINSOCK
-#include <winsock2.h>
-#else
-#include <sys/select.h>
-#endif
-
-static fd_set read_fds;
-static fd_set write_fds;
-static fd_set error_fds;
-
-static int select_n = 0;
-
-static void fdevent_init(void)
-{
- FD_ZERO(&read_fds);
- FD_ZERO(&write_fds);
- FD_ZERO(&error_fds);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
- if(fde->fd >= select_n) {
- select_n = fde->fd + 1;
- }
-}
-
-static void fdevent_disconnect(fdevent *fde)
-{
- int i, n;
-
- FD_CLR(fde->fd, &read_fds);
- FD_CLR(fde->fd, &write_fds);
- FD_CLR(fde->fd, &error_fds);
-
- for(n = 0, i = 0; i < select_n; i++) {
- if(fd_table[i] != 0) n = i;
- }
- select_n = n + 1;
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
- if(events & FDE_READ) {
- FD_SET(fde->fd, &read_fds);
- } else {
- FD_CLR(fde->fd, &read_fds);
- }
- if(events & FDE_WRITE) {
- FD_SET(fde->fd, &write_fds);
- } else {
- FD_CLR(fde->fd, &write_fds);
- }
- if(events & FDE_ERROR) {
- FD_SET(fde->fd, &error_fds);
- } else {
- FD_CLR(fde->fd, &error_fds);
- }
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-}
-
-/* Looks at fd_table[] for bad FDs and sets bit in fds.
-** Returns the number of bad FDs.
-*/
-static int fdevent_fd_check(fd_set *fds)
-{
- int i, n = 0;
- fdevent *fde;
-
- for(i = 0; i < select_n; i++) {
- fde = fd_table[i];
- if(fde == 0) continue;
- if(fcntl(i, F_GETFL, NULL) < 0) {
- FD_SET(i, fds);
- n++;
- // fde->state |= FDE_DONT_CLOSE;
-
- }
- }
- return n;
-}
-
-#if !DEBUG
-static inline void dump_all_fds(const char *extra_msg) {}
-#else
-static void dump_all_fds(const char *extra_msg)
-{
-int i;
- fdevent *fde;
- // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank
- char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff;
- size_t max_chars = FD_SETSIZE * 6 + 1;
- int printed_out;
-#define SAFE_SPRINTF(...) \
- do { \
- printed_out = snprintf(pb, max_chars, __VA_ARGS__); \
- if (printed_out <= 0) { \
- D("... snprintf failed.\n"); \
- return; \
- } \
- if (max_chars < (unsigned int)printed_out) { \
- D("... snprintf out of space.\n"); \
- return; \
- } \
- pb += printed_out; \
- max_chars -= printed_out; \
- } while(0)
-
- for(i = 0; i < select_n; i++) {
- fde = fd_table[i];
- SAFE_SPRINTF("%d", i);
- if(fde == 0) {
- SAFE_SPRINTF("? ");
- continue;
- }
- if(fcntl(i, F_GETFL, NULL) < 0) {
- SAFE_SPRINTF("b");
- }
- SAFE_SPRINTF(" ");
- }
- D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff);
-}
-#endif
-
-static void fdevent_process()
-{
- int i, n;
- fdevent *fde;
- unsigned events;
- fd_set rfd, wfd, efd;
-
- memcpy(&rfd, &read_fds, sizeof(fd_set));
- memcpy(&wfd, &write_fds, sizeof(fd_set));
- memcpy(&efd, &error_fds, sizeof(fd_set));
-
- dump_all_fds("pre select()");
-
- n = select(select_n, &rfd, &wfd, &efd, NULL);
- int saved_errno = errno;
- D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
-
- dump_all_fds("post select()");
-
- if(n < 0) {
- switch(saved_errno) {
- case EINTR: return;
- case EBADF:
- // Can't trust the FD sets after an error.
- FD_ZERO(&wfd);
- FD_ZERO(&efd);
- FD_ZERO(&rfd);
- break;
- default:
- D("Unexpected select() error=%d\n", saved_errno);
- return;
- }
- }
- if(n <= 0) {
- // We fake a read, as the rest of the code assumes
- // that errors will be detected at that point.
- n = fdevent_fd_check(&rfd);
- }
-
- for(i = 0; (i < select_n) && (n > 0); i++) {
- events = 0;
- if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; }
- if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; }
- if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; }
-
- if(events) {
- fde = fd_table[i];
- if(fde == 0)
- FATAL("missing fde for fd %d\n", i);
-
- fde->events |= events;
-
- D("got events fde->fd=%d events=%04x, state=%04x\n",
- fde->fd, fde->events, fde->state);
- if(fde->state & FDE_PENDING) continue;
- fde->state |= FDE_PENDING;
- fdevent_plist_enqueue(fde);
- }
- }
-}
-
-#endif
-
-static void fdevent_register(fdevent *fde)
-{
- if(fde->fd < 0) {
- FATAL("bogus negative fd (%d)\n", fde->fd);
- }
-
- if(fde->fd >= fd_table_max) {
- int oldmax = fd_table_max;
- if(fde->fd > 32000) {
- FATAL("bogus huuuuge fd (%d)\n", fde->fd);
- }
- if(fd_table_max == 0) {
- fdevent_init();
- fd_table_max = 256;
- }
- while(fd_table_max <= fde->fd) {
- fd_table_max *= 2;
- }
- fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
- if(fd_table == 0) {
- FATAL("could not expand fd_table to %d entries\n", fd_table_max);
- }
- memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
- }
-
- fd_table[fde->fd] = fde;
-}
-
-static void fdevent_unregister(fdevent *fde)
-{
- if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
- FATAL("fd out of range (%d)\n", fde->fd);
- }
-
- if(fd_table[fde->fd] != fde) {
- FATAL("fd_table out of sync [%d]\n", fde->fd);
- }
-
- fd_table[fde->fd] = 0;
-
- if(!(fde->state & FDE_DONT_CLOSE)) {
- dump_fde(fde, "close");
- adb_close(fde->fd);
- }
-}
-
-static void fdevent_plist_enqueue(fdevent *node)
-{
- fdevent *list = &list_pending;
-
- node->next = list;
- node->prev = list->prev;
- node->prev->next = node;
- list->prev = node;
-}
-
-static void fdevent_plist_remove(fdevent *node)
-{
- node->prev->next = node->next;
- node->next->prev = node->prev;
- node->next = 0;
- node->prev = 0;
-}
-
-static fdevent *fdevent_plist_dequeue(void)
-{
- fdevent *list = &list_pending;
- fdevent *node = list->next;
-
- if(node == list) return 0;
-
- list->next = node->next;
- list->next->prev = list;
- node->next = 0;
- node->prev = 0;
-
- return node;
-}
-
-static void fdevent_call_fdfunc(fdevent* fde)
-{
- unsigned events = fde->events;
- fde->events = 0;
- if(!(fde->state & FDE_PENDING)) return;
- fde->state &= (~FDE_PENDING);
- dump_fde(fde, "callback");
- fde->func(fde->fd, events, fde->arg);
-}
-
-static void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata)
-{
-
- D("subproc handling on fd=%d ev=%04x\n", fd, ev);
-
- // Hook oneself back into the fde's suitable for select() on read.
- if((fd < 0) || (fd >= fd_table_max)) {
- FATAL("fd %d out of range for fd_table \n", fd);
- }
- fdevent *fde = fd_table[fd];
- fdevent_add(fde, FDE_READ);
-
- if(ev & FDE_READ){
- int subproc_fd;
-
- if(readx(fd, &subproc_fd, sizeof(subproc_fd))) {
- FATAL("Failed to read the subproc's fd from fd=%d\n", fd);
- }
- if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
- D("subproc_fd %d out of range 0, fd_table_max=%d\n",
- subproc_fd, fd_table_max);
- return;
- }
- fdevent *subproc_fde = fd_table[subproc_fd];
- if(!subproc_fde) {
- D("subproc_fd %d cleared from fd_table\n", subproc_fd);
- return;
- }
- if(subproc_fde->fd != subproc_fd) {
- // Already reallocated?
- D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
- return;
- }
-
- subproc_fde->force_eof = 1;
-
- int rcount = 0;
- ioctl(subproc_fd, FIONREAD, &rcount);
- D("subproc with fd=%d has rcount=%d err=%d\n",
- subproc_fd, rcount, errno);
-
- if(rcount) {
- // If there is data left, it will show up in the select().
- // This works because there is no other thread reading that
- // data when in this fd_func().
- return;
- }
-
- D("subproc_fde.state=%04x\n", subproc_fde->state);
- subproc_fde->events |= FDE_READ;
- if(subproc_fde->state & FDE_PENDING) {
- return;
- }
- subproc_fde->state |= FDE_PENDING;
- fdevent_call_fdfunc(subproc_fde);
- }
-}
-
-fdevent *fdevent_create(int fd, fd_func func, void *arg)
-{
- fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
- if(fde == 0) return 0;
- fdevent_install(fde, fd, func, arg);
- fde->state |= FDE_CREATED;
- return fde;
-}
-
-void fdevent_destroy(fdevent *fde)
-{
- if(fde == 0) return;
- if(!(fde->state & FDE_CREATED)) {
- FATAL("fde %p not created by fdevent_create()\n", fde);
- }
- fdevent_remove(fde);
-}
-
-void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
-{
- memset(fde, 0, sizeof(fdevent));
- fde->state = FDE_ACTIVE;
- fde->fd = fd;
- fde->force_eof = 0;
- fde->func = func;
- fde->arg = arg;
-
-#ifndef HAVE_WINSOCK
- fcntl(fd, F_SETFL, O_NONBLOCK);
-#endif
- fdevent_register(fde);
- dump_fde(fde, "connect");
- fdevent_connect(fde);
- fde->state |= FDE_ACTIVE;
-}
-
-void fdevent_remove(fdevent *fde)
-{
- if(fde->state & FDE_PENDING) {
- fdevent_plist_remove(fde);
- }
-
- if(fde->state & FDE_ACTIVE) {
- fdevent_disconnect(fde);
- dump_fde(fde, "disconnect");
- fdevent_unregister(fde);
- }
-
- fde->state = 0;
- fde->events = 0;
-}
-
-
-void fdevent_set(fdevent *fde, unsigned events)
-{
- events &= FDE_EVENTMASK;
-
- if((fde->state & FDE_EVENTMASK) == events) return;
-
- if(fde->state & FDE_ACTIVE) {
- fdevent_update(fde, events);
- dump_fde(fde, "update");
- }
-
- fde->state = (fde->state & FDE_STATEMASK) | events;
-
- if(fde->state & FDE_PENDING) {
- /* if we're pending, make sure
- ** we don't signal an event that
- ** is no longer wanted.
- */
- fde->events &= (~events);
- if(fde->events == 0) {
- fdevent_plist_remove(fde);
- fde->state &= (~FDE_PENDING);
- }
- }
-}
-
-void fdevent_add(fdevent *fde, unsigned events)
-{
- fdevent_set(
- fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
-}
-
-void fdevent_del(fdevent *fde, unsigned events)
-{
- fdevent_set(
- fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
-}
-
-void fdevent_subproc_setup()
-{
- int s[2];
-
- if(adb_socketpair(s)) {
- FATAL("cannot create shell-exit socket-pair\n");
- }
- SHELL_EXIT_NOTIFY_FD = s[0];
- fdevent *fde;
- fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL);
- if(!fde)
- FATAL("cannot create fdevent for shell-exit handler\n");
- fdevent_add(fde, FDE_READ);
-}
-
-void fdevent_loop()
-{
- fdevent *fde;
- fdevent_subproc_setup();
-
- for(;;) {
- D("--- ---- waiting for events\n");
-
- fdevent_process();
-
- while((fde = fdevent_plist_dequeue())) {
- fdevent_call_fdfunc(fde);
- }
- }
-}
diff --git a/minadbd/fdevent.h b/minadbd/fdevent.h
deleted file mode 100644
index a0ebe2a7e..000000000
--- a/minadbd/fdevent.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2006 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 __FDEVENT_H
-#define __FDEVENT_H
-
-#include <stdint.h> /* for int64_t */
-
-/* events that may be observed */
-#define FDE_READ 0x0001
-#define FDE_WRITE 0x0002
-#define FDE_ERROR 0x0004
-#define FDE_TIMEOUT 0x0008
-
-/* features that may be set (via the events set/add/del interface) */
-#define FDE_DONT_CLOSE 0x0080
-
-typedef struct fdevent fdevent;
-
-typedef void (*fd_func)(int fd, unsigned events, void *userdata);
-
-/* Allocate and initialize a new fdevent object
- * Note: use FD_TIMER as 'fd' to create a fd-less object
- * (used to implement timers).
-*/
-fdevent *fdevent_create(int fd, fd_func func, void *arg);
-
-/* Uninitialize and deallocate an fdevent object that was
-** created by fdevent_create()
-*/
-void fdevent_destroy(fdevent *fde);
-
-/* Initialize an fdevent object that was externally allocated
-*/
-void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg);
-
-/* Uninitialize an fdevent object that was initialized by
-** fdevent_install()
-*/
-void fdevent_remove(fdevent *item);
-
-/* Change which events should cause notifications
-*/
-void fdevent_set(fdevent *fde, unsigned events);
-void fdevent_add(fdevent *fde, unsigned events);
-void fdevent_del(fdevent *fde, unsigned events);
-
-void fdevent_set_timeout(fdevent *fde, int64_t timeout_ms);
-
-/* loop forever, handling events.
-*/
-void fdevent_loop();
-
-struct fdevent
-{
- fdevent *next;
- fdevent *prev;
-
- int fd;
- int force_eof;
-
- unsigned short state;
- unsigned short events;
-
- fd_func func;
- void *arg;
-};
-
-
-#endif
diff --git a/minadbd/fuse_adb_provider.c b/minadbd/fuse_adb_provider.c
index f80533a8c..5da7fd76c 100644
--- a/minadbd/fuse_adb_provider.c
+++ b/minadbd/fuse_adb_provider.c
@@ -16,29 +16,28 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <errno.h>
+#include "sysdeps.h"
+
#include "adb.h"
+#include "adb_io.h"
+#include "fuse_adb_provider.h"
#include "fuse_sideload.h"
-struct adb_data {
- int sfd; // file descriptor for the adb channel
-
- uint64_t file_size;
- uint32_t block_size;
-};
-
-static int read_block_adb(void* cookie, uint32_t block, uint8_t* buffer, uint32_t fetch_size) {
+int read_block_adb(void* cookie, uint32_t block, uint8_t* buffer,
+ uint32_t fetch_size) {
struct adb_data* ad = (struct adb_data*)cookie;
char buf[10];
snprintf(buf, sizeof(buf), "%08u", block);
- if (writex(ad->sfd, buf, 8) < 0) {
+ if (!WriteStringFully(ad->sfd, buf)) {
fprintf(stderr, "failed to write to adb host: %s\n", strerror(errno));
return -EIO;
}
- if (readx(ad->sfd, buffer, fetch_size) < 0) {
+ if (!ReadFdExactly(ad->sfd, buffer, fetch_size)) {
fprintf(stderr, "failed to read from adb host: %s\n", strerror(errno));
return -EIO;
}
@@ -49,7 +48,7 @@ static int read_block_adb(void* cookie, uint32_t block, uint8_t* buffer, uint32_
static void close_adb(void* cookie) {
struct adb_data* ad = (struct adb_data*)cookie;
- writex(ad->sfd, "DONEDONE", 8);
+ WriteStringFully(ad->sfd, "DONEDONE");
}
int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size) {
diff --git a/minadbd/fuse_adb_provider.h b/minadbd/fuse_adb_provider.h
index 0eb1f79d1..b88ce497b 100644
--- a/minadbd/fuse_adb_provider.h
+++ b/minadbd/fuse_adb_provider.h
@@ -17,6 +17,25 @@
#ifndef __FUSE_ADB_PROVIDER_H
#define __FUSE_ADB_PROVIDER_H
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct adb_data {
+ int sfd; // file descriptor for the adb channel
+
+ uint64_t file_size;
+ uint32_t block_size;
+};
+
+int read_block_adb(void* cookie, uint32_t block, uint8_t* buffer,
+ uint32_t fetch_size);
int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/minadbd/fuse_adb_provider_test.cpp b/minadbd/fuse_adb_provider_test.cpp
new file mode 100644
index 000000000..ecd9f384b
--- /dev/null
+++ b/minadbd/fuse_adb_provider_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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 "fuse_adb_provider.h"
+
+#include <gtest/gtest.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+
+#include <string>
+
+#include "adb_io.h"
+#include "utils/file.h"
+
+TEST(fuse_adb_provider, read_block_adb) {
+ adb_data data = {};
+ int sockets[2];
+
+ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sockets));
+ data.sfd = sockets[0];
+
+ int host_socket = sockets[1];
+ fcntl(host_socket, F_SETFL, O_NONBLOCK);
+
+ const char expected_data[] = "foobar";
+ char block_data[sizeof(expected_data)] = {};
+
+ // If we write the result of read_block_adb's request before the request is
+ // actually made we can avoid needing an extra thread for this test.
+ ASSERT_TRUE(WriteFdExactly(host_socket, expected_data,
+ strlen(expected_data)));
+
+ uint32_t block = 1234U;
+ const char expected_block[] = "00001234";
+ ASSERT_EQ(0, read_block_adb(reinterpret_cast<void*>(&data), block,
+ reinterpret_cast<uint8_t*>(block_data),
+ sizeof(expected_data) - 1));
+
+ // Check that read_block_adb requested the right block.
+ char block_req[sizeof(expected_block)] = {};
+ ASSERT_TRUE(ReadFdExactly(host_socket, block_req, 8));
+ ASSERT_EQ(0, block_req[8]);
+ ASSERT_EQ(8U, strlen(block_req));
+ ASSERT_STREQ(expected_block, block_req);
+
+ // Check that read_block_adb returned the right data.
+ ASSERT_EQ(0, block_req[8]);
+ ASSERT_STREQ(expected_data, block_data);
+
+ // Check that nothing else was written to the socket.
+ char tmp;
+ errno = 0;
+ ASSERT_EQ(-1, read(host_socket, &tmp, 1));
+ ASSERT_EQ(EWOULDBLOCK, errno);
+
+ close(sockets[0]);
+ close(sockets[1]);
+}
+
+TEST(fuse_adb_provider, read_block_adb_fail_write) {
+ adb_data data = {};
+ int sockets[2];
+
+ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sockets));
+ data.sfd = sockets[0];
+
+ ASSERT_EQ(0, close(sockets[1]));
+
+ char buf[1];
+ ASSERT_EQ(-EIO, read_block_adb(reinterpret_cast<void*>(&data), 0,
+ reinterpret_cast<uint8_t*>(buf), 1));
+
+ close(sockets[0]);
+}
diff --git a/minadbd/mutex_list.h b/minadbd/mutex_list.h
deleted file mode 100644
index 652dd7341..000000000
--- a/minadbd/mutex_list.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* the list of mutexes used by adb */
-/* #ifndef __MUTEX_LIST_H
- * Do not use an include-guard. This file is included once to declare the locks
- * and once in win32 to actually do the runtime initialization.
- */
-#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
-ADB_MUTEX(local_transports_lock)
-#endif
-ADB_MUTEX(usb_lock)
-
-// Sadly logging to /data/adb/adb-... is not thread safe.
-// After modifying adb.h::D() to count invocations:
-// DEBUG(jpa):0:Handling main()
-// DEBUG(jpa):1:[ usb_init - starting thread ]
-// (Oopsies, no :2:, and matching message is also gone.)
-// DEBUG(jpa):3:[ usb_thread - opening device ]
-// DEBUG(jpa):4:jdwp control socket started (10)
-ADB_MUTEX(D_lock)
-
-#undef ADB_MUTEX
diff --git a/minadbd/services.c b/minadbd/services.c
index 218b84a38..581d847fc 100644
--- a/minadbd/services.c
+++ b/minadbd/services.c
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-#include <stdlib.h>
+#include <errno.h>
+#include <inttypes.h>
#include <stdio.h>
-#include <unistd.h>
+#include <stdlib.h>
#include <string.h>
-#include <errno.h>
+#include <unistd.h>
#include "sysdeps.h"
-#include "fdevent.h"
-#include "fuse_adb_provider.h"
#define TRACE_TAG TRACE_SERVICES
#include "adb.h"
+#include "fdevent.h"
+#include "fuse_adb_provider.h"
typedef struct stinfo stinfo;
@@ -47,12 +48,13 @@ void *service_bootstrap_func(void *x)
static void sideload_host_service(int sfd, void* cookie)
{
char* saveptr;
- const char* s = strtok_r(cookie, ":", &saveptr);
+ const char* s = adb_strtok_r(cookie, ":", &saveptr);
uint64_t file_size = strtoull(s, NULL, 10);
- s = strtok_r(NULL, ":", &saveptr);
+ s = adb_strtok_r(NULL, ":", &saveptr);
uint32_t block_size = strtoul(s, NULL, 10);
- printf("sideload-host file size %llu block size %lu\n", file_size, block_size);
+ printf("sideload-host file size %" PRIu64 " block size %" PRIu32 "\n",
+ file_size, block_size);
int result = run_adb_fuse(sfd, file_size, block_size);
@@ -61,40 +63,6 @@ static void sideload_host_service(int sfd, void* cookie)
exit(result == 0 ? 0 : 1);
}
-#if 0
-static void echo_service(int fd, void *cookie)
-{
- char buf[4096];
- int r;
- char *p;
- int c;
-
- for(;;) {
- r = 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;
@@ -135,10 +103,6 @@ int service_to_fd(const char *name)
exit(3);
} else if (!strncmp(name, "sideload-host:", 14)) {
ret = create_service_thread(sideload_host_service, (void*)(name + 14));
-#if 0
- } else if(!strncmp(name, "echo:", 5)){
- ret = create_service_thread(echo_service, 0);
-#endif
}
if (ret >= 0) {
close_on_exec(ret);
diff --git a/minadbd/sockets.c b/minadbd/sockets.c
deleted file mode 100644
index 817410d13..000000000
--- a/minadbd/sockets.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "sysdeps.h"
-
-#define TRACE_TAG TRACE_SOCKETS
-#include "adb.h"
-
-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(writex(fd, buf, 8)) return -1;
- return writex(fd, reason, len);
-}
-
-//extern int online;
-
-static unsigned local_socket_next_id = 1;
-
-static asocket local_socket_list = {
- .next = &local_socket_list,
- .prev = &local_socket_list,
-};
-
-/* the the list of currently closing local sockets.
-** these have no peer anymore, but still packets to
-** write to their fd.
-*/
-static asocket local_socket_closing_list = {
- .next = &local_socket_closing_list,
- .prev = &local_socket_closing_list,
-};
-
-asocket *find_local_socket(unsigned id)
-{
- asocket *s;
- asocket *result = NULL;
-
- adb_mutex_lock(&socket_list_lock);
- for (s = local_socket_list.next; s != &local_socket_list; s = s->next) {
- if (s->id == id) {
- result = s;
- break;
- }
- }
- adb_mutex_unlock(&socket_list_lock);
-
- return result;
-}
-
-static void
-insert_local_socket(asocket* s, asocket* list)
-{
- s->next = list;
- s->prev = s->next->prev;
- s->prev->next = s;
- s->next->prev = s;
-}
-
-
-void install_local_socket(asocket *s)
-{
- adb_mutex_lock(&socket_list_lock);
-
- s->id = local_socket_next_id++;
- insert_local_socket(s, &local_socket_list);
-
- adb_mutex_unlock(&socket_list_lock);
-}
-
-void remove_socket(asocket *s)
-{
- // socket_list_lock should already be held
- if (s->prev && s->next)
- {
- s->prev->next = s->next;
- s->next->prev = s->prev;
- s->next = 0;
- s->prev = 0;
- s->id = 0;
- }
-}
-
-void close_all_sockets(atransport *t)
-{
- asocket *s;
-
- /* this is a little gross, but since s->close() *will* modify
- ** the list out from under you, your options are limited.
- */
- adb_mutex_lock(&socket_list_lock);
-restart:
- for(s = local_socket_list.next; s != &local_socket_list; s = s->next){
- if(s->transport == t || (s->peer && s->peer->transport == t)) {
- local_socket_close_locked(s);
- goto restart;
- }
- }
- adb_mutex_unlock(&socket_list_lock);
-}
-
-static int local_socket_enqueue(asocket *s, apacket *p)
-{
- D("LS(%d): enqueue %d\n", s->id, p->len);
-
- p->ptr = p->data;
-
- /* if there is already data queue'd, we will receive
- ** events when it's time to write. just add this to
- ** the tail
- */
- if(s->pkt_first) {
- goto enqueue;
- }
-
- /* write as much as we can, until we
- ** would block or there is an error/eof
- */
- while(p->len > 0) {
- int r = adb_write(s->fd, p->ptr, p->len);
- if(r > 0) {
- p->len -= r;
- p->ptr += r;
- continue;
- }
- if((r == 0) || (errno != EAGAIN)) {
- D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) );
- s->close(s);
- return 1; /* not ready (error) */
- } else {
- break;
- }
- }
-
- if(p->len == 0) {
- put_apacket(p);
- return 0; /* ready for more data */
- }
-
-enqueue:
- p->next = 0;
- if(s->pkt_first) {
- s->pkt_last->next = p;
- } else {
- s->pkt_first = p;
- }
- s->pkt_last = p;
-
- /* make sure we are notified when we can drain the queue */
- fdevent_add(&s->fde, FDE_WRITE);
-
- return 1; /* not ready (backlog) */
-}
-
-static void local_socket_ready(asocket *s)
-{
- /* far side is ready for data, pay attention to
- readable events */
- fdevent_add(&s->fde, FDE_READ);
-// D("LS(%d): ready()\n", s->id);
-}
-
-static void local_socket_close(asocket *s)
-{
- adb_mutex_lock(&socket_list_lock);
- local_socket_close_locked(s);
- adb_mutex_unlock(&socket_list_lock);
-}
-
-// be sure to hold the socket list lock when calling this
-static void local_socket_destroy(asocket *s)
-{
- apacket *p, *n;
- D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
-
- /* IMPORTANT: the remove closes the fd
- ** that belongs to this socket
- */
- fdevent_remove(&s->fde);
-
- /* dispose of any unwritten data */
- for(p = s->pkt_first; p; p = n) {
- D("LS(%d): discarding %d bytes\n", s->id, p->len);
- n = p->next;
- put_apacket(p);
- }
- remove_socket(s);
- free(s);
-}
-
-
-static void local_socket_close_locked(asocket *s)
-{
- D("entered. LS(%d) fd=%d\n", s->id, s->fd);
- if(s->peer) {
- D("LS(%d): closing peer. peer->id=%d peer->fd=%d\n",
- s->id, s->peer->id, s->peer->fd);
- s->peer->peer = 0;
- // tweak to avoid deadlock
- if (s->peer->close == local_socket_close) {
- local_socket_close_locked(s->peer);
- } else {
- s->peer->close(s->peer);
- }
- s->peer = 0;
- }
-
- /* If we are already closing, or if there are no
- ** pending packets, destroy immediately
- */
- if (s->closing || s->pkt_first == NULL) {
- int id = s->id;
- local_socket_destroy(s);
- D("LS(%d): closed\n", id);
- return;
- }
-
- /* otherwise, put on the closing list
- */
- D("LS(%d): closing\n", s->id);
- s->closing = 1;
- fdevent_del(&s->fde, FDE_READ);
- remove_socket(s);
- D("LS(%d): put on socket_closing_list fd=%d\n", s->id, s->fd);
- insert_local_socket(s, &local_socket_closing_list);
-}
-
-static void local_socket_event_func(int fd, unsigned ev, void *_s)
-{
- asocket *s = _s;
-
- D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev);
-
- /* put the FDE_WRITE processing before the FDE_READ
- ** in order to simplify the code.
- */
- if(ev & FDE_WRITE){
- apacket *p;
-
- while((p = s->pkt_first) != 0) {
- while(p->len > 0) {
- int r = adb_write(fd, p->ptr, p->len);
- if(r > 0) {
- p->ptr += r;
- p->len -= r;
- continue;
- }
- if(r < 0) {
- /* returning here is ok because FDE_READ will
- ** be processed in the next iteration loop
- */
- if(errno == EAGAIN) return;
- if(errno == EINTR) continue;
- }
- D(" closing after write because r=%d and errno is %d\n", r, errno);
- s->close(s);
- return;
- }
-
- if(p->len == 0) {
- s->pkt_first = p->next;
- if(s->pkt_first == 0) s->pkt_last = 0;
- put_apacket(p);
- }
- }
-
- /* if we sent the last packet of a closing socket,
- ** we can now destroy it.
- */
- if (s->closing) {
- D(" closing because 'closing' is set after write\n");
- s->close(s);
- return;
- }
-
- /* no more packets queued, so we can ignore
- ** writable events again and tell our peer
- ** to resume writing
- */
- fdevent_del(&s->fde, FDE_WRITE);
- s->peer->ready(s->peer);
- }
-
-
- if(ev & FDE_READ){
- apacket *p = get_apacket();
- unsigned char *x = p->data;
- size_t avail = MAX_PAYLOAD;
- int r;
- int is_eof = 0;
-
- while(avail > 0) {
- r = adb_read(fd, x, avail);
- D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu\n",
- s->id, s->fd, r, r<0?errno:0, avail);
- if(r > 0) {
- avail -= r;
- x += r;
- continue;
- }
- if(r < 0) {
- if(errno == EAGAIN) break;
- if(errno == EINTR) continue;
- }
-
- /* r = 0 or unhandled error */
- is_eof = 1;
- break;
- }
- D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
- s->id, s->fd, r, is_eof, s->fde.force_eof);
- if((avail == MAX_PAYLOAD) || (s->peer == 0)) {
- put_apacket(p);
- } else {
- p->len = MAX_PAYLOAD - avail;
-
- r = s->peer->enqueue(s->peer, p);
- D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd, r);
-
- if(r < 0) {
- /* error return means they closed us as a side-effect
- ** and we must return immediately.
- **
- ** note that if we still have buffered packets, the
- ** socket will be placed on the closing socket list.
- ** this handler function will be called again
- ** to process FDE_WRITE events.
- */
- return;
- }
-
- if(r > 0) {
- /* if the remote cannot accept further events,
- ** we disable notification of READs. They'll
- ** be enabled again when we get a call to ready()
- */
- fdevent_del(&s->fde, FDE_READ);
- }
- }
- /* Don't allow a forced eof if data is still there */
- if((s->fde.force_eof && !r) || is_eof) {
- D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n", is_eof, r, s->fde.force_eof);
- s->close(s);
- }
- }
-
- if(ev & FDE_ERROR){
- /* this should be caught be the next read or write
- ** catching it here means we may skip the last few
- ** bytes of readable data.
- */
-// s->close(s);
- D("LS(%d): FDE_ERROR (fd=%d)\n", s->id, s->fd);
-
- return;
- }
-}
-
-asocket *create_local_socket(int fd)
-{
- asocket *s = calloc(1, sizeof(asocket));
- if (s == NULL) fatal("cannot allocate socket");
- s->fd = fd;
- s->enqueue = local_socket_enqueue;
- s->ready = local_socket_ready;
- s->close = local_socket_close;
- install_local_socket(s);
-
- fdevent_install(&s->fde, fd, local_socket_event_func, s);
-/* fdevent_add(&s->fde, FDE_ERROR); */
- //fprintf(stderr, "Created local socket in create_local_socket \n");
- D("LS(%d): created (fd=%d)\n", s->id, s->fd);
- return s;
-}
-
-asocket *create_local_service_socket(const char *name)
-{
- asocket *s;
- int fd;
-
- fd = service_to_fd(name);
- if(fd < 0) return 0;
-
- s = create_local_socket(fd);
- D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
- return s;
-}
-
-/* a Remote socket is used to send/receive data to/from a given transport object
-** it needs to be closed when the transport is forcibly destroyed by the user
-*/
-typedef struct aremotesocket {
- asocket socket;
- adisconnect disconnect;
-} aremotesocket;
-
-static int remote_socket_enqueue(asocket *s, apacket *p)
-{
- D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d\n",
- s->id, s->fd, s->peer->fd);
- p->msg.command = A_WRTE;
- p->msg.arg0 = s->peer->id;
- p->msg.arg1 = s->id;
- p->msg.data_length = p->len;
- send_packet(p, s->transport);
- return 1;
-}
-
-static void remote_socket_ready(asocket *s)
-{
- D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d\n",
- s->id, s->fd, s->peer->fd);
- apacket *p = get_apacket();
- p->msg.command = A_OKAY;
- p->msg.arg0 = s->peer->id;
- p->msg.arg1 = s->id;
- send_packet(p, s->transport);
-}
-
-static void remote_socket_close(asocket *s)
-{
- D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d\n",
- s->id, s->fd, s->peer?s->peer->fd:-1);
- apacket *p = get_apacket();
- p->msg.command = A_CLSE;
- if(s->peer) {
- p->msg.arg0 = s->peer->id;
- s->peer->peer = 0;
- D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d\n",
- s->id, s->peer->id, s->peer->fd);
- s->peer->close(s->peer);
- }
- p->msg.arg1 = s->id;
- send_packet(p, s->transport);
- D("RS(%d): closed\n", s->id);
- remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
- free(s);
-}
-
-static void remote_socket_disconnect(void* _s, atransport* t)
-{
- asocket* s = _s;
- asocket* peer = s->peer;
-
- D("remote_socket_disconnect RS(%d)\n", s->id);
- if (peer) {
- peer->peer = NULL;
- peer->close(peer);
- }
- remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
- free(s);
-}
-
-asocket *create_remote_socket(unsigned id, atransport *t)
-{
- asocket *s = calloc(1, sizeof(aremotesocket));
- adisconnect* dis = &((aremotesocket*)s)->disconnect;
-
- if (s == NULL) fatal("cannot allocate socket");
- s->id = id;
- s->enqueue = remote_socket_enqueue;
- s->ready = remote_socket_ready;
- s->close = remote_socket_close;
- s->transport = t;
-
- dis->func = remote_socket_disconnect;
- dis->opaque = s;
- add_transport_disconnect( t, dis );
- D("RS(%d): created\n", s->id);
- return s;
-}
-
-void connect_to_remote(asocket *s, const char *destination)
-{
- D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
- apacket *p = get_apacket();
- int len = strlen(destination) + 1;
-
- if(len > (MAX_PAYLOAD-1)) {
- fatal("destination oversized");
- }
-
- D("LS(%d): connect('%s')\n", s->id, destination);
- p->msg.command = A_OPEN;
- p->msg.arg0 = s->id;
- p->msg.data_length = len;
- strcpy((char*) p->data, destination);
- send_packet(p, s->transport);
-}
-
-
-/* this is used by magic sockets to rig local sockets to
- send the go-ahead message when they connect */
-static void local_socket_ready_notify(asocket *s)
-{
- s->ready = local_socket_ready;
- s->close = local_socket_close;
- adb_write(s->fd, "OKAY", 4);
- s->ready(s);
-}
-
-/* this is used by magic sockets to rig local sockets to
- send the failure message if they are closed before
- connected (to avoid closing them without a status message) */
-static void local_socket_close_notify(asocket *s)
-{
- s->ready = local_socket_ready;
- s->close = local_socket_close;
- sendfailmsg(s->fd, "closed");
- s->close(s);
-}
-
-unsigned unhex(unsigned char *s, int len)
-{
- unsigned n = 0, c;
-
- while(len-- > 0) {
- switch((c = *s++)) {
- case '0': case '1': case '2':
- case '3': case '4': case '5':
- case '6': case '7': case '8':
- case '9':
- c -= '0';
- break;
- case 'a': case 'b': case 'c':
- case 'd': case 'e': case 'f':
- c = c - 'a' + 10;
- break;
- case 'A': case 'B': case 'C':
- case 'D': case 'E': case 'F':
- c = c - 'A' + 10;
- break;
- default:
- return 0xffffffff;
- }
-
- n = (n << 4) | c;
- }
-
- return n;
-}
-
-/* skip_host_serial return the position in a string
- 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) {
- char *first_colon, *serial_end;
-
- first_colon = strchr(service, ':');
- if (!first_colon) {
- /* No colon in service string. */
- return NULL;
- }
- serial_end = first_colon;
- if (isdigit(serial_end[1])) {
- serial_end++;
- while ((*serial_end) && isdigit(*serial_end)) {
- serial_end++;
- }
- if ((*serial_end) != ':') {
- // Something other than numbers was found, reset the end.
- serial_end = first_colon;
- }
- }
- return serial_end;
-}
-
-static int smart_socket_enqueue(asocket *s, apacket *p)
-{
- unsigned len;
-
- D("SS(%d): enqueue %d\n", s->id, p->len);
-
- if(s->pkt_first == 0) {
- s->pkt_first = p;
- s->pkt_last = p;
- } else {
- if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
- D("SS(%d): overflow\n", s->id);
- put_apacket(p);
- goto fail;
- }
-
- memcpy(s->pkt_first->data + s->pkt_first->len,
- p->data, p->len);
- s->pkt_first->len += p->len;
- put_apacket(p);
-
- p = s->pkt_first;
- }
-
- /* don't bother if we can't decode the length */
- if(p->len < 4) return 0;
-
- len = unhex(p->data, 4);
- if((len < 1) || (len > 1024)) {
- D("SS(%d): bad size (%d)\n", s->id, len);
- goto fail;
- }
-
- D("SS(%d): len is %d\n", s->id, len );
- /* can't do anything until we have the full header */
- if((len + 4) > p->len) {
- D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len);
- return 0;
- }
-
- p->data[len + 4] = 0;
-
- D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
-
- if (s->transport == NULL) {
- char* error_string = "unknown failure";
- s->transport = acquire_one_transport (CS_ANY,
- kTransportAny, NULL, &error_string);
-
- if (s->transport == NULL) {
- sendfailmsg(s->peer->fd, error_string);
- goto fail;
- }
- }
-
- if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
- /* if there's no remote we fail the connection
- ** right here and terminate it
- */
- sendfailmsg(s->peer->fd, "device offline (x)");
- goto fail;
- }
-
-
- /* instrument our peer to pass the success or fail
- ** message back once it connects or closes, then
- ** detach from it, request the connection, and
- ** tear down
- */
- s->peer->ready = local_socket_ready_notify;
- s->peer->close = local_socket_close_notify;
- s->peer->peer = 0;
- /* give him our transport and upref it */
- s->peer->transport = s->transport;
-
- connect_to_remote(s->peer, (char*) (p->data + 4));
- s->peer = 0;
- s->close(s);
- return 1;
-
-fail:
- /* we're going to close our peer as a side-effect, so
- ** return -1 to signal that state to the local socket
- ** who is enqueueing against us
- */
- s->close(s);
- return -1;
-}
-
-static void smart_socket_ready(asocket *s)
-{
- D("SS(%d): ready\n", s->id);
-}
-
-static void smart_socket_close(asocket *s)
-{
- D("SS(%d): closed\n", s->id);
- if(s->pkt_first){
- put_apacket(s->pkt_first);
- }
- if(s->peer) {
- s->peer->peer = 0;
- s->peer->close(s->peer);
- s->peer = 0;
- }
- free(s);
-}
-
-asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act))
-{
- D("Creating smart socket \n");
- asocket *s = calloc(1, sizeof(asocket));
- if (s == NULL) fatal("cannot allocate socket");
- 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);
- 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);
- s->peer = ss;
- ss->peer = s;
- s->ready(s);
-}
diff --git a/minadbd/sysdeps.h b/minadbd/sysdeps.h
deleted file mode 100644
index 800ddb753..000000000
--- a/minadbd/sysdeps.h
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-/* this file contains system-dependent definitions used by ADB
- * they're related to threads, sockets and file descriptors
- */
-#ifndef _ADB_SYSDEPS_H
-#define _ADB_SYSDEPS_H
-
-#ifdef __CYGWIN__
-# undef _WIN32
-#endif
-
-#ifdef _WIN32
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <process.h>
-#include <fcntl.h>
-#include <io.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <ctype.h>
-
-#define OS_PATH_SEPARATOR '\\'
-#define OS_PATH_SEPARATOR_STR "\\"
-
-typedef CRITICAL_SECTION adb_mutex_t;
-
-#define ADB_MUTEX_DEFINE(x) adb_mutex_t x
-
-/* declare all mutexes */
-/* For win32, adb_sysdeps_init() will do the mutex runtime initialization. */
-#define ADB_MUTEX(x) extern adb_mutex_t x;
-#include "mutex_list.h"
-
-extern void adb_sysdeps_init(void);
-
-static __inline__ void adb_mutex_lock( adb_mutex_t* lock )
-{
- EnterCriticalSection( lock );
-}
-
-static __inline__ void adb_mutex_unlock( adb_mutex_t* lock )
-{
- LeaveCriticalSection( lock );
-}
-
-typedef struct { unsigned tid; } adb_thread_t;
-
-typedef void* (*adb_thread_func_t)(void* arg);
-
-typedef void (*win_thread_func_t)(void* arg);
-
-static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func_t func, void* arg)
-{
- thread->tid = _beginthread( (win_thread_func_t)func, 0, arg );
- if (thread->tid == (unsigned)-1L) {
- return -1;
- }
- return 0;
-}
-
-static __inline__ void close_on_exec(int fd)
-{
- /* nothing really */
-}
-
-extern void disable_tcp_nagle(int fd);
-
-#define lstat stat /* no symlinks on Win32 */
-
-#define S_ISLNK(m) 0 /* no symlinks on Win32 */
-
-static __inline__ int adb_unlink(const char* path)
-{
- int rc = unlink(path);
-
- if (rc == -1 && errno == EACCES) {
- /* unlink returns EACCES when the file is read-only, so we first */
- /* try to make it writable, then unlink again... */
- rc = chmod(path, _S_IREAD|_S_IWRITE );
- if (rc == 0)
- rc = unlink(path);
- }
- return rc;
-}
-#undef unlink
-#define unlink ___xxx_unlink
-
-static __inline__ int adb_mkdir(const char* path, int mode)
-{
- return _mkdir(path);
-}
-#undef mkdir
-#define mkdir ___xxx_mkdir
-
-extern int adb_open(const char* path, int options);
-extern int adb_creat(const char* path, int mode);
-extern int adb_read(int fd, void* buf, int len);
-extern int adb_write(int fd, const void* buf, int len);
-extern int adb_lseek(int fd, int pos, int where);
-extern int adb_shutdown(int fd);
-extern int adb_close(int fd);
-
-static __inline__ int unix_close(int fd)
-{
- return close(fd);
-}
-#undef close
-#define close ____xxx_close
-
-static __inline__ int unix_read(int fd, void* buf, size_t len)
-{
- return read(fd, buf, len);
-}
-#undef read
-#define read ___xxx_read
-
-static __inline__ int unix_write(int fd, const void* buf, size_t len)
-{
- return write(fd, buf, len);
-}
-#undef write
-#define write ___xxx_write
-
-static __inline__ int adb_open_mode(const char* path, int options, int mode)
-{
- return adb_open(path, options);
-}
-
-static __inline__ int unix_open(const char* path, int options,...)
-{
- if ((options & O_CREAT) == 0)
- {
- return open(path, options);
- }
- else
- {
- int mode;
- va_list args;
- va_start( args, options );
- mode = va_arg( args, int );
- va_end( args );
- return open(path, options, mode);
- }
-}
-#define open ___xxx_unix_open
-
-
-/* normally provided by <cutils/misc.h> */
-extern void* load_file(const char* pathname, unsigned* psize);
-
-/* normally provided by <cutils/sockets.h> */
-extern int socket_loopback_client(int port, int type);
-extern int socket_network_client(const char *host, int port, int type);
-extern int socket_loopback_server(int port, int type);
-extern int socket_inaddr_any_server(int port, int type);
-
-/* normally provided by "fdevent.h" */
-
-#define FDE_READ 0x0001
-#define FDE_WRITE 0x0002
-#define FDE_ERROR 0x0004
-#define FDE_DONT_CLOSE 0x0080
-
-typedef struct fdevent fdevent;
-
-typedef void (*fd_func)(int fd, unsigned events, void *userdata);
-
-fdevent *fdevent_create(int fd, fd_func func, void *arg);
-void fdevent_destroy(fdevent *fde);
-void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg);
-void fdevent_remove(fdevent *item);
-void fdevent_set(fdevent *fde, unsigned events);
-void fdevent_add(fdevent *fde, unsigned events);
-void fdevent_del(fdevent *fde, unsigned events);
-void fdevent_loop();
-
-struct fdevent {
- fdevent *next;
- fdevent *prev;
-
- int fd;
- int force_eof;
-
- unsigned short state;
- unsigned short events;
-
- fd_func func;
- void *arg;
-};
-
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- Sleep( mseconds );
-}
-
-extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen);
-
-#undef accept
-#define accept ___xxx_accept
-
-static __inline__ int adb_socket_setbufsize( int fd, int bufsize )
-{
- int opt = bufsize;
- return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(opt));
-}
-
-extern int adb_socketpair( int sv[2] );
-
-static __inline__ char* adb_dirstart( const char* path )
-{
- char* p = strchr(path, '/');
- char* p2 = strchr(path, '\\');
-
- if ( !p )
- p = p2;
- else if ( p2 && p2 > p )
- p = p2;
-
- return p;
-}
-
-static __inline__ char* adb_dirstop( const char* path )
-{
- char* p = strrchr(path, '/');
- char* p2 = strrchr(path, '\\');
-
- if ( !p )
- p = p2;
- else if ( p2 && p2 > p )
- p = p2;
-
- return p;
-}
-
-static __inline__ int adb_is_absolute_host_path( const char* path )
-{
- return isalpha(path[0]) && path[1] == ':' && path[2] == '\\';
-}
-
-#else /* !_WIN32 a.k.a. Unix */
-
-#include "fdevent.h"
-#include <cutils/sockets.h>
-#include <cutils/properties.h>
-#include <cutils/misc.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <pthread.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <string.h>
-
-#define OS_PATH_SEPARATOR '/'
-#define OS_PATH_SEPARATOR_STR "/"
-
-typedef pthread_mutex_t adb_mutex_t;
-
-#define ADB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#define adb_mutex_init pthread_mutex_init
-#define adb_mutex_lock pthread_mutex_lock
-#define adb_mutex_unlock pthread_mutex_unlock
-#define adb_mutex_destroy pthread_mutex_destroy
-
-#define ADB_MUTEX_DEFINE(m) adb_mutex_t m = PTHREAD_MUTEX_INITIALIZER
-
-#define adb_cond_t pthread_cond_t
-#define adb_cond_init pthread_cond_init
-#define adb_cond_wait pthread_cond_wait
-#define adb_cond_broadcast pthread_cond_broadcast
-#define adb_cond_signal pthread_cond_signal
-#define adb_cond_destroy pthread_cond_destroy
-
-/* declare all mutexes */
-#define ADB_MUTEX(x) extern adb_mutex_t x;
-#include "mutex_list.h"
-
-static __inline__ void close_on_exec(int fd)
-{
- fcntl( fd, F_SETFD, FD_CLOEXEC );
-}
-
-static __inline__ int unix_open(const char* path, int options,...)
-{
- if ((options & O_CREAT) == 0)
- {
- return open(path, options);
- }
- else
- {
- int mode;
- va_list args;
- va_start( args, options );
- mode = va_arg( args, int );
- va_end( args );
- return open(path, options, mode);
- }
-}
-
-static __inline__ int adb_open_mode( const char* pathname, int options, int mode )
-{
- return open( pathname, options, mode );
-}
-
-static __inline__ int adb_creat(const char* path, int mode)
-{
- int fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, mode);
-
- if ( fd < 0 )
- return -1;
-
- close_on_exec(fd);
- return fd;
-}
-#undef creat
-#define creat ___xxx_creat
-
-static __inline__ int adb_open( const char* pathname, int options )
-{
- int fd = open( pathname, options );
- if (fd < 0)
- return -1;
- close_on_exec( fd );
- return fd;
-}
-#undef open
-#define open ___xxx_open
-
-static __inline__ int adb_shutdown(int fd)
-{
- return shutdown(fd, SHUT_RDWR);
-}
-#undef shutdown
-#define shutdown ____xxx_shutdown
-
-static __inline__ int adb_close(int fd)
-{
- return close(fd);
-}
-#undef close
-#define close ____xxx_close
-
-
-static __inline__ int adb_read(int fd, void* buf, size_t len)
-{
- return read(fd, buf, len);
-}
-
-#undef read
-#define read ___xxx_read
-
-static __inline__ int adb_write(int fd, const void* buf, size_t len)
-{
- return write(fd, buf, len);
-}
-#undef write
-#define write ___xxx_write
-
-static __inline__ int adb_lseek(int fd, int pos, int where)
-{
- return lseek(fd, pos, where);
-}
-#undef lseek
-#define lseek ___xxx_lseek
-
-static __inline__ int adb_unlink(const char* path)
-{
- return unlink(path);
-}
-#undef unlink
-#define unlink ___xxx_unlink
-
-static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen)
-{
- int fd;
-
- fd = accept(serverfd, addr, addrlen);
- if (fd >= 0)
- close_on_exec(fd);
-
- return fd;
-}
-
-#undef accept
-#define accept ___xxx_accept
-
-#define unix_read adb_read
-#define unix_write adb_write
-#define unix_close adb_close
-
-typedef pthread_t adb_thread_t;
-
-typedef void* (*adb_thread_func_t)( void* arg );
-
-static __inline__ int adb_thread_create( adb_thread_t *pthread, adb_thread_func_t start, void* arg )
-{
- pthread_attr_t attr;
-
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-
- return pthread_create( pthread, &attr, start, arg );
-}
-
-static __inline__ int adb_socket_setbufsize( int fd, int bufsize )
-{
- int opt = bufsize;
- return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
-}
-
-static __inline__ void disable_tcp_nagle(int fd)
-{
- int on = 1;
- setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) );
-}
-
-
-static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] )
-{
- return socketpair( d, type, protocol, sv );
-}
-
-static __inline__ int adb_socketpair( int sv[2] )
-{
- int rc;
-
- rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
- if (rc < 0)
- return -1;
-
- close_on_exec( sv[0] );
- close_on_exec( sv[1] );
- return 0;
-}
-
-#undef socketpair
-#define socketpair ___xxx_socketpair
-
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- usleep( mseconds*1000 );
-}
-
-static __inline__ int adb_mkdir(const char* path, int mode)
-{
- return mkdir(path, mode);
-}
-#undef mkdir
-#define mkdir ___xxx_mkdir
-
-static __inline__ void adb_sysdeps_init(void)
-{
-}
-
-static __inline__ char* adb_dirstart(const char* path)
-{
- return strchr(path, '/');
-}
-
-static __inline__ char* adb_dirstop(const char* path)
-{
- return strrchr(path, '/');
-}
-
-static __inline__ int adb_is_absolute_host_path( const char* path )
-{
- return path[0] == '/';
-}
-
-#endif /* !_WIN32 */
-
-#endif /* _ADB_SYSDEPS_H */
diff --git a/minadbd/transport.c b/minadbd/transport.c
deleted file mode 100644
index 92679f518..000000000
--- a/minadbd/transport.c
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include "sysdeps.h"
-
-#define TRACE_TAG TRACE_TRANSPORT
-#include "adb.h"
-
-static void transport_unref(atransport *t);
-
-static atransport transport_list = {
- .next = &transport_list,
- .prev = &transport_list,
-};
-
-ADB_MUTEX_DEFINE( transport_lock );
-
-#if ADB_TRACE
-#define MAX_DUMP_HEX_LEN 16
-static 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)
- {
- int kicked;
-
- adb_mutex_lock(&transport_lock);
- kicked = t->kicked;
- if (!kicked)
- t->kicked = 1;
- adb_mutex_unlock(&transport_lock);
-
- if (!kicked)
- t->kick(t);
- }
-}
-
-void
-run_transport_disconnects(atransport* t)
-{
- adisconnect* dis = t->disconnects.next;
-
- D("%s: run_transport_disconnects\n", t->serial);
- while (dis != &t->disconnects) {
- adisconnect* next = dis->next;
- dis->func( dis->opaque, t );
- dis = next;
- }
-}
-
-#if ADB_TRACE
-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];
- char arg0[12], arg1[12];
- int n;
-
- for (n = 0; n < 4; n++) {
- int b = (command >> (n*8)) & 255;
- if (b < 32 || b >= 127)
- break;
- cmd[n] = (char)b;
- }
- if (n == 4) {
- cmd[4] = 0;
- } else {
- /* There is some non-ASCII name in the command, so dump
- * the hexadecimal value instead */
- snprintf(cmd, sizeof cmd, "%08x", command);
- }
-
- if (p->msg.arg0 < 256U)
- snprintf(arg0, sizeof arg0, "%d", p->msg.arg0);
- else
- snprintf(arg0, sizeof arg0, "0x%x", p->msg.arg0);
-
- if (p->msg.arg1 < 256U)
- snprintf(arg1, sizeof arg1, "%d", p->msg.arg1);
- else
- snprintf(arg1, sizeof arg1, "0x%x", p->msg.arg1);
-
- D("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ",
- 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)
-{
- char *p = (char*)ppacket; /* really read a packet address */
- int r;
- int len = sizeof(*ppacket);
- char buff[8];
- if (!name) {
- snprintf(buff, sizeof buff, "fd=%d", fd);
- name = buff;
- }
- while(len > 0) {
- r = adb_read(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
- if((r < 0) && (errno == EINTR)) continue;
- return -1;
- }
- }
-
-#if ADB_TRACE
- if (ADB_TRACING) {
- dump_packet(name, "from remote", *ppacket);
- }
-#endif
- return 0;
-}
-
-static int
-write_packet(int fd, const char* name, apacket** ppacket)
-{
- char *p = (char*) ppacket; /* we really write the packet address */
- int r, len = sizeof(ppacket);
- char buff[8];
- if (!name) {
- snprintf(buff, sizeof buff, "fd=%d", fd);
- 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);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
- if((r < 0) && (errno == EINTR)) continue;
- return -1;
- }
- }
- return 0;
-}
-
-static void transport_socket_events(int fd, unsigned events, void *_t)
-{
- atransport *t = _t;
- D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
- if(events & FDE_READ){
- apacket *p = 0;
- if(read_packet(fd, t->serial, &p)){
- D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);
- } else {
- handle_packet(p, (atransport *) _t);
- }
- }
-}
-
-void send_packet(apacket *p, atransport *t)
-{
- unsigned char *x;
- unsigned sum;
- unsigned count;
-
- p->msg.magic = p->msg.command ^ 0xffffffff;
-
- count = p->msg.data_length;
- x = (unsigned char *) p->data;
- sum = 0;
- while(count-- > 0){
- sum += *x++;
- }
- p->msg.data_check = sum;
-
- print_packet("send", p);
-
- if (t == NULL) {
- D("Transport is null \n");
- // Zap errno because print_packet() and other stuff have errno effect.
- errno = 0;
- fatal_errno("Transport is null");
- }
-
- if(write_packet(t->transport_socket, t->serial, &p)){
- fatal_errno("cannot enqueue packet on transport socket");
- }
-}
-
-/* The transport is opened by transport_register_func before
-** the input and output threads are started.
-**
-** The output thread issues a SYNC(1, token) message to let
-** the input thread know to start things up. In the event
-** of transport IO failure, the output thread will post a
-** SYNC(0,0) message to ensure shutdown.
-**
-** The transport will not actually be closed until both
-** threads exit, but the input thread will kick the transport
-** on its way out to disconnect the underlying device.
-*/
-
-static void *output_thread(void *_t)
-{
- atransport *t = _t;
- apacket *p;
-
- D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
- t->serial, t->fd, t->sync_token + 1);
- p = get_apacket();
- p->msg.command = A_SYNC;
- p->msg.arg0 = 1;
- p->msg.arg1 = ++(t->sync_token);
- p->msg.magic = A_SYNC ^ 0xffffffff;
- if(write_packet(t->fd, t->serial, &p)) {
- put_apacket(p);
- D("%s: failed to write SYNC packet\n", t->serial);
- goto oops;
- }
-
- D("%s: data pump started\n", t->serial);
- for(;;) {
- p = get_apacket();
-
- if(t->read_from_remote(p, t) == 0){
- D("%s: received remote packet, sending to transport\n",
- t->serial);
- if(write_packet(t->fd, t->serial, &p)){
- put_apacket(p);
- D("%s: failed to write apacket to transport\n", t->serial);
- goto oops;
- }
- } else {
- D("%s: remote read failed for transport\n", t->serial);
- put_apacket(p);
- break;
- }
- }
-
- D("%s: SYNC offline for transport\n", t->serial);
- p = get_apacket();
- p->msg.command = A_SYNC;
- p->msg.arg0 = 0;
- p->msg.arg1 = 0;
- p->msg.magic = A_SYNC ^ 0xffffffff;
- if(write_packet(t->fd, t->serial, &p)) {
- put_apacket(p);
- D("%s: failed to write SYNC apacket to transport", t->serial);
- }
-
-oops:
- D("%s: transport output thread is exiting\n", t->serial);
- kick_transport(t);
- transport_unref(t);
- return 0;
-}
-
-static void *input_thread(void *_t)
-{
- atransport *t = _t;
- apacket *p;
- int active = 0;
-
- D("%s: starting transport input thread, reading from fd %d\n",
- t->serial, t->fd);
-
- for(;;){
- if(read_packet(t->fd, t->serial, &p)) {
- D("%s: failed to read apacket from transport on fd %d\n",
- t->serial, t->fd );
- break;
- }
- if(p->msg.command == A_SYNC){
- if(p->msg.arg0 == 0) {
- D("%s: transport SYNC offline\n", t->serial);
- put_apacket(p);
- break;
- } else {
- if(p->msg.arg1 == t->sync_token) {
- D("%s: transport SYNC online\n", t->serial);
- active = 1;
- } else {
- D("%s: transport ignoring SYNC %d != %d\n",
- t->serial, p->msg.arg1, t->sync_token);
- }
- }
- } else {
- if(active) {
- D("%s: transport got packet, sending to remote\n", t->serial);
- t->write_to_remote(p, t);
- } else {
- D("%s: transport ignoring packet while offline\n", t->serial);
- }
- }
-
- put_apacket(p);
- }
-
- // this is necessary to avoid a race condition that occured when a transport closes
- // while a client socket is still active.
- close_all_sockets(t);
-
- D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd);
- kick_transport(t);
- transport_unref(t);
- return 0;
-}
-
-
-static int transport_registration_send = -1;
-static int transport_registration_recv = -1;
-static fdevent transport_registration_fde;
-
-void update_transports(void)
-{
- // nothing to do on the device side
-}
-
-typedef struct tmsg tmsg;
-struct tmsg
-{
- atransport *transport;
- int action;
-};
-
-static int
-transport_read_action(int fd, struct tmsg* m)
-{
- char *p = (char*)m;
- int len = sizeof(*m);
- int r;
-
- while(len > 0) {
- r = adb_read(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- if((r < 0) && (errno == EINTR)) continue;
- D("transport_read_action: on fd %d, error %d: %s\n",
- fd, errno, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-static int
-transport_write_action(int fd, struct tmsg* m)
-{
- char *p = (char*)m;
- int len = sizeof(*m);
- int r;
-
- while(len > 0) {
- r = adb_write(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- if((r < 0) && (errno == EINTR)) continue;
- D("transport_write_action: on fd %d, error %d: %s\n",
- fd, errno, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-static void transport_registration_func(int _fd, unsigned ev, void *data)
-{
- tmsg m;
- adb_thread_t output_thread_ptr;
- adb_thread_t input_thread_ptr;
- int s[2];
- atransport *t;
-
- if(!(ev & FDE_READ)) {
- return;
- }
-
- if(transport_read_action(_fd, &m)) {
- fatal_errno("cannot read transport registration socket");
- }
-
- t = m.transport;
-
- if(m.action == 0){
- D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket);
-
- /* IMPORTANT: the remove closes one half of the
- ** socket pair. The close closes the other half.
- */
- fdevent_remove(&(t->transport_fde));
- adb_close(t->fd);
-
- adb_mutex_lock(&transport_lock);
- t->next->prev = t->prev;
- t->prev->next = t->next;
- adb_mutex_unlock(&transport_lock);
-
- run_transport_disconnects(t);
-
- if (t->product)
- free(t->product);
- if (t->serial)
- free(t->serial);
-
- memset(t,0xee,sizeof(atransport));
- free(t);
-
- update_transports();
- return;
- }
-
- /* don't create transport threads for inaccessible devices */
- if (t->connection_state != CS_NOPERM) {
- /* initial references are the two threads */
- t->ref_count = 2;
-
- if(adb_socketpair(s)) {
- fatal_errno("cannot open transport socketpair");
- }
-
- D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]);
-
- t->transport_socket = s[0];
- t->fd = s[1];
-
- fdevent_install(&(t->transport_fde),
- t->transport_socket,
- transport_socket_events,
- t);
-
- fdevent_set(&(t->transport_fde), FDE_READ);
-
- if(adb_thread_create(&input_thread_ptr, input_thread, t)){
- fatal_errno("cannot create input thread");
- }
-
- if(adb_thread_create(&output_thread_ptr, output_thread, t)){
- fatal_errno("cannot create output thread");
- }
- }
-
- /* put us on the master device list */
- adb_mutex_lock(&transport_lock);
- t->next = &transport_list;
- t->prev = transport_list.prev;
- t->next->prev = t;
- t->prev->next = t;
- adb_mutex_unlock(&transport_lock);
-
- t->disconnects.next = t->disconnects.prev = &t->disconnects;
-
- update_transports();
-}
-
-void init_transport_registration(void)
-{
- int s[2];
-
- if(adb_socketpair(s)){
- fatal_errno("cannot open transport registration socketpair");
- }
-
- transport_registration_send = s[0];
- transport_registration_recv = s[1];
-
- fdevent_install(&transport_registration_fde,
- transport_registration_recv,
- transport_registration_func,
- 0);
-
- fdevent_set(&transport_registration_fde, FDE_READ);
-}
-
-/* the fdevent select pump is single threaded */
-static void register_transport(atransport *transport)
-{
- tmsg m;
- m.transport = transport;
- m.action = 1;
- D("transport: %s registered\n", transport->serial);
- if(transport_write_action(transport_registration_send, &m)) {
- fatal_errno("cannot write transport registration socket\n");
- }
-}
-
-static void remove_transport(atransport *transport)
-{
- tmsg m;
- m.transport = transport;
- m.action = 0;
- D("transport: %s removed\n", transport->serial);
- if(transport_write_action(transport_registration_send, &m)) {
- fatal_errno("cannot write transport registration socket\n");
- }
-}
-
-
-static void transport_unref_locked(atransport *t)
-{
- t->ref_count--;
- if (t->ref_count == 0) {
- D("transport: %s unref (kicking and closing)\n", t->serial);
- if (!t->kicked) {
- t->kicked = 1;
- t->kick(t);
- }
- t->close(t);
- remove_transport(t);
- } else {
- D("transport: %s unref (count=%d)\n", t->serial, t->ref_count);
- }
-}
-
-static void transport_unref(atransport *t)
-{
- if (t) {
- adb_mutex_lock(&transport_lock);
- transport_unref_locked(t);
- adb_mutex_unlock(&transport_lock);
- }
-}
-
-void add_transport_disconnect(atransport* t, adisconnect* dis)
-{
- adb_mutex_lock(&transport_lock);
- dis->next = &t->disconnects;
- dis->prev = dis->next->prev;
- dis->prev->next = dis;
- dis->next->prev = dis;
- adb_mutex_unlock(&transport_lock);
-}
-
-void remove_transport_disconnect(atransport* t, adisconnect* dis)
-{
- dis->prev->next = dis->next;
- dis->next->prev = dis->prev;
- dis->next = dis->prev = dis;
-}
-
-
-atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out)
-{
- atransport *t;
- atransport *result = NULL;
- int ambiguous = 0;
-
-retry:
- if (error_out)
- *error_out = "device not found";
-
- adb_mutex_lock(&transport_lock);
- for (t = transport_list.next; t != &transport_list; t = t->next) {
- if (t->connection_state == CS_NOPERM) {
- if (error_out)
- *error_out = "insufficient permissions for device";
- continue;
- }
-
- /* check for matching serial number */
- if (serial) {
- if (t->serial && !strcmp(serial, t->serial)) {
- result = t;
- break;
- }
- } else {
- if (ttype == kTransportUsb && t->type == kTransportUsb) {
- if (result) {
- if (error_out)
- *error_out = "more than one device";
- ambiguous = 1;
- result = NULL;
- break;
- }
- result = t;
- } else if (ttype == kTransportLocal && t->type == kTransportLocal) {
- if (result) {
- if (error_out)
- *error_out = "more than one emulator";
- ambiguous = 1;
- result = NULL;
- break;
- }
- result = t;
- } else if (ttype == kTransportAny) {
- if (result) {
- if (error_out)
- *error_out = "more than one device and emulator";
- ambiguous = 1;
- result = NULL;
- break;
- }
- result = t;
- }
- }
- }
- adb_mutex_unlock(&transport_lock);
-
- if (result) {
- /* offline devices are ignored -- they are either being born or dying */
- if (result && result->connection_state == CS_OFFLINE) {
- if (error_out)
- *error_out = "device offline";
- result = NULL;
- }
- /* check for required connection state */
- if (result && state != CS_ANY && result->connection_state != state) {
- if (error_out)
- *error_out = "invalid device state";
- result = NULL;
- }
- }
-
- if (result) {
- /* found one that we can take */
- if (error_out)
- *error_out = NULL;
- } else if (state != CS_ANY && (serial || !ambiguous)) {
- adb_sleep_ms(1000);
- goto retry;
- }
-
- return result;
-}
-
-void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
-{
- atransport *t = calloc(1, sizeof(atransport));
- D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
- serial ? serial : "");
- init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
- if(serial) {
- t->serial = strdup(serial);
- }
- register_transport(t);
-}
-
-/* this should only be used for transports with connection_state == CS_NOPERM */
-void unregister_usb_transport(usb_handle *usb)
-{
- atransport *t;
- adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- if (t->usb == usb && t->connection_state == CS_NOPERM) {
- t->next->prev = t->prev;
- t->prev->next = t->next;
- break;
- }
- }
- adb_mutex_unlock(&transport_lock);
-}
-
-#undef TRACE_TAG
-#define TRACE_TAG TRACE_RWX
-
-int readx(int fd, void *ptr, size_t len)
-{
- char *p = ptr;
- int r;
-#if ADB_TRACE
- size_t len0 = len;
-#endif
- D("readx: fd=%d wanted=%d\n", fd, (int)len);
- while(len > 0) {
- r = adb_read(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- if (r < 0) {
- D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno));
- if (errno == EINTR)
- continue;
- } else {
- D("readx: fd=%d disconnected\n", fd);
- }
- return -1;
- }
- }
-
-#if ADB_TRACE
- D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
- dump_hex( ptr, len0 );
-#endif
- return 0;
-}
-
-int writex(int fd, const void *ptr, size_t len)
-{
- char *p = (char*) ptr;
- int r;
-
-#if ADB_TRACE
- D("writex: fd=%d len=%d: ", fd, (int)len);
- dump_hex( ptr, len );
-#endif
- while(len > 0) {
- r = adb_write(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- if (r < 0) {
- D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
- if (errno == EINTR)
- continue;
- } else {
- D("writex: fd=%d disconnected\n", fd);
- }
- return -1;
- }
- }
- return 0;
-}
-
-int check_header(apacket *p)
-{
- if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
- D("check_header(): invalid magic\n");
- return -1;
- }
-
- if(p->msg.data_length > MAX_PAYLOAD) {
- D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length);
- return -1;
- }
-
- return 0;
-}
-
-int check_data(apacket *p)
-{
- unsigned count, sum;
- unsigned char *x;
-
- count = p->msg.data_length;
- x = p->data;
- sum = 0;
- while(count-- > 0) {
- sum += *x++;
- }
-
- if(sum != p->msg.data_check) {
- return -1;
- } else {
- return 0;
- }
-}
diff --git a/minadbd/transport_usb.c b/minadbd/transport_usb.c
deleted file mode 100644
index 91cbf6151..000000000
--- a/minadbd/transport_usb.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sysdeps.h>
-
-#define TRACE_TAG TRACE_TRANSPORT
-#include "adb.h"
-
-#ifdef HAVE_BIG_ENDIAN
-#define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
-static inline void fix_endians(apacket *p)
-{
- p->msg.command = H4(p->msg.command);
- p->msg.arg0 = H4(p->msg.arg0);
- p->msg.arg1 = H4(p->msg.arg1);
- p->msg.data_length = H4(p->msg.data_length);
- p->msg.data_check = H4(p->msg.data_check);
- p->msg.magic = H4(p->msg.magic);
-}
-unsigned host_to_le32(unsigned n)
-{
- return H4(n);
-}
-#else
-#define fix_endians(p) do {} while (0)
-unsigned host_to_le32(unsigned n)
-{
- return n;
-}
-#endif
-
-static int remote_read(apacket *p, atransport *t)
-{
- if(usb_read(t->usb, &p->msg, sizeof(amessage))){
- D("remote usb: read terminated (message)\n");
- return -1;
- }
-
- fix_endians(p);
-
- if(check_header(p)) {
- D("remote usb: check_header failed\n");
- return -1;
- }
-
- if(p->msg.data_length) {
- if(usb_read(t->usb, p->data, p->msg.data_length)){
- D("remote usb: terminated (data)\n");
- return -1;
- }
- }
-
- if(check_data(p)) {
- D("remote usb: check_data failed\n");
- return -1;
- }
-
- return 0;
-}
-
-static int remote_write(apacket *p, atransport *t)
-{
- unsigned size = p->msg.data_length;
-
- fix_endians(p);
-
- if(usb_write(t->usb, &p->msg, sizeof(amessage))) {
- D("remote usb: 1 - write terminated\n");
- return -1;
- }
- if(p->msg.data_length == 0) return 0;
- if(usb_write(t->usb, &p->data, size)) {
- D("remote usb: 2 - write terminated\n");
- return -1;
- }
-
- return 0;
-}
-
-static void remote_close(atransport *t)
-{
- usb_close(t->usb);
- t->usb = 0;
-}
-
-static void remote_kick(atransport *t)
-{
- usb_kick(t->usb);
-}
-
-void init_usb_transport(atransport *t, usb_handle *h, int state)
-{
- D("transport: usb\n");
- t->close = remote_close;
- t->kick = remote_kick;
- t->read_from_remote = remote_read;
- t->write_to_remote = remote_write;
- t->sync_token = 1;
- t->connection_state = state;
- t->type = kTransportUsb;
- t->usb = h;
-
- HOST = 0;
-}
diff --git a/minadbd/usb_linux_client.c b/minadbd/usb_linux_client.c
deleted file mode 100644
index 29bab1558..000000000
--- a/minadbd/usb_linux_client.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/functionfs.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include "sysdeps.h"
-
-#define TRACE_TAG TRACE_USB
-#include "adb.h"
-
-#define MAX_PACKET_SIZE_FS 64
-#define MAX_PACKET_SIZE_HS 512
-
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
-
-struct usb_handle
-{
- int fd;
- adb_cond_t notify;
- adb_mutex_t lock;
-
- int (*write)(usb_handle *h, const void *data, int len);
- int (*read)(usb_handle *h, void *data, int len);
- void (*kick)(usb_handle *h);
-
- int control;
- int bulk_out; /* "out" from the host's perspective => source for adbd */
- int bulk_in; /* "in" from the host's perspective => sink for adbd */
-};
-
-static const struct {
- struct usb_functionfs_descs_head header;
- struct {
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor_no_audio source;
- struct usb_endpoint_descriptor_no_audio sink;
- } __attribute__((packed)) fs_descs, hs_descs;
-} __attribute__((packed)) descriptors = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC),
- .length = cpu_to_le32(sizeof(descriptors)),
- .fs_count = 3,
- .hs_count = 3,
- },
- .fs_descs = {
- .intf = {
- .bLength = sizeof(descriptors.fs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 2,
- .bInterfaceClass = ADB_CLASS,
- .bInterfaceSubClass = ADB_SUBCLASS,
- .bInterfaceProtocol = ADB_PROTOCOL,
- .iInterface = 1, /* first string from the provided table */
- },
- .source = {
- .bLength = sizeof(descriptors.fs_descs.source),
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_FS,
- },
- .sink = {
- .bLength = sizeof(descriptors.fs_descs.sink),
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_FS,
- },
- },
- .hs_descs = {
- .intf = {
- .bLength = sizeof(descriptors.hs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 2,
- .bInterfaceClass = ADB_CLASS,
- .bInterfaceSubClass = ADB_SUBCLASS,
- .bInterfaceProtocol = ADB_PROTOCOL,
- .iInterface = 1, /* first string from the provided table */
- },
- .source = {
- .bLength = sizeof(descriptors.hs_descs.source),
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_HS,
- },
- .sink = {
- .bLength = sizeof(descriptors.hs_descs.sink),
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = MAX_PACKET_SIZE_HS,
- },
- },
-};
-
-#define STR_INTERFACE_ "ADB Interface"
-
-static const struct {
- struct usb_functionfs_strings_head header;
- struct {
- __le16 code;
- const char str1[sizeof(STR_INTERFACE_)];
- } __attribute__((packed)) lang0;
-} __attribute__((packed)) strings = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
- .length = cpu_to_le32(sizeof(strings)),
- .str_count = cpu_to_le32(1),
- .lang_count = cpu_to_le32(1),
- },
- .lang0 = {
- cpu_to_le16(0x0409), /* en-us */
- STR_INTERFACE_,
- },
-};
-
-void usb_cleanup()
-{
- // nothing to do here
-}
-
-static void *usb_adb_open_thread(void *x)
-{
- struct usb_handle *usb = (struct usb_handle *)x;
- int fd;
-
- while (1) {
- // wait until the USB device needs opening
- adb_mutex_lock(&usb->lock);
- while (usb->fd != -1)
- adb_cond_wait(&usb->notify, &usb->lock);
- adb_mutex_unlock(&usb->lock);
-
- D("[ usb_thread - opening device ]\n");
- do {
- /* XXX use inotify? */
- fd = unix_open("/dev/android_adb", O_RDWR);
- if (fd < 0) {
- // to support older kernels
- fd = unix_open("/dev/android", O_RDWR);
- fprintf(stderr, "usb_adb_open_thread: %d\n", fd );
- }
- if (fd < 0) {
- adb_sleep_ms(1000);
- }
- } while (fd < 0);
- D("[ opening device succeeded ]\n");
-
- close_on_exec(fd);
- usb->fd = fd;
-
- D("[ usb_thread - registering device ]\n");
- register_usb_transport(usb, 0, 1);
- }
-
- // never gets here
- return 0;
-}
-
-static int usb_adb_write(usb_handle *h, const void *data, int len)
-{
- int n;
-
- D("about to write (fd=%d, len=%d)\n", h->fd, len);
- n = adb_write(h->fd, data, len);
- if(n != len) {
- D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
- h->fd, n, errno, strerror(errno));
- return -1;
- }
- D("[ done fd=%d ]\n", h->fd);
- return 0;
-}
-
-static int usb_adb_read(usb_handle *h, void *data, int len)
-{
- int n;
-
- D("about to read (fd=%d, len=%d)\n", h->fd, len);
- n = adb_read(h->fd, data, len);
- if(n != len) {
- D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
- h->fd, n, errno, strerror(errno));
- return -1;
- }
- D("[ done fd=%d ]\n", h->fd);
- return 0;
-}
-
-static void usb_adb_kick(usb_handle *h)
-{
- D("usb_kick\n");
- adb_mutex_lock(&h->lock);
- adb_close(h->fd);
- h->fd = -1;
-
- // notify usb_adb_open_thread that we are disconnected
- adb_cond_signal(&h->notify);
- adb_mutex_unlock(&h->lock);
-}
-
-static void usb_adb_init()
-{
- usb_handle *h;
- adb_thread_t tid;
- int fd;
-
- h = calloc(1, sizeof(usb_handle));
-
- h->write = usb_adb_write;
- h->read = usb_adb_read;
- h->kick = usb_adb_kick;
- h->fd = -1;
-
- adb_cond_init(&h->notify, 0);
- adb_mutex_init(&h->lock, 0);
-
- fprintf(stderr, "Starting to open usb_init()\n");
- // Open the file /dev/android_adb_enable to trigger
- // the enabling of the adb USB function in the kernel.
- // We never touch this file again - just leave it open
- // indefinitely so the kernel will know when we are running
- // and when we are not.
- fd = unix_open("/dev/android_adb_enable", O_RDWR);
- fprintf(stderr, "unix_open to open usb_init(): %d\n", fd);
- if (fd < 0) {
- D("failed to open /dev/android_adb_enable\n");
- } else {
- close_on_exec(fd);
- }
-
- D("[ usb_init - starting thread ]\n");
- if(adb_thread_create(&tid, usb_adb_open_thread, h)){
- fatal_errno("cannot create usb thread");
- fprintf(stderr, "cannot create the usb thread()\n");
- }
-}
-
-
-static void init_functionfs(struct usb_handle *h)
-{
- ssize_t ret;
-
- D("OPENING %s\n", USB_FFS_ADB_EP0);
- h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
- if (h->control < 0) {
- D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno);
- goto err;
- }
-
- ret = adb_write(h->control, &descriptors, sizeof(descriptors));
- if (ret < 0) {
- D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
- goto err;
- }
-
- ret = adb_write(h->control, &strings, sizeof(strings));
- if (ret < 0) {
- D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno);
- goto err;
- }
-
- h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
- if (h->bulk_out < 0) {
- D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno);
- goto err;
- }
-
- h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
- if (h->bulk_in < 0) {
- D("[ %s: cannot open bulk-in ep: errno=%d ]\n", USB_FFS_ADB_IN, errno);
- goto err;
- }
-
- return;
-
-err:
- if (h->bulk_in > 0) {
- adb_close(h->bulk_in);
- h->bulk_in = -1;
- }
- if (h->bulk_out > 0) {
- adb_close(h->bulk_out);
- h->bulk_out = -1;
- }
- if (h->control > 0) {
- adb_close(h->control);
- h->control = -1;
- }
- return;
-}
-
-static void *usb_ffs_open_thread(void *x)
-{
- struct usb_handle *usb = (struct usb_handle *)x;
-
- while (1) {
- // wait until the USB device needs opening
- adb_mutex_lock(&usb->lock);
- while (usb->control != -1)
- adb_cond_wait(&usb->notify, &usb->lock);
- adb_mutex_unlock(&usb->lock);
-
- while (1) {
- init_functionfs(usb);
-
- if (usb->control >= 0)
- break;
-
- adb_sleep_ms(1000);
- }
-
- D("[ usb_thread - registering device ]\n");
- register_usb_transport(usb, 0, 1);
- }
-
- // never gets here
- return 0;
-}
-
-static int bulk_write(int bulk_in, const char *buf, size_t length)
-{
- size_t count = 0;
- int ret;
-
- do {
- ret = adb_write(bulk_in, buf + count, length - count);
- if (ret < 0) {
- if (errno != EINTR)
- return ret;
- } else {
- count += ret;
- }
- } while (count < length);
-
- D("[ bulk_write done fd=%d ]\n", bulk_in);
- return count;
-}
-
-static int usb_ffs_write(usb_handle *h, const void *data, int len)
-{
- int n;
-
- D("about to write (fd=%d, len=%d)\n", h->bulk_in, len);
- n = bulk_write(h->bulk_in, data, len);
- if (n != len) {
- D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
- h->bulk_in, n, errno, strerror(errno));
- return -1;
- }
- D("[ done fd=%d ]\n", h->bulk_in);
- return 0;
-}
-
-static int bulk_read(int bulk_out, char *buf, size_t length)
-{
- size_t count = 0;
- int ret;
-
- do {
- ret = adb_read(bulk_out, buf + count, length - count);
- if (ret < 0) {
- if (errno != EINTR) {
- D("[ bulk_read failed fd=%d length=%zu count=%zu ]\n",
- bulk_out, length, count);
- return ret;
- }
- } else {
- count += ret;
- }
- } while (count < length);
-
- return count;
-}
-
-static int usb_ffs_read(usb_handle *h, void *data, int len)
-{
- int n;
-
- D("about to read (fd=%d, len=%d)\n", h->bulk_out, len);
- n = bulk_read(h->bulk_out, data, len);
- if (n != len) {
- D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
- h->bulk_out, n, errno, strerror(errno));
- return -1;
- }
- D("[ done fd=%d ]\n", h->bulk_out);
- return 0;
-}
-
-static void usb_ffs_kick(usb_handle *h)
-{
- int err;
-
- err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
- if (err < 0)
- D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);
-
- err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT);
- if (err < 0)
- D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
-
- adb_mutex_lock(&h->lock);
- adb_close(h->control);
- adb_close(h->bulk_out);
- adb_close(h->bulk_in);
- h->control = h->bulk_out = h->bulk_in = -1;
-
- // notify usb_ffs_open_thread that we are disconnected
- adb_cond_signal(&h->notify);
- adb_mutex_unlock(&h->lock);
-}
-
-static void usb_ffs_init()
-{
- usb_handle *h;
- adb_thread_t tid;
-
- D("[ usb_init - using FunctionFS ]\n");
-
- h = calloc(1, sizeof(usb_handle));
-
- h->write = usb_ffs_write;
- h->read = usb_ffs_read;
- h->kick = usb_ffs_kick;
-
- h->control = -1;
- h->bulk_out = -1;
- h->bulk_out = -1;
-
- adb_cond_init(&h->notify, 0);
- adb_mutex_init(&h->lock, 0);
-
- D("[ usb_init - starting thread ]\n");
- if (adb_thread_create(&tid, usb_ffs_open_thread, h)){
- fatal_errno("[ cannot create usb thread ]\n");
- }
-}
-
-void usb_init()
-{
- if (access(USB_FFS_ADB_EP0, F_OK) == 0)
- usb_ffs_init();
- else
- usb_adb_init();
-}
-
-int usb_write(usb_handle *h, const void *data, int len)
-{
- return h->write(h, data, len);
-}
-
-int usb_read(usb_handle *h, void *data, int len)
-{
- return h->read(h, data, len);
-}
-int usb_close(usb_handle *h)
-{
- // nothing to do here
- return 0;
-}
-
-void usb_kick(usb_handle *h)
-{
- h->kick(h);
-}
diff --git a/minadbd/utils.c b/minadbd/utils.c
deleted file mode 100644
index 91518bab6..000000000
--- a/minadbd/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/minadbd/utils.h b/minadbd/utils.h
deleted file mode 100644
index f70ecd24d..000000000
--- a/minadbd/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 */
diff --git a/minui/Android.mk b/minui/Android.mk
index df4aac169..9b2e09b70 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -4,11 +4,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := graphics.c graphics_adf.c graphics_fbdev.c events.c \
resources.c
-LOCAL_C_INCLUDES +=\
- external/libpng\
- external/zlib
-
LOCAL_WHOLE_STATIC_LIBRARIES += libadf
+LOCAL_STATIC_LIBRARIES += libpng
LOCAL_MODULE := libminui
@@ -16,6 +13,9 @@ LOCAL_MODULE := libminui
# ordinary characters in this context). Strip double-quotes from the
# value so that either will work.
+ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),ABGR_8888)
+ LOCAL_CFLAGS += -DRECOVERY_ABGR
+endif
ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),RGBX_8888)
LOCAL_CFLAGS += -DRECOVERY_RGBX
endif
@@ -30,3 +30,10 @@ else
endif
include $(BUILD_STATIC_LIBRARY)
+
+# Used by OEMs for factory test images.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libminui
+LOCAL_WHOLE_STATIC_LIBRARIES += libminui
+LOCAL_SHARED_LIBRARIES := libpng
+include $(BUILD_SHARED_LIBRARY)
diff --git a/minui/events.c b/minui/events.c
index df7dad448..9e4255dd7 100644
--- a/minui/events.c
+++ b/minui/events.c
@@ -16,6 +16,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/epoll.h>
@@ -78,8 +80,8 @@ int ev_init(ev_callback input_cb, void *data)
}
/* TODO: add ability to specify event masks. For now, just assume
- * that only EV_KEY and EV_REL event types are ever needed. */
- if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) {
+ * that only EV_KEY, EV_REL & EV_SW event types are ever needed. */
+ if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
close(fd);
continue;
}
diff --git a/minui/graphics.c b/minui/graphics.c
index 6049d85ca..870ffa089 100644
--- a/minui/graphics.c
+++ b/minui/graphics.c
@@ -16,6 +16,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
@@ -160,10 +161,17 @@ void gr_texticon(int x, int y, GRSurface* icon) {
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ gr_current_r = b;
+ gr_current_g = g;
+ gr_current_b = r;
+ gr_current_a = a;
+#else
gr_current_r = r;
gr_current_g = g;
gr_current_b = b;
gr_current_a = a;
+#endif
}
void gr_clear()
diff --git a/minui/graphics_adf.c b/minui/graphics_adf.c
index ac6d64e9e..c023d4db9 100644
--- a/minui/graphics_adf.c
+++ b/minui/graphics_adf.c
@@ -19,6 +19,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/cdefs.h>
@@ -141,7 +142,9 @@ static gr_surface adf_init(minui_backend *backend)
ssize_t n_dev_ids, i;
gr_surface ret;
-#if defined(RECOVERY_BGRA)
+#if defined(RECOVERY_ABGR)
+ pdata->format = DRM_FORMAT_ABGR8888;
+#elif defined(RECOVERY_BGRA)
pdata->format = DRM_FORMAT_BGRA8888;
#elif defined(RECOVERY_RGBX)
pdata->format = DRM_FORMAT_RGBX8888;
diff --git a/minui/graphics_fbdev.c b/minui/graphics_fbdev.c
index 6df2726f5..4a5b5b513 100644
--- a/minui/graphics_fbdev.c
+++ b/minui/graphics_fbdev.c
@@ -16,6 +16,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
@@ -198,21 +199,8 @@ static gr_surface fbdev_flip(minui_backend* backend __unused) {
set_displayed_framebuffer(1-displayed_buffer);
} else {
// Copy from the in-memory surface to the framebuffer.
-
-#if defined(RECOVERY_BGRA)
- unsigned int idx;
- unsigned char* ucfb_vaddr = (unsigned char*)gr_framebuffer[0].data;
- unsigned char* ucbuffer_vaddr = (unsigned char*)gr_draw->data;
- for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes); idx += 4) {
- ucfb_vaddr[idx ] = ucbuffer_vaddr[idx + 2];
- ucfb_vaddr[idx + 1] = ucbuffer_vaddr[idx + 1];
- ucfb_vaddr[idx + 2] = ucbuffer_vaddr[idx ];
- ucfb_vaddr[idx + 3] = ucbuffer_vaddr[idx + 3];
- }
-#else
memcpy(gr_framebuffer[0].data, gr_draw->data,
gr_draw->height * gr_draw->row_bytes);
-#endif
}
return gr_draw;
}
diff --git a/minui/resources.c b/minui/resources.c
index 2bae4ded0..886c3255d 100644
--- a/minui/resources.c
+++ b/minui/resources.c
@@ -15,6 +15,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
@@ -215,6 +216,10 @@ int res_create_display_surface(const char* name, gr_surface* pSurface) {
goto exit;
}
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
unsigned char* p_row = malloc(width * 4);
unsigned int y;
for (y = 0; y < height; ++y) {
@@ -278,6 +283,10 @@ int res_create_multi_display_surface(const char* name, int* frames, gr_surface**
}
}
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
unsigned char* p_row = malloc(width * 4);
unsigned int y;
for (y = 0; y < height; ++y) {
@@ -333,6 +342,10 @@ int res_create_alpha_surface(const char* name, gr_surface* pSurface) {
surface->row_bytes = width;
surface->pixel_bytes = 1;
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
unsigned char* p_row;
unsigned int y;
for (y = 0; y < height; ++y) {
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c
index fe2c880ac..97cb2e0ee 100644
--- a/minzip/DirUtil.c
+++ b/minzip/DirUtil.c
@@ -85,7 +85,7 @@ dirCreateHierarchy(const char *path, int mode,
c--;
}
if (c == cpath) {
-//xxx test this path
+ //xxx test this path
/* No directory component. Act like the path was empty.
*/
errno = ENOENT;
@@ -206,7 +206,7 @@ dirUnlinkHierarchy(const char *path)
/* recurse over components */
errno = 0;
while ((de = readdir(dir)) != NULL) {
-//TODO: don't blow the stack
+ //TODO: don't blow the stack
char dn[PATH_MAX];
if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
continue;
diff --git a/minzip/Hash.c b/minzip/Hash.c
index 8c6ca9bc2..8f8ed68e5 100644
--- a/minzip/Hash.c
+++ b/minzip/Hash.c
@@ -140,7 +140,6 @@ static bool resizeHash(HashTable* pHashTable, int newSize)
int i;
assert(countTombStones(pHashTable) == pHashTable->numDeadEntries);
- //LOGI("before: dead=%d\n", pHashTable->numDeadEntries);
pNewEntries = (HashEntry*) calloc(newSize, sizeof(HashTable));
if (pNewEntries == NULL)
@@ -196,7 +195,6 @@ void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item
(*cmpFunc)(pEntry->data, item) == 0)
{
/* match */
- //LOGD("+++ match on entry %d\n", pEntry - pHashTable->pEntries);
break;
}
@@ -206,8 +204,6 @@ void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item
break; /* edge case - single-entry table */
pEntry = pHashTable->pEntries;
}
-
- //LOGI("+++ look probing %d...\n", pEntry - pHashTable->pEntries);
}
if (pEntry->data == NULL) {
@@ -228,10 +224,6 @@ void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item
abort();
}
/* note "pEntry" is now invalid */
- } else {
- //LOGW("okay %d/%d/%d\n",
- // pHashTable->numEntries, pHashTable->tableSize,
- // (pHashTable->tableSize * LOAD_NUMER) / LOAD_DENOM);
}
/* full table is bad -- search for nonexistent never halts */
@@ -264,7 +256,6 @@ bool mzHashTableRemove(HashTable* pHashTable, unsigned int itemHash, void* item)
pEnd = &pHashTable->pEntries[pHashTable->tableSize];
while (pEntry->data != NULL) {
if (pEntry->data == item) {
- //LOGI("+++ stepping on entry %d\n", pEntry - pHashTable->pEntries);
pEntry->data = HASH_TOMBSTONE;
pHashTable->numEntries--;
pHashTable->numDeadEntries++;
@@ -277,8 +268,6 @@ bool mzHashTableRemove(HashTable* pHashTable, unsigned int itemHash, void* item)
break; /* edge case - single-entry table */
pEntry = pHashTable->pEntries;
}
-
- //LOGI("+++ del probing %d...\n", pEntry - pHashTable->pEntries);
}
return false;
diff --git a/minzip/Zip.c b/minzip/Zip.c
index 70aff00cd..12e06f6d8 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -327,10 +327,6 @@ static bool parseZipArchive(ZipArchive* pArchive)
#else
pEntry = &pArchive->pEntries[i];
#endif
-
- //LOGI("%d: localHdr=%d fnl=%d el=%d cl=%d\n",
- // i, localHdrOffset, fileNameLen, extraLen, commentLen);
-
pEntry->fileNameLen = fileNameLen;
pEntry->fileName = fileName;
@@ -488,7 +484,7 @@ const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
/*
* Return true if the entry is a symbolic link.
*/
-bool mzIsZipEntrySymlink(const ZipEntry* pEntry)
+static bool mzIsZipEntrySymlink(const ZipEntry* pEntry)
{
if ((pEntry->versionMadeBy & 0xff00) == CENVEM_UNIX) {
return S_ISLNK(pEntry->externalFileAttributes >> 16);
@@ -632,30 +628,6 @@ static bool crcProcessFunction(const unsigned char *data, int dataLen,
return true;
}
-/*
- * Check the CRC on this entry; return true if it is correct.
- * May do other internal checks as well.
- */
-bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry)
-{
- unsigned long crc;
- bool ret;
-
- crc = crc32(0L, Z_NULL, 0);
- ret = mzProcessZipEntryContents(pArchive, pEntry, crcProcessFunction,
- (void *)&crc);
- if (!ret) {
- LOGE("Can't calculate CRC for entry\n");
- return false;
- }
- if (crc != (unsigned long)pEntry->crc32) {
- LOGW("CRC for entry %.*s (0x%08lx) != expected (0x%08lx)\n",
- pEntry->fileNameLen, pEntry->fileName, crc, pEntry->crc32);
- return false;
- }
- return true;
-}
-
typedef struct {
char *buf;
int bufLen;
@@ -737,23 +709,6 @@ bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
return true;
}
-/*
- * Obtain a pointer to the in-memory representation of a stored entry.
- */
-bool mzGetStoredEntry(const ZipArchive *pArchive,
- const ZipEntry *pEntry, unsigned char **addr, size_t *length)
-{
- if (pEntry->compression != STORED) {
- LOGE("Can't getStoredEntry for '%s'; not stored\n",
- pEntry->fileName);
- return false;
- }
-
- *addr = pArchive->addr + pEntry->offset;
- *length = pEntry->uncompLen;
- return true;
-}
-
typedef struct {
unsigned char* buffer;
long len;
@@ -923,8 +878,8 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
/* Walk through the entries and extract anything whose path begins
* with zpath.
-//TODO: since the entries are sorted, binary search for the first match
-// and stop after the first non-match.
+ //TODO: since the entries are sorted, binary search for the first match
+ // and stop after the first non-match.
*/
unsigned int i;
bool seenMatch = false;
@@ -933,10 +888,10 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
for (i = 0; i < pArchive->numEntries; i++) {
ZipEntry *pEntry = pArchive->pEntries + i;
if (pEntry->fileNameLen < zipDirLen) {
-//TODO: look out for a single empty directory entry that matches zpath, but
-// missing the trailing slash. Most zip files seem to include
-// the trailing slash, but I think it's legal to leave it off.
-// e.g., zpath "a/b/", entry "a/b", with no children of the entry.
+ //TODO: look out for a single empty directory entry that matches zpath, but
+ // missing the trailing slash. Most zip files seem to include
+ // the trailing slash, but I think it's legal to leave it off.
+ // e.g., zpath "a/b/", entry "a/b", with no children of the entry.
/* No chance of matching.
*/
#if SORT_ENTRIES
diff --git a/minzip/Zip.h b/minzip/Zip.h
index 2054b38a4..54eab3222 100644
--- a/minzip/Zip.h
+++ b/minzip/Zip.h
@@ -92,49 +92,15 @@ INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
return pArchive->numEntries;
}
-/*
- * Get an entry by index. Returns NULL if the index is out-of-bounds.
- */
-INLINE const ZipEntry*
-mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
-{
- if (index < pArchive->numEntries) {
- return pArchive->pEntries + index;
- }
- return NULL;
-}
-
-/*
- * Get the index number of an entry in the archive.
- */
-INLINE unsigned int
-mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
- return pEntry - pArchive->pEntries;
-}
-
-/*
- * Simple accessors.
- */
-INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
- UnterminatedString ret;
- ret.str = pEntry->fileName;
- ret.len = pEntry->fileNameLen;
- return ret;
-}
INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
return pEntry->offset;
}
INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
return pEntry->uncompLen;
}
-INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
- return pEntry->modTime;
-}
INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
return pEntry->crc32;
}
-bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
-
/*
* Type definition for the callback function used by
@@ -164,12 +130,6 @@ bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
char* buf, int bufLen);
/*
- * Check the CRC on this entry; return true if it is correct.
- * May do other internal checks as well.
- */
-bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
-
-/*
* Inflate and write an entry to a file.
*/
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
@@ -183,17 +143,6 @@ bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive,
const ZipEntry *pEntry, unsigned char* buffer);
/*
- * Return a pointer and length for a given entry. The returned region
- * should be valid until pArchive is closed, and should be treated as
- * read-only.
- *
- * Only makes sense for entries which are stored (ie, not compressed).
- * No guarantees are made regarding alignment of the returned pointer.
- */
-bool mzGetStoredEntry(const ZipArchive *pArchive,
- const ZipEntry* pEntry, unsigned char **addr, size_t *length);
-
-/*
* Inflate all entries under zipDir to the directory specified by
* targetDir, which must exist and be a writable directory.
*
diff --git a/mtdutils/mounts.c b/mtdutils/mounts.c
index c90fc8acf..6a9b03d30 100644
--- a/mtdutils/mounts.c
+++ b/mtdutils/mounts.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,10 +60,8 @@ free_volume_internals(const MountedVolume *volume, int zero)
int
scan_mounted_volumes()
{
- char buf[2048];
- const char *bufp;
- int fd;
- ssize_t nbytes;
+ FILE* fp;
+ struct mntent* mentry;
if (g_mounts_state.volumes == NULL) {
const int numv = 32;
@@ -84,80 +83,20 @@ scan_mounted_volumes()
}
g_mounts_state.volume_count = 0;
- /* Open and read the file contents.
- */
- fd = open(PROC_MOUNTS_FILENAME, O_RDONLY);
- if (fd < 0) {
- goto bail;
- }
- nbytes = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (nbytes < 0) {
- goto bail;
+ /* Open and read mount table entries. */
+ fp = setmntent(PROC_MOUNTS_FILENAME, "r");
+ if (fp == NULL) {
+ return -1;
}
- buf[nbytes] = '\0';
-
- /* Parse the contents of the file, which looks like:
- *
- * # cat /proc/mounts
- * rootfs / rootfs rw 0 0
- * /dev/pts /dev/pts devpts rw 0 0
- * /proc /proc proc rw 0 0
- * /sys /sys sysfs rw 0 0
- * /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0
- * /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0
- * /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0
- *
- * The zeroes at the end are dummy placeholder fields to make the
- * output match Linux's /etc/mtab, but don't represent anything here.
- */
- bufp = buf;
- while (nbytes > 0) {
- char device[64];
- char mount_point[64];
- char filesystem[64];
- char flags[128];
- int matches;
-
- /* %as is a gnu extension that malloc()s a string for each field.
- */
- matches = sscanf(bufp, "%63s %63s %63s %127s",
- device, mount_point, filesystem, flags);
-
- if (matches == 4) {
- device[sizeof(device)-1] = '\0';
- mount_point[sizeof(mount_point)-1] = '\0';
- filesystem[sizeof(filesystem)-1] = '\0';
- flags[sizeof(flags)-1] = '\0';
-
- MountedVolume *v =
- &g_mounts_state.volumes[g_mounts_state.volume_count++];
- v->device = strdup(device);
- v->mount_point = strdup(mount_point);
- v->filesystem = strdup(filesystem);
- v->flags = strdup(flags);
- } else {
-printf("matches was %d on <<%.40s>>\n", matches, bufp);
- }
-
- /* Eat the line.
- */
- while (nbytes > 0 && *bufp != '\n') {
- bufp++;
- nbytes--;
- }
- if (nbytes > 0) {
- bufp++;
- nbytes--;
- }
+ while ((mentry = getmntent(fp)) != NULL) {
+ MountedVolume* v = &g_mounts_state.volumes[g_mounts_state.volume_count++];
+ v->device = strdup(mentry->mnt_fsname);
+ v->mount_point = strdup(mentry->mnt_dir);
+ v->filesystem = strdup(mentry->mnt_type);
+ v->flags = strdup(mentry->mnt_opts);
}
-
+ endmntent(fp);
return 0;
-
-bail:
-//TODO: free the strings we've allocated.
- g_mounts_state.volume_count = 0;
- return -1;
}
const MountedVolume *
diff --git a/recovery.cpp b/recovery.cpp
index 6deeaaaed..f3cb06747 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -44,7 +44,7 @@
#include "device.h"
#include "adb_install.h"
extern "C" {
-#include "minadbd/adb.h"
+#include "adb.h"
#include "fuse_sideload.h"
#include "fuse_sdcard_provider.h"
}
@@ -169,6 +169,11 @@ fopen_path(const char *path, const char *mode) {
return fp;
}
+bool is_ro_debuggable() {
+ char value[PROPERTY_VALUE_MAX+1];
+ return (property_get("ro.debuggable", value, NULL) == 1 && value[0] == '1');
+}
+
static void redirect_stdio(const char* filename) {
// If these fail, there's not really anywhere to complain...
freopen(filename, "a", stdout); setbuf(stdout, NULL);
@@ -993,7 +998,7 @@ main(int argc, char **argv) {
// only way recovery should be run with this argument is when it
// starts a copy of itself from the apply_from_adb() function.
if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
- adb_main();
+ adb_main(0, DEFAULT_ADB_PORT);
return 0;
}
@@ -1112,9 +1117,7 @@ main(int argc, char **argv) {
// If this is an eng or userdebug build, then automatically
// turn the text display on if the script fails so the error
// message is visible.
- char buffer[PROPERTY_VALUE_MAX+1];
- property_get("ro.build.fingerprint", buffer, "");
- if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) {
+ if (is_ro_debuggable()) {
ui->ShowText(true);
}
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 4d99d5249..02a272a24 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -1,26 +1,25 @@
-# Build the unit tests.
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the unit tests.
-test_src_files := \
- asn1_decoder_test.cpp
+#
+# 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.
+#
-shared_libraries := \
- liblog \
- libcutils
-
-static_libraries := \
- libgtest \
- libgtest_main \
- libverifier
+LOCAL_PATH := $(call my-dir)
-$(foreach file,$(test_src_files), \
- $(eval include $(CLEAR_VARS)) \
- $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
- $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
- $(eval LOCAL_SRC_FILES := $(file)) \
- $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
- $(eval LOCAL_C_INCLUDES := $(LOCAL_PATH)/..) \
- $(eval include $(BUILD_NATIVE_TEST)) \
-) \ No newline at end of file
+include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_STATIC_LIBRARIES := libverifier
+LOCAL_SRC_FILES := asn1_decoder_test.cpp
+LOCAL_MODULE := asn1_decoder_test
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
+include $(BUILD_NATIVE_TEST)
diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c
index da02f4602..cbf792629 100644
--- a/tools/ota/check-lost+found.c
+++ b/tools/ota/check-lost+found.c
@@ -26,6 +26,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
+#include <unistd.h>
#include "private/android_filesystem_config.h"
diff --git a/uncrypt/uncrypt.c b/uncrypt/uncrypt.c
index 7fb0989a7..aa75210b0 100644
--- a/uncrypt/uncrypt.c
+++ b/uncrypt/uncrypt.c
@@ -39,8 +39,10 @@
// Recovery can take this block map file and retrieve the underlying
// file data to use as an update package.
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/updater/Android.mk b/updater/Android.mk
index 11e7bb807..ff02a33b0 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -79,7 +79,7 @@ $(inc) : $(inc_dep_file)
$(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@;)
$(hide) echo "}" >> $@
-$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc)
+$(call intermediates-dir-for,EXECUTABLES,updater,,,$(TARGET_PREFER_32_BIT))/updater.o : $(inc)
LOCAL_C_INCLUDES += $(dir $(inc))
inc :=
diff --git a/updater/MODULE_LICENSE_GPL b/updater/MODULE_LICENSE_GPL
deleted file mode 100644
index e69de29bb..000000000
--- a/updater/MODULE_LICENSE_GPL
+++ /dev/null
diff --git a/updater/NOTICE b/updater/NOTICE
deleted file mode 100644
index e77696ae8..000000000
--- a/updater/NOTICE
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/updater/updater.c b/updater/updater.c
index 465e1238e..661f69587 100644
--- a/updater/updater.c
+++ b/updater/updater.c
@@ -17,6 +17,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include "edify/expr.h"
#include "updater.h"
diff --git a/verifier.cpp b/verifier.cpp
index eeff95a59..61e5adf0b 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -26,9 +26,10 @@
#include "mincrypt/sha.h"
#include "mincrypt/sha256.h"
-#include <string.h>
-#include <stdio.h>
#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
extern RecoveryUI* ui;
diff --git a/verifier_test.cpp b/verifier_test.cpp
index 10a5ddaad..93a071e37 100644
--- a/verifier_test.cpp
+++ b/verifier_test.cpp
@@ -14,12 +14,14 @@
* limitations under the License.
*/
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
#include "common.h"
#include "verifier.h"