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