diff options
Diffstat (limited to 'minadbd')
-rw-r--r-- | minadbd/Android.mk | 8 | ||||
-rw-r--r-- | minadbd/adb.c | 10 | ||||
-rw-r--r-- | minadbd/adb.h | 3 | ||||
-rw-r--r-- | minadbd/fuse_adb_provider.c | 67 | ||||
-rw-r--r-- | minadbd/fuse_adb_provider.h | 22 | ||||
-rw-r--r-- | minadbd/services.c | 51 |
6 files changed, 112 insertions, 49 deletions
diff --git a/minadbd/Android.mk b/minadbd/Android.mk index 5a4de6828..04956d870 100644 --- a/minadbd/Android.mk +++ b/minadbd/Android.mk @@ -13,6 +13,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ adb.c \ fdevent.c \ + fuse_adb_provider.c \ transport.c \ transport_usb.c \ sockets.c \ @@ -22,11 +23,10 @@ LOCAL_SRC_FILES := \ LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE +LOCAL_C_INCLUDES += bootable/recovery LOCAL_MODULE := libminadbd -LOCAL_STATIC_LIBRARIES := libcutils libc -include $(BUILD_STATIC_LIBRARY) - - +LOCAL_STATIC_LIBRARIES := libfusesideload libcutils libc +include $(BUILD_STATIC_LIBRARY) diff --git a/minadbd/adb.c b/minadbd/adb.c index 7291b4bd5..127d072be 100644 --- a/minadbd/adb.c +++ b/minadbd/adb.c @@ -392,16 +392,6 @@ int adb_main() usb_init(); } - if (setgid(AID_SHELL) != 0) { - fprintf(stderr, "failed to setgid to shell\n"); - exit(1); - } - if (setuid(AID_SHELL) != 0) { - fprintf(stderr, "failed to setuid to shell\n"); - exit(1); - } - fprintf(stderr, "userid is %d\n", getuid()); - D("Event loop starting\n"); fdevent_loop(); diff --git a/minadbd/adb.h b/minadbd/adb.h index d389165ae..714868f5c 100644 --- a/minadbd/adb.h +++ b/minadbd/adb.h @@ -400,6 +400,7 @@ int connection_state(atransport *t); #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; @@ -420,6 +421,4 @@ extern int SHELL_EXIT_NOTIFY_FD; int sendfailmsg(int fd, const char *reason); int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s); -#define ADB_SIDELOAD_FILENAME "/tmp/update.zip" - #endif diff --git a/minadbd/fuse_adb_provider.c b/minadbd/fuse_adb_provider.c new file mode 100644 index 000000000..f80533a8c --- /dev/null +++ b/minadbd/fuse_adb_provider.c @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +#include "adb.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) { + struct adb_data* ad = (struct adb_data*)cookie; + + char buf[10]; + snprintf(buf, sizeof(buf), "%08u", block); + if (writex(ad->sfd, buf, 8) < 0) { + fprintf(stderr, "failed to write to adb host: %s\n", strerror(errno)); + return -EIO; + } + + if (readx(ad->sfd, buffer, fetch_size) < 0) { + fprintf(stderr, "failed to read from adb host: %s\n", strerror(errno)); + return -EIO; + } + + return 0; +} + +static void close_adb(void* cookie) { + struct adb_data* ad = (struct adb_data*)cookie; + + writex(ad->sfd, "DONEDONE", 8); +} + +int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size) { + struct adb_data ad; + struct provider_vtab vtab; + + ad.sfd = sfd; + ad.file_size = file_size; + ad.block_size = block_size; + + vtab.read_block = read_block_adb; + vtab.close = close_adb; + + return run_fuse_sideload(&vtab, &ad, file_size, block_size); +} diff --git a/minadbd/fuse_adb_provider.h b/minadbd/fuse_adb_provider.h new file mode 100644 index 000000000..0eb1f79d1 --- /dev/null +++ b/minadbd/fuse_adb_provider.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FUSE_ADB_PROVIDER_H +#define __FUSE_ADB_PROVIDER_H + +int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size); + +#endif diff --git a/minadbd/services.c b/minadbd/services.c index 752b33e82..218b84a38 100644 --- a/minadbd/services.c +++ b/minadbd/services.c @@ -22,6 +22,7 @@ #include "sysdeps.h" #include "fdevent.h" +#include "fuse_adb_provider.h" #define TRACE_TAG TRACE_SERVICES #include "adb.h" @@ -43,44 +44,23 @@ void *service_bootstrap_func(void *x) return 0; } -static void sideload_service(int s, void *cookie) +static void sideload_host_service(int sfd, void* cookie) { - unsigned char buf[4096]; - unsigned count = (unsigned)(uintptr_t)cookie; - int fd; - - fprintf(stderr, "sideload_service invoked\n"); - - fd = adb_creat(ADB_SIDELOAD_FILENAME, 0644); - if(fd < 0) { - fprintf(stderr, "failed to create %s\n", ADB_SIDELOAD_FILENAME); - adb_close(s); - exit(1); - } + char* saveptr; + const char* s = strtok_r(cookie, ":", &saveptr); + uint64_t file_size = strtoull(s, NULL, 10); + s = strtok_r(NULL, ":", &saveptr); + uint32_t block_size = strtoul(s, NULL, 10); - while(count > 0) { - unsigned xfer = (count > 4096) ? 4096 : count; - if(readx(s, buf, xfer)) break; - if(writex(fd, buf, xfer)) break; - count -= xfer; - } + printf("sideload-host file size %llu block size %lu\n", file_size, block_size); - if(count == 0) { - writex(s, "OKAY", 4); - } else { - writex(s, "FAIL", 4); - } - adb_close(fd); - adb_close(s); + int result = run_adb_fuse(sfd, file_size, block_size); - if (count == 0) { - fprintf(stderr, "adbd exiting after successful sideload\n"); - sleep(1); - exit(0); - } + printf("sideload_host finished\n"); + sleep(1); + exit(result == 0 ? 0 : 1); } - #if 0 static void echo_service(int fd, void *cookie) { @@ -149,7 +129,12 @@ int service_to_fd(const char *name) int ret = -1; if (!strncmp(name, "sideload:", 9)) { - ret = create_service_thread(sideload_service, (void*)(uintptr_t)atoi(name + 9)); + // this exit status causes recovery to print a special error + // message saying to use a newer adb (that supports + // sideload-host). + 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); |