Home | History | Annotate | Download | only in adb
      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 <stdlib.h>
     18 #include <stdio.h>
     19 #include <unistd.h>
     20 #include <string.h>
     21 #include <errno.h>
     22 
     23 #include "sysdeps.h"
     24 
     25 #define  TRACE_TAG  TRACE_SERVICES
     26 #include "adb.h"
     27 #include "file_sync_service.h"
     28 
     29 #if ADB_HOST
     30 #  ifndef HAVE_WINSOCK
     31 #    include <netinet/in.h>
     32 #    include <netdb.h>
     33 #    include <sys/ioctl.h>
     34 #  endif
     35 #else
     36 #  include <cutils/android_reboot.h>
     37 #endif
     38 
     39 typedef struct stinfo stinfo;
     40 
     41 struct stinfo {
     42     void (*func)(int fd, void *cookie);
     43     int fd;
     44     void *cookie;
     45 };
     46 
     47 
     48 void *service_bootstrap_func(void *x)
     49 {
     50     stinfo *sti = x;
     51     sti->func(sti->fd, sti->cookie);
     52     free(sti);
     53     return 0;
     54 }
     55 
     56 #if ADB_HOST
     57 ADB_MUTEX_DEFINE( dns_lock );
     58 
     59 static void dns_service(int fd, void *cookie)
     60 {
     61     char *hostname = cookie;
     62     struct hostent *hp;
     63     unsigned zero = 0;
     64 
     65     adb_mutex_lock(&dns_lock);
     66     hp = gethostbyname(hostname);
     67     free(cookie);
     68     if(hp == 0) {
     69         writex(fd, &zero, 4);
     70     } else {
     71         writex(fd, hp->h_addr, 4);
     72     }
     73     adb_mutex_unlock(&dns_lock);
     74     adb_close(fd);
     75 }
     76 #else
     77 extern int recovery_mode;
     78 
     79 static void recover_service(int s, void *cookie)
     80 {
     81     unsigned char buf[4096];
     82     unsigned count = (unsigned) cookie;
     83     int fd;
     84 
     85     fd = adb_creat("/tmp/update", 0644);
     86     if(fd < 0) {
     87         adb_close(s);
     88         return;
     89     }
     90 
     91     while(count > 0) {
     92         unsigned xfer = (count > 4096) ? 4096 : count;
     93         if(readx(s, buf, xfer)) break;
     94         if(writex(fd, buf, xfer)) break;
     95         count -= xfer;
     96     }
     97 
     98     if(count == 0) {
     99         writex(s, "OKAY", 4);
    100     } else {
    101         writex(s, "FAIL", 4);
    102     }
    103     adb_close(fd);
    104     adb_close(s);
    105 
    106     fd = adb_creat("/tmp/update.begin", 0644);
    107     adb_close(fd);
    108 }
    109 
    110 void restart_root_service(int fd, void *cookie)
    111 {
    112     char buf[100];
    113     char value[PROPERTY_VALUE_MAX];
    114 
    115     if (getuid() == 0) {
    116         snprintf(buf, sizeof(buf), "adbd is already running as root\n");
    117         writex(fd, buf, strlen(buf));
    118         adb_close(fd);
    119     } else {
    120         property_get("ro.debuggable", value, "");
    121         if (strcmp(value, "1") != 0) {
    122             snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
    123             writex(fd, buf, strlen(buf));
    124             adb_close(fd);
    125             return;
    126         }
    127 
    128         snprintf(buf, sizeof(buf), "restarting adbd as root\n");
    129         writex(fd, buf, strlen(buf));
    130         adb_close(fd);
    131 
    132         // This will cause a property trigger in init.rc to restart us
    133         property_set("service.adb.root", "1");
    134     }
    135 }
    136 
    137 void restart_tcp_service(int fd, void *cookie)
    138 {
    139     char buf[100];
    140     char value[PROPERTY_VALUE_MAX];
    141     int port = (int)cookie;
    142 
    143     if (port <= 0) {
    144         snprintf(buf, sizeof(buf), "invalid port\n");
    145         writex(fd, buf, strlen(buf));
    146         adb_close(fd);
    147         return;
    148     }
    149 
    150     snprintf(value, sizeof(value), "%d", port);
    151     property_set("service.adb.tcp.port", value);
    152     snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
    153     writex(fd, buf, strlen(buf));
    154     adb_close(fd);
    155 
    156     // quit, and init will restart us in TCP mode
    157     sleep(1);
    158     exit(1);
    159 }
    160 
    161 void restart_usb_service(int fd, void *cookie)
    162 {
    163     char buf[100];
    164 
    165     property_set("service.adb.tcp.port", "0");
    166     snprintf(buf, sizeof(buf), "restarting in USB mode\n");
    167     writex(fd, buf, strlen(buf));
    168     adb_close(fd);
    169 
    170     // quit, and init will restart us in USB mode
    171     sleep(1);
    172     exit(1);
    173 }
    174 
    175 void reboot_service(int fd, void *arg)
    176 {
    177     char buf[100];
    178     int pid, ret;
    179 
    180     sync();
    181 
    182     /* Attempt to unmount the SD card first.
    183      * No need to bother checking for errors.
    184      */
    185     pid = fork();
    186     if (pid == 0) {
    187         /* ask vdc to unmount it */
    188         execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount",
    189                 getenv("EXTERNAL_STORAGE"), "force", NULL);
    190     } else if (pid > 0) {
    191         /* wait until vdc succeeds or fails */
    192         waitpid(pid, &ret, 0);
    193     }
    194 
    195     ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
    196     if (ret < 0) {
    197         snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
    198         writex(fd, buf, strlen(buf));
    199     }
    200     free(arg);
    201     adb_close(fd);
    202 }
    203 
    204 #endif
    205 
    206 #if 0
    207 static void echo_service(int fd, void *cookie)
    208 {
    209     char buf[4096];
    210     int r;
    211     char *p;
    212     int c;
    213 
    214     for(;;) {
    215         r = read(fd, buf, 4096);
    216         if(r == 0) goto done;
    217         if(r < 0) {
    218             if(errno == EINTR) continue;
    219             else goto done;
    220         }
    221 
    222         c = r;
    223         p = buf;
    224         while(c > 0) {
    225             r = write(fd, p, c);
    226             if(r > 0) {
    227                 c -= r;
    228                 p += r;
    229                 continue;
    230             }
    231             if((r < 0) && (errno == EINTR)) continue;
    232             goto done;
    233         }
    234     }
    235 done:
    236     close(fd);
    237 }
    238 #endif
    239 
    240 static int create_service_thread(void (*func)(int, void *), void *cookie)
    241 {
    242     stinfo *sti;
    243     adb_thread_t t;
    244     int s[2];
    245 
    246     if(adb_socketpair(s)) {
    247         printf("cannot create service socket pair\n");
    248         return -1;
    249     }
    250 
    251     sti = malloc(sizeof(stinfo));
    252     if(sti == 0) fatal("cannot allocate stinfo");
    253     sti->func = func;
    254     sti->cookie = cookie;
    255     sti->fd = s[1];
    256 
    257     if(adb_thread_create( &t, service_bootstrap_func, sti)){
    258         free(sti);
    259         adb_close(s[0]);
    260         adb_close(s[1]);
    261         printf("cannot create service thread\n");
    262         return -1;
    263     }
    264 
    265     D("service thread started, %d:%d\n",s[0], s[1]);
    266     return s[0];
    267 }
    268 
    269 #if !ADB_HOST
    270 static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
    271 {
    272 #ifdef HAVE_WIN32_PROC
    273     D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
    274     fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
    275     return -1;
    276 #else /* !HAVE_WIN32_PROC */
    277     char *devname;
    278     int ptm;
    279 
    280     ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
    281     if(ptm < 0){
    282         printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
    283         return -1;
    284     }
    285     fcntl(ptm, F_SETFD, FD_CLOEXEC);
    286 
    287     if(grantpt(ptm) || unlockpt(ptm) ||
    288        ((devname = (char*) ptsname(ptm)) == 0)){
    289         printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
    290         adb_close(ptm);
    291         return -1;
    292     }
    293 
    294     *pid = fork();
    295     if(*pid < 0) {
    296         printf("- fork failed: %s -\n", strerror(errno));
    297         adb_close(ptm);
    298         return -1;
    299     }
    300 
    301     if(*pid == 0){
    302         int pts;
    303 
    304         setsid();
    305 
    306         pts = unix_open(devname, O_RDWR);
    307         if(pts < 0) {
    308             fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
    309             exit(-1);
    310         }
    311 
    312         dup2(pts, 0);
    313         dup2(pts, 1);
    314         dup2(pts, 2);
    315 
    316         adb_close(pts);
    317         adb_close(ptm);
    318 
    319         // set OOM adjustment to zero
    320         char text[64];
    321         snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid());
    322         int fd = adb_open(text, O_WRONLY);
    323         if (fd >= 0) {
    324             adb_write(fd, "0", 1);
    325             adb_close(fd);
    326         } else {
    327            D("adb: unable to open %s\n", text);
    328         }
    329         execl(cmd, cmd, arg0, arg1, NULL);
    330         fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
    331                 cmd, strerror(errno), errno);
    332         exit(-1);
    333     } else {
    334         // Don't set child's OOM adjustment to zero.
    335         // Let the child do it itself, as sometimes the parent starts
    336         // running before the child has a /proc/pid/oom_adj.
    337         // """adb: unable to open /proc/644/oom_adj""" seen in some logs.
    338         return ptm;
    339     }
    340 #endif /* !HAVE_WIN32_PROC */
    341 }
    342 #endif  /* !ABD_HOST */
    343 
    344 #if ADB_HOST
    345 #define SHELL_COMMAND "/bin/sh"
    346 #else
    347 #define SHELL_COMMAND "/system/bin/sh"
    348 #endif
    349 
    350 #if !ADB_HOST
    351 static void subproc_waiter_service(int fd, void *cookie)
    352 {
    353     pid_t pid = (pid_t)cookie;
    354 
    355     D("entered. fd=%d of pid=%d\n", fd, pid);
    356     for (;;) {
    357         int status;
    358         pid_t p = waitpid(pid, &status, 0);
    359         if (p == pid) {
    360             D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status);
    361             if (WIFSIGNALED(status)) {
    362                 D("*** Killed by signal %d\n", WTERMSIG(status));
    363                 break;
    364             } else if (!WIFEXITED(status)) {
    365                 D("*** Didn't exit!!. status %d\n", status);
    366                 break;
    367             } else if (WEXITSTATUS(status) >= 0) {
    368                 D("*** Exit code %d\n", WEXITSTATUS(status));
    369                 break;
    370             }
    371          }
    372         usleep(100000);  // poll every 0.1 sec
    373     }
    374     D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
    375     if (SHELL_EXIT_NOTIFY_FD >=0) {
    376       int res;
    377       res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd));
    378       D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n",
    379         SHELL_EXIT_NOTIFY_FD, pid, res, errno);
    380     }
    381 }
    382 
    383 static int create_subproc_thread(const char *name)
    384 {
    385     stinfo *sti;
    386     adb_thread_t t;
    387     int ret_fd;
    388     pid_t pid;
    389     if(name) {
    390         ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
    391     } else {
    392         ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
    393     }
    394     D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
    395 
    396     sti = malloc(sizeof(stinfo));
    397     if(sti == 0) fatal("cannot allocate stinfo");
    398     sti->func = subproc_waiter_service;
    399     sti->cookie = (void*)pid;
    400     sti->fd = ret_fd;
    401 
    402     if(adb_thread_create( &t, service_bootstrap_func, sti)){
    403         free(sti);
    404         adb_close(ret_fd);
    405         printf("cannot create service thread\n");
    406         return -1;
    407     }
    408 
    409     D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
    410     return ret_fd;
    411 }
    412 #endif
    413 
    414 int service_to_fd(const char *name)
    415 {
    416     int ret = -1;
    417 
    418     if(!strncmp(name, "tcp:", 4)) {
    419         int port = atoi(name + 4);
    420         name = strchr(name + 4, ':');
    421         if(name == 0) {
    422             ret = socket_loopback_client(port, SOCK_STREAM);
    423             if (ret >= 0)
    424                 disable_tcp_nagle(ret);
    425         } else {
    426 #if ADB_HOST
    427             adb_mutex_lock(&dns_lock);
    428             ret = socket_network_client(name + 1, port, SOCK_STREAM);
    429             adb_mutex_unlock(&dns_lock);
    430 #else
    431             return -1;
    432 #endif
    433         }
    434 #ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
    435     } else if(!strncmp(name, "local:", 6)) {
    436         ret = socket_local_client(name + 6,
    437                 ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    438     } else if(!strncmp(name, "localreserved:", 14)) {
    439         ret = socket_local_client(name + 14,
    440                 ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    441     } else if(!strncmp(name, "localabstract:", 14)) {
    442         ret = socket_local_client(name + 14,
    443                 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    444     } else if(!strncmp(name, "localfilesystem:", 16)) {
    445         ret = socket_local_client(name + 16,
    446                 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
    447 #endif
    448 #if ADB_HOST
    449     } else if(!strncmp("dns:", name, 4)){
    450         char *n = strdup(name + 4);
    451         if(n == 0) return -1;
    452         ret = create_service_thread(dns_service, n);
    453 #else /* !ADB_HOST */
    454     } else if(!strncmp("dev:", name, 4)) {
    455         ret = unix_open(name + 4, O_RDWR);
    456     } else if(!strncmp(name, "framebuffer:", 12)) {
    457         ret = create_service_thread(framebuffer_service, 0);
    458     } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
    459         ret = create_service_thread(recover_service, (void*) atoi(name + 8));
    460     } else if (!strncmp(name, "jdwp:", 5)) {
    461         ret = create_jdwp_connection_fd(atoi(name+5));
    462     } else if (!strncmp(name, "log:", 4)) {
    463         ret = create_service_thread(log_service, get_log_file_path(name + 4));
    464     } else if(!HOST && !strncmp(name, "shell:", 6)) {
    465         if(name[6]) {
    466             ret = create_subproc_thread(name + 6);
    467         } else {
    468             ret = create_subproc_thread(0);
    469         }
    470     } else if(!strncmp(name, "sync:", 5)) {
    471         ret = create_service_thread(file_sync_service, NULL);
    472     } else if(!strncmp(name, "remount:", 8)) {
    473         ret = create_service_thread(remount_service, NULL);
    474     } else if(!strncmp(name, "reboot:", 7)) {
    475         void* arg = strdup(name + 7);
    476         if(arg == 0) return -1;
    477         ret = create_service_thread(reboot_service, arg);
    478     } else if(!strncmp(name, "root:", 5)) {
    479         ret = create_service_thread(restart_root_service, NULL);
    480     } else if(!strncmp(name, "backup:", 7)) {
    481         char* arg = strdup(name+7);
    482         if (arg == NULL) return -1;
    483         ret = backup_service(BACKUP, arg);
    484     } else if(!strncmp(name, "restore:", 8)) {
    485         ret = backup_service(RESTORE, NULL);
    486     } else if(!strncmp(name, "tcpip:", 6)) {
    487         int port;
    488         if (sscanf(name + 6, "%d", &port) == 0) {
    489             port = 0;
    490         }
    491         ret = create_service_thread(restart_tcp_service, (void *)port);
    492     } else if(!strncmp(name, "usb:", 4)) {
    493         ret = create_service_thread(restart_usb_service, NULL);
    494 #endif
    495 #if 0
    496     } else if(!strncmp(name, "echo:", 5)){
    497         ret = create_service_thread(echo_service, 0);
    498 #endif
    499     }
    500     if (ret >= 0) {
    501         close_on_exec(ret);
    502     }
    503     return ret;
    504 }
    505 
    506 #if ADB_HOST
    507 struct state_info {
    508     transport_type transport;
    509     char* serial;
    510     int state;
    511 };
    512 
    513 static void wait_for_state(int fd, void* cookie)
    514 {
    515     struct state_info* sinfo = cookie;
    516     char* err = "unknown error";
    517 
    518     D("wait_for_state %d\n", sinfo->state);
    519 
    520     atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
    521     if(t != 0) {
    522         writex(fd, "OKAY", 4);
    523     } else {
    524         sendfailmsg(fd, err);
    525     }
    526 
    527     if (sinfo->serial)
    528         free(sinfo->serial);
    529     free(sinfo);
    530     adb_close(fd);
    531     D("wait_for_state is done\n");
    532 }
    533 #endif
    534 
    535 #if ADB_HOST
    536 asocket*  host_service_to_socket(const char*  name, const char *serial)
    537 {
    538     if (!strcmp(name,"track-devices")) {
    539         return create_device_tracker();
    540     } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
    541         struct state_info* sinfo = malloc(sizeof(struct state_info));
    542 
    543         if (serial)
    544             sinfo->serial = strdup(serial);
    545         else
    546             sinfo->serial = NULL;
    547 
    548         name += strlen("wait-for-");
    549 
    550         if (!strncmp(name, "local", strlen("local"))) {
    551             sinfo->transport = kTransportLocal;
    552             sinfo->state = CS_DEVICE;
    553         } else if (!strncmp(name, "usb", strlen("usb"))) {
    554             sinfo->transport = kTransportUsb;
    555             sinfo->state = CS_DEVICE;
    556         } else if (!strncmp(name, "any", strlen("any"))) {
    557             sinfo->transport = kTransportAny;
    558             sinfo->state = CS_DEVICE;
    559         } else {
    560             free(sinfo);
    561             return NULL;
    562         }
    563 
    564         int fd = create_service_thread(wait_for_state, sinfo);
    565         return create_local_socket(fd);
    566     }
    567     return NULL;
    568 }
    569 #endif /* ADB_HOST */
    570