1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <errno.h> 18 #include <inttypes.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #include "adb.h" 25 #include "fdevent.h" 26 #include "fuse_adb_provider.h" 27 #include "sysdeps.h" 28 29 typedef struct stinfo stinfo; 30 31 struct stinfo { 32 void (*func)(int fd, void *cookie); 33 int fd; 34 void *cookie; 35 }; 36 37 void service_bootstrap_func(void* x) { 38 stinfo* sti = reinterpret_cast<stinfo*>(x); 39 sti->func(sti->fd, sti->cookie); 40 free(sti); 41 } 42 43 static void sideload_host_service(int sfd, void* data) { 44 char* args = reinterpret_cast<char*>(data); 45 int file_size; 46 int block_size; 47 if (sscanf(args, "%d:%d", &file_size, &block_size) != 2) { 48 printf("bad sideload-host arguments: %s\n", args); 49 exit(1); 50 } 51 free(args); 52 53 printf("sideload-host file size %d block size %d\n", file_size, block_size); 54 55 int result = run_adb_fuse(sfd, file_size, block_size); 56 57 printf("sideload_host finished\n"); 58 sleep(1); 59 exit(result == 0 ? 0 : 1); 60 } 61 62 static int create_service_thread(void (*func)(int, void *), void *cookie) { 63 int s[2]; 64 if (adb_socketpair(s)) { 65 printf("cannot create service socket pair\n"); 66 return -1; 67 } 68 69 stinfo* sti = static_cast<stinfo*>(malloc(sizeof(stinfo))); 70 if(sti == 0) fatal("cannot allocate stinfo"); 71 sti->func = func; 72 sti->cookie = cookie; 73 sti->fd = s[1]; 74 75 if (!adb_thread_create(service_bootstrap_func, sti)) { 76 free(sti); 77 adb_close(s[0]); 78 adb_close(s[1]); 79 printf("cannot create service thread\n"); 80 return -1; 81 } 82 83 VLOG(SERVICES) << "service thread started, " << s[0] << ":" << s[1]; 84 return s[0]; 85 } 86 87 int service_to_fd(const char* name, const atransport* transport) { 88 int ret = -1; 89 90 if (!strncmp(name, "sideload:", 9)) { 91 // this exit status causes recovery to print a special error 92 // message saying to use a newer adb (that supports 93 // sideload-host). 94 exit(3); 95 } else if (!strncmp(name, "sideload-host:", 14)) { 96 char* arg = strdup(name + 14); 97 ret = create_service_thread(sideload_host_service, arg); 98 } 99 if (ret >= 0) { 100 close_on_exec(ret); 101 } 102 return ret; 103 } 104