commandline.cpp revision bd9305eeb7152058ba8255f0c2601d512c906f98
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#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20
21#include <assert.h>
22#include <ctype.h>
23#include <errno.h>
24#include <inttypes.h>
25#include <limits.h>
26#include <stdarg.h>
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33
34#include <string>
35
36#include <base/stringprintf.h>
37
38#if !defined(_WIN32)
39#include <termios.h>
40#include <unistd.h>
41#endif
42
43#include "adb.h"
44#include "adb_auth.h"
45#include "adb_client.h"
46#include "adb_io.h"
47#include "adb_utils.h"
48#include "file_sync_service.h"
49
50static int install_app(TransportType t, const char* serial, int argc, const char** argv);
51static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
52static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
53
54static std::string gProductOutPath;
55extern int gListenAll;
56
57static std::string product_file(const char *extra) {
58    if (gProductOutPath.empty()) {
59        fprintf(stderr, "adb: Product directory not specified; "
60                "use -p or define ANDROID_PRODUCT_OUT\n");
61        exit(1);
62    }
63
64    return android::base::StringPrintf("%s%s%s",
65                                       gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
66}
67
68static void help() {
69    fprintf(stderr, "%s\n", adb_version().c_str());
70    fprintf(stderr,
71        " -a                            - directs adb to listen on all interfaces for a connection\n"
72        " -d                            - directs command to the only connected USB device\n"
73        "                                 returns an error if more than one USB device is present.\n"
74        " -e                            - directs command to the only running emulator.\n"
75        "                                 returns an error if more than one emulator is running.\n"
76        " -s <specific device>          - directs command to the device or emulator with the given\n"
77        "                                 serial number or qualifier. Overrides ANDROID_SERIAL\n"
78        "                                 environment variable.\n"
79        " -p <product name or path>     - simple product name like 'sooner', or\n"
80        "                                 a relative/absolute path to a product\n"
81        "                                 out directory like 'out/target/product/sooner'.\n"
82        "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
83        "                                 environment variable is used, which must\n"
84        "                                 be an absolute path.\n"
85        " -H                            - Name of adb server host (default: localhost)\n"
86        " -P                            - Port of adb server (default: 5037)\n"
87        " devices [-l]                  - list all connected devices\n"
88        "                                 ('-l' will also list device qualifiers)\n"
89        " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
90        "                                 Port 5555 is used by default if no port number is specified.\n"
91        " disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.\n"
92        "                                 Port 5555 is used by default if no port number is specified.\n"
93        "                                 Using this command with no additional arguments\n"
94        "                                 will disconnect from all connected TCP/IP devices.\n"
95        "\n"
96        "device commands:\n"
97        "  adb push [-p] <local> <remote>\n"
98        "                               - copy file/dir to device\n"
99        "                                 ('-p' to display the transfer progress)\n"
100        "  adb pull [-p] [-a] <remote> [<local>]\n"
101        "                               - copy file/dir from device\n"
102        "                                 ('-p' to display the transfer progress)\n"
103        "                                 ('-a' means copy timestamp and mode)\n"
104        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
105        "                                 (-l means list but don't copy)\n"
106        "  adb shell                    - run remote shell interactively\n"
107        "  adb shell <command>          - run remote shell command\n"
108        "  adb emu <command>            - run emulator console command\n"
109        "  adb logcat [ <filter-spec> ] - View device log\n"
110        "  adb forward --list           - list all forward socket connections.\n"
111        "                                 the format is a list of lines with the following format:\n"
112        "                                    <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
113        "  adb forward <local> <remote> - forward socket connections\n"
114        "                                 forward specs are one of: \n"
115        "                                   tcp:<port>\n"
116        "                                   localabstract:<unix domain socket name>\n"
117        "                                   localreserved:<unix domain socket name>\n"
118        "                                   localfilesystem:<unix domain socket name>\n"
119        "                                   dev:<character device name>\n"
120        "                                   jdwp:<process pid> (remote only)\n"
121        "  adb forward --no-rebind <local> <remote>\n"
122        "                               - same as 'adb forward <local> <remote>' but fails\n"
123        "                                 if <local> is already forwarded\n"
124        "  adb forward --remove <local> - remove a specific forward socket connection\n"
125        "  adb forward --remove-all     - remove all forward socket connections\n"
126        "  adb reverse --list           - list all reverse socket connections from device\n"
127        "  adb reverse <remote> <local> - reverse socket connections\n"
128        "                                 reverse specs are one of:\n"
129        "                                   tcp:<port>\n"
130        "                                   localabstract:<unix domain socket name>\n"
131        "                                   localreserved:<unix domain socket name>\n"
132        "                                   localfilesystem:<unix domain socket name>\n"
133        "  adb reverse --norebind <remote> <local>\n"
134        "                               - same as 'adb reverse <remote> <local>' but fails\n"
135        "                                 if <remote> is already reversed.\n"
136        "  adb reverse --remove <remote>\n"
137        "                               - remove a specific reversed socket connection\n"
138        "  adb reverse --remove-all     - remove all reversed socket connections from device\n"
139        "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
140        "  adb install [-lrtsdg] <file>\n"
141        "                               - push this package file to the device and install it\n"
142        "                                 (-l: forward lock application)\n"
143        "                                 (-r: replace existing application)\n"
144        "                                 (-t: allow test packages)\n"
145        "                                 (-s: install application on sdcard)\n"
146        "                                 (-d: allow version code downgrade)\n"
147        "                                 (-g: grant all runtime permissions)\n"
148        "  adb install-multiple [-lrtsdpg] <file...>\n"
149        "                               - push this package file to the device and install it\n"
150        "                                 (-l: forward lock application)\n"
151        "                                 (-r: replace existing application)\n"
152        "                                 (-t: allow test packages)\n"
153        "                                 (-s: install application on sdcard)\n"
154        "                                 (-d: allow version code downgrade)\n"
155        "                                 (-p: partial application install)\n"
156        "                                 (-g: grant all runtime permissions)\n"
157        "  adb uninstall [-k] <package> - remove this app package from the device\n"
158        "                                 ('-k' means keep the data and cache directories)\n"
159        "  adb bugreport                - return all information from the device\n"
160        "                                 that should be included in a bug report.\n"
161        "\n"
162        "  adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
163        "                               - write an archive of the device's data to <file>.\n"
164        "                                 If no -f option is supplied then the data is written\n"
165        "                                 to \"backup.ab\" in the current directory.\n"
166        "                                 (-apk|-noapk enable/disable backup of the .apks themselves\n"
167        "                                    in the archive; the default is noapk.)\n"
168        "                                 (-obb|-noobb enable/disable backup of any installed apk expansion\n"
169        "                                    (aka .obb) files associated with each application; the default\n"
170        "                                    is noobb.)\n"
171        "                                 (-shared|-noshared enable/disable backup of the device's\n"
172        "                                    shared storage / SD card contents; the default is noshared.)\n"
173        "                                 (-all means to back up all installed applications)\n"
174        "                                 (-system|-nosystem toggles whether -all automatically includes\n"
175        "                                    system applications; the default is to include system apps)\n"
176        "                                 (<packages...> is the list of applications to be backed up.  If\n"
177        "                                    the -all or -shared flags are passed, then the package\n"
178        "                                    list is optional.  Applications explicitly given on the\n"
179        "                                    command line will be included even if -nosystem would\n"
180        "                                    ordinarily cause them to be omitted.)\n"
181        "\n"
182        "  adb restore <file>           - restore device contents from the <file> backup archive\n"
183        "\n"
184        "  adb disable-verity           - disable dm-verity checking on USERDEBUG builds\n"
185        "  adb enable-verity            - re-enable dm-verity checking on USERDEBUG builds\n"
186        "  adb keygen <file>            - generate adb public/private key. The private key is stored in <file>,\n"
187        "                                 and the public key is stored in <file>.pub. Any existing files\n"
188        "                                 are overwritten.\n"
189        "  adb help                     - show this help message\n"
190        "  adb version                  - show version num\n"
191        "\n"
192        "scripting:\n"
193        "  adb wait-for-device          - block until device is online\n"
194        "  adb start-server             - ensure that there is a server running\n"
195        "  adb kill-server              - kill the server if it is running\n"
196        "  adb get-state                - prints: offline | bootloader | device\n"
197        "  adb get-serialno             - prints: <serial-number>\n"
198        "  adb get-devpath              - prints: <device-path>\n"
199        "  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
200        "  adb reboot [bootloader|recovery]\n"
201        "                               - reboots the device, optionally into the bootloader or recovery program.\n"
202        "  adb reboot sideload          - reboots the device into the sideload mode in recovery program (adb root required).\n"
203        "  adb reboot sideload-auto-reboot\n"
204        "                               - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
205        "  adb sideload <file>          - sideloads the given package\n"
206        "  adb root                     - restarts the adbd daemon with root permissions\n"
207        "  adb unroot                   - restarts the adbd daemon without root permissions\n"
208        "  adb usb                      - restarts the adbd daemon listening on USB\n"
209        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port\n"
210        "\n"
211        "networking:\n"
212        "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
213        " Note: you should not automatically start a PPP connection.\n"
214        " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
215        " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
216        "\n"
217        "adb sync notes: adb sync [ <directory> ]\n"
218        "  <localdir> can be interpreted in several ways:\n"
219        "\n"
220        "  - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.\n"
221        "\n"
222        "  - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
223        "    is updated.\n"
224        "\n"
225        "environment variables:\n"
226        "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
227        "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
228        "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
229        "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
230        );
231}
232
233static int usage() {
234    help();
235    return 1;
236}
237
238#if defined(_WIN32)
239
240// Implemented in sysdeps_win32.cpp.
241void stdin_raw_init(int fd);
242void stdin_raw_restore(int fd);
243
244#else
245static termios g_saved_terminal_state;
246
247static void stdin_raw_init(int fd) {
248    if (tcgetattr(fd, &g_saved_terminal_state)) return;
249
250    termios tio;
251    if (tcgetattr(fd, &tio)) return;
252
253    cfmakeraw(&tio);
254
255    // No timeout but request at least one character per read.
256    tio.c_cc[VTIME] = 0;
257    tio.c_cc[VMIN] = 1;
258
259    tcsetattr(fd, TCSAFLUSH, &tio);
260}
261
262static void stdin_raw_restore(int fd) {
263    tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
264}
265#endif
266
267static void read_and_dump(int fd) {
268    while (fd >= 0) {
269        D("read_and_dump(): pre adb_read(fd=%d)", fd);
270        char buf[BUFSIZ];
271        int len = adb_read(fd, buf, sizeof(buf));
272        D("read_and_dump(): post adb_read(fd=%d): len=%d", fd, len);
273        if (len <= 0) {
274            break;
275        }
276
277        fwrite(buf, 1, len, stdout);
278        fflush(stdout);
279    }
280}
281
282static void read_status_line(int fd, char* buf, size_t count)
283{
284    count--;
285    while (count > 0) {
286        int len = adb_read(fd, buf, count);
287        if (len <= 0) {
288            break;
289        }
290
291        buf += len;
292        count -= len;
293    }
294    *buf = '\0';
295}
296
297static void copy_to_file(int inFd, int outFd) {
298    const size_t BUFSIZE = 32 * 1024;
299    char* buf = (char*) malloc(BUFSIZE);
300    if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
301    int len;
302    long total = 0;
303#ifdef _WIN32
304    int old_stdin_mode = -1;
305    int old_stdout_mode = -1;
306#endif
307
308    D("copy_to_file(%d -> %d)", inFd, outFd);
309
310    if (inFd == STDIN_FILENO) {
311        stdin_raw_init(STDIN_FILENO);
312#ifdef _WIN32
313        old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
314        if (old_stdin_mode == -1) {
315            fatal_errno("could not set stdin to binary");
316        }
317#endif
318    }
319
320#ifdef _WIN32
321    if (outFd == STDOUT_FILENO) {
322        old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
323        if (old_stdout_mode == -1) {
324            fatal_errno("could not set stdout to binary");
325        }
326    }
327#endif
328
329    while (true) {
330        if (inFd == STDIN_FILENO) {
331            len = unix_read(inFd, buf, BUFSIZE);
332        } else {
333            len = adb_read(inFd, buf, BUFSIZE);
334        }
335        if (len == 0) {
336            D("copy_to_file() : read 0 bytes; exiting");
337            break;
338        }
339        if (len < 0) {
340            D("copy_to_file(): read failed: %s", strerror(errno));
341            break;
342        }
343        if (outFd == STDOUT_FILENO) {
344            fwrite(buf, 1, len, stdout);
345            fflush(stdout);
346        } else {
347            adb_write(outFd, buf, len);
348        }
349        total += len;
350    }
351
352    if (inFd == STDIN_FILENO) {
353        stdin_raw_restore(STDIN_FILENO);
354#ifdef _WIN32
355        if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
356            fatal_errno("could not restore stdin mode");
357        }
358#endif
359    }
360
361#ifdef _WIN32
362    if (outFd == STDOUT_FILENO) {
363        if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
364            fatal_errno("could not restore stdout mode");
365        }
366    }
367#endif
368
369    D("copy_to_file() finished after %lu bytes", total);
370    free(buf);
371}
372
373static void *stdin_read_thread(void *x)
374{
375    int fd, fdi;
376    unsigned char buf[1024];
377    int r, n;
378    int state = 0;
379
380    int *fds = (int*) x;
381    fd = fds[0];
382    fdi = fds[1];
383    free(fds);
384
385    adb_thread_setname("stdin reader");
386
387    while (true) {
388        /* fdi is really the client's stdin, so use read, not adb_read here */
389        D("stdin_read_thread(): pre unix_read(fdi=%d,...)", fdi);
390        r = unix_read(fdi, buf, 1024);
391        D("stdin_read_thread(): post unix_read(fdi=%d,...)", fdi);
392        if (r <= 0) break;
393        for (n = 0; n < r; n++){
394            switch(buf[n]) {
395            case '\n':
396                state = 1;
397                break;
398            case '\r':
399                state = 1;
400                break;
401            case '~':
402                if(state == 1) state++;
403                break;
404            case '.':
405                if(state == 2) {
406                    fprintf(stderr,"\n* disconnect *\n");
407                    stdin_raw_restore(fdi);
408                    exit(0);
409                }
410            default:
411                state = 0;
412            }
413        }
414        r = adb_write(fd, buf, r);
415        if(r <= 0) {
416            break;
417        }
418    }
419    return 0;
420}
421
422static int interactive_shell() {
423    int fdi;
424
425    std::string error;
426    int fd = adb_connect("shell:", &error);
427    if (fd < 0) {
428        fprintf(stderr,"error: %s\n", error.c_str());
429        return 1;
430    }
431    fdi = 0; //dup(0);
432
433    int* fds = reinterpret_cast<int*>(malloc(sizeof(int) * 2));
434    if (fds == nullptr) {
435        fprintf(stderr, "couldn't allocate fds array: %s\n", strerror(errno));
436        return 1;
437    }
438
439    fds[0] = fd;
440    fds[1] = fdi;
441
442    stdin_raw_init(fdi);
443
444    adb_thread_create(stdin_read_thread, fds);
445    read_and_dump(fd);
446    stdin_raw_restore(fdi);
447    return 0;
448}
449
450
451static std::string format_host_command(const char* command, TransportType type, const char* serial) {
452    if (serial) {
453        return android::base::StringPrintf("host-serial:%s:%s", serial, command);
454    }
455
456    const char* prefix = "host";
457    if (type == kTransportUsb) {
458        prefix = "host-usb";
459    } else if (type == kTransportLocal) {
460        prefix = "host-local";
461    }
462    return android::base::StringPrintf("%s:%s", prefix, command);
463}
464
465static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
466                               bool show_progress)
467{
468    std::string error;
469    int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
470    if (fd < 0) {
471        fprintf(stderr,"error: %s\n", error.c_str());
472        return -1;
473    }
474
475    int opt = CHUNK_SIZE;
476    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
477
478    unsigned total = sz;
479    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
480
481    if (show_progress) {
482        const char* x = strrchr(service, ':');
483        if (x) service = x + 1;
484    }
485
486    while (sz > 0) {
487        unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
488        if (!WriteFdExactly(fd, ptr, xfer)) {
489            std::string error;
490            adb_status(fd, &error);
491            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
492            return -1;
493        }
494        sz -= xfer;
495        ptr += xfer;
496        if (show_progress) {
497            printf("sending: '%s' %4d%%    \r", fn, (int)(100LL - ((100LL * sz) / (total))));
498            fflush(stdout);
499        }
500    }
501    if (show_progress) {
502        printf("\n");
503    }
504
505    if (!adb_status(fd, &error)) {
506        fprintf(stderr,"* error response '%s' *\n", error.c_str());
507        return -1;
508    }
509
510    adb_close(fd);
511    return 0;
512}
513
514#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
515
516/*
517 * The sideload-host protocol serves the data in a file (given on the
518 * command line) to the client, using a simple protocol:
519 *
520 * - The connect message includes the total number of bytes in the
521 *   file and a block size chosen by us.
522 *
523 * - The other side sends the desired block number as eight decimal
524 *   digits (eg "00000023" for block 23).  Blocks are numbered from
525 *   zero.
526 *
527 * - We send back the data of the requested block.  The last block is
528 *   likely to be partial; when the last block is requested we only
529 *   send the part of the block that exists, it's not padded up to the
530 *   block size.
531 *
532 * - When the other side sends "DONEDONE" instead of a block number,
533 *   we hang up.
534 */
535static int adb_sideload_host(const char* fn) {
536    unsigned sz;
537    size_t xfer = 0;
538    int status;
539    int last_percent = -1;
540    int opt = SIDELOAD_HOST_BLOCK_SIZE;
541
542    printf("loading: '%s'", fn);
543    fflush(stdout);
544    uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
545    if (data == 0) {
546        printf("\n");
547        fprintf(stderr, "* cannot read '%s' *\n", fn);
548        return -1;
549    }
550
551    std::string service =
552            android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
553    std::string error;
554    int fd = adb_connect(service, &error);
555    if (fd < 0) {
556        // Try falling back to the older sideload method.  Maybe this
557        // is an older device that doesn't support sideload-host.
558        printf("\n");
559        status = adb_download_buffer("sideload", fn, data, sz, true);
560        goto done;
561    }
562
563    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
564
565    while (true) {
566        char buf[9];
567        if (!ReadFdExactly(fd, buf, 8)) {
568            fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
569            status = -1;
570            goto done;
571        }
572        buf[8] = '\0';
573
574        if (strcmp("DONEDONE", buf) == 0) {
575            status = 0;
576            break;
577        }
578
579        int block = strtol(buf, NULL, 10);
580
581        size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
582        if (offset >= sz) {
583            fprintf(stderr, "* attempt to read block %d past end\n", block);
584            status = -1;
585            goto done;
586        }
587        uint8_t* start = data + offset;
588        size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
589        size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
590        if (offset_end > sz) {
591            to_write = sz - offset;
592        }
593
594        if(!WriteFdExactly(fd, start, to_write)) {
595            adb_status(fd, &error);
596            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
597            status = -1;
598            goto done;
599        }
600        xfer += to_write;
601
602        // For normal OTA packages, we expect to transfer every byte
603        // twice, plus a bit of overhead (one read during
604        // verification, one read of each byte for installation, plus
605        // extra access to things like the zip central directory).
606        // This estimate of the completion becomes 100% when we've
607        // transferred ~2.13 (=100/47) times the package size.
608        int percent = (int)(xfer * 47LL / (sz ? sz : 1));
609        if (percent != last_percent) {
610            printf("\rserving: '%s'  (~%d%%)    ", fn, percent);
611            fflush(stdout);
612            last_percent = percent;
613        }
614    }
615
616    printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
617
618  done:
619    if (fd >= 0) adb_close(fd);
620    free(data);
621    return status;
622}
623
624/**
625 * Run ppp in "notty" mode against a resource listed as the first parameter
626 * eg:
627 *
628 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
629 *
630 */
631static int ppp(int argc, const char** argv) {
632#if defined(_WIN32)
633    fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
634    return -1;
635#else
636    if (argc < 2) {
637        fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
638                argv[0]);
639
640        return 1;
641    }
642
643    const char* adb_service_name = argv[1];
644    std::string error;
645    int fd = adb_connect(adb_service_name, &error);
646    if (fd < 0) {
647        fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
648                adb_service_name, error.c_str());
649        return 1;
650    }
651
652    pid_t pid = fork();
653
654    if (pid < 0) {
655        perror("from fork()");
656        return 1;
657    } else if (pid == 0) {
658        int err;
659        int i;
660        const char **ppp_args;
661
662        // copy args
663        ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
664        ppp_args[0] = "pppd";
665        for (i = 2 ; i < argc ; i++) {
666            //argv[2] and beyond become ppp_args[1] and beyond
667            ppp_args[i - 1] = argv[i];
668        }
669        ppp_args[i-1] = NULL;
670
671        // child side
672
673        dup2(fd, STDIN_FILENO);
674        dup2(fd, STDOUT_FILENO);
675        adb_close(STDERR_FILENO);
676        adb_close(fd);
677
678        err = execvp("pppd", (char * const *)ppp_args);
679
680        if (err < 0) {
681            perror("execing pppd");
682        }
683        exit(-1);
684    } else {
685        // parent side
686
687        adb_close(fd);
688        return 0;
689    }
690#endif /* !defined(_WIN32) */
691}
692
693static bool wait_for_device(const char* service, TransportType t, const char* serial) {
694    // Was the caller vague about what they'd like us to wait for?
695    // If so, check they weren't more specific in their choice of transport type.
696    if (strcmp(service, "wait-for-device") == 0) {
697        if (t == kTransportUsb) {
698            service = "wait-for-usb";
699        } else if (t == kTransportLocal) {
700            service = "wait-for-local";
701        } else {
702            service = "wait-for-any";
703        }
704    }
705
706    std::string cmd = format_host_command(service, t, serial);
707    return adb_command(cmd);
708}
709
710static int send_shell_command(TransportType transport_type, const char* serial,
711                              const std::string& command) {
712    int fd;
713    while (true) {
714        std::string error;
715        fd = adb_connect(command, &error);
716        if (fd >= 0) {
717            break;
718        }
719        fprintf(stderr,"- waiting for device -\n");
720        adb_sleep_ms(1000);
721        wait_for_device("wait-for-device", transport_type, serial);
722    }
723
724    read_and_dump(fd);
725    int rc = adb_close(fd);
726    if (rc) {
727        perror("close");
728    }
729    return rc;
730}
731
732static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
733    char* log_tags = getenv("ANDROID_LOG_TAGS");
734    std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
735
736    std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
737
738    if (!strcmp(argv[0], "longcat")) {
739        cmd += " -v long";
740    }
741
742    --argc;
743    ++argv;
744    while (argc-- > 0) {
745        cmd += " " + escape_arg(*argv++);
746    }
747
748    return send_shell_command(transport, serial, cmd);
749}
750
751static int backup(int argc, const char** argv) {
752    const char* filename = "./backup.ab";
753
754    /* find, extract, and use any -f argument */
755    for (int i = 1; i < argc; i++) {
756        if (!strcmp("-f", argv[i])) {
757            if (i == argc-1) {
758                fprintf(stderr, "adb: -f passed with no filename\n");
759                return usage();
760            }
761            filename = argv[i+1];
762            for (int j = i+2; j <= argc; ) {
763                argv[i++] = argv[j++];
764            }
765            argc -= 2;
766            argv[argc] = NULL;
767        }
768    }
769
770    /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
771    if (argc < 2) return usage();
772
773    adb_unlink(filename);
774    mkdirs(filename);
775    int outFd = adb_creat(filename, 0640);
776    if (outFd < 0) {
777        fprintf(stderr, "adb: unable to open file %s\n", filename);
778        return -1;
779    }
780
781    std::string cmd = "backup:";
782    --argc;
783    ++argv;
784    while (argc-- > 0) {
785        cmd += " " + escape_arg(*argv++);
786    }
787
788    D("backup. filename=%s cmd=%s", filename, cmd.c_str());
789    std::string error;
790    int fd = adb_connect(cmd, &error);
791    if (fd < 0) {
792        fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
793        adb_close(outFd);
794        return -1;
795    }
796
797    printf("Now unlock your device and confirm the backup operation.\n");
798    copy_to_file(fd, outFd);
799
800    adb_close(fd);
801    adb_close(outFd);
802    return 0;
803}
804
805static int restore(int argc, const char** argv) {
806    if (argc != 2) return usage();
807
808    const char* filename = argv[1];
809    int tarFd = adb_open(filename, O_RDONLY);
810    if (tarFd < 0) {
811        fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
812        return -1;
813    }
814
815    std::string error;
816    int fd = adb_connect("restore:", &error);
817    if (fd < 0) {
818        fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
819        adb_close(tarFd);
820        return -1;
821    }
822
823    printf("Now unlock your device and confirm the restore operation.\n");
824    copy_to_file(tarFd, fd);
825
826    adb_close(fd);
827    adb_close(tarFd);
828    return 0;
829}
830
831/* <hint> may be:
832 * - A simple product name
833 *   e.g., "sooner"
834 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
835 *   e.g., "out/target/product/sooner"
836 * - An absolute path to the PRODUCT_OUT dir
837 *   e.g., "/src/device/out/target/product/sooner"
838 *
839 * Given <hint>, try to construct an absolute path to the
840 * ANDROID_PRODUCT_OUT dir.
841 */
842static std::string find_product_out_path(const std::string& hint) {
843    if (hint.empty()) {
844        return "";
845    }
846
847    // If it's already absolute, don't bother doing any work.
848    if (adb_is_absolute_host_path(hint.c_str())) {
849        return hint;
850    }
851
852    // If there are any slashes in it, assume it's a relative path;
853    // make it absolute.
854    if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
855        std::string cwd;
856        if (!getcwd(&cwd)) {
857            fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
858            return "";
859        }
860        return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
861    }
862
863    // It's a string without any slashes.  Try to do something with it.
864    //
865    // Try to find the root of the build tree, and build a PRODUCT_OUT
866    // path from there.
867    char* top = getenv("ANDROID_BUILD_TOP");
868    if (top == nullptr) {
869        fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
870        return "";
871    }
872
873    std::string path = top;
874    path += OS_PATH_SEPARATOR_STR;
875    path += "out";
876    path += OS_PATH_SEPARATOR_STR;
877    path += "target";
878    path += OS_PATH_SEPARATOR_STR;
879    path += "product";
880    path += OS_PATH_SEPARATOR_STR;
881    path += hint;
882    if (!directory_exists(path)) {
883        fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
884                        "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
885        return "";
886    }
887    return path;
888}
889
890static void parse_push_pull_args(const char **arg, int narg, char const **path1,
891                                 char const **path2, bool* show_progress,
892                                 int *copy_attrs) {
893    *show_progress = false;
894    *copy_attrs = 0;
895
896    while (narg > 0) {
897        if (!strcmp(*arg, "-p")) {
898            *show_progress = true;
899        } else if (!strcmp(*arg, "-a")) {
900            *copy_attrs = 1;
901        } else {
902            break;
903        }
904        ++arg;
905        --narg;
906    }
907
908    if (narg > 0) {
909        *path1 = *arg;
910        ++arg;
911        --narg;
912    }
913
914    if (narg > 0) {
915        *path2 = *arg;
916    }
917}
918
919static int adb_connect_command(const std::string& command) {
920    std::string error;
921    int fd = adb_connect(command, &error);
922    if (fd < 0) {
923        fprintf(stderr, "error: %s\n", error.c_str());
924        return 1;
925    }
926    read_and_dump(fd);
927    adb_close(fd);
928    return 0;
929}
930
931static int adb_query_command(const std::string& command) {
932    std::string result;
933    std::string error;
934    if (!adb_query(command, &result, &error)) {
935        fprintf(stderr, "error: %s\n", error.c_str());
936        return 1;
937    }
938    printf("%s\n", result.c_str());
939    return 0;
940}
941
942// Disallow stdin, stdout, and stderr.
943static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
944#ifdef _WIN32
945    const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
946    return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
947           (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
948           (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
949#else
950    return ack_reply_fd > 2;
951#endif
952}
953
954int adb_commandline(int argc, const char **argv) {
955    int no_daemon = 0;
956    int is_daemon = 0;
957    int is_server = 0;
958    int r;
959    TransportType transport_type = kTransportAny;
960    int ack_reply_fd = -1;
961
962    // If defined, this should be an absolute path to
963    // the directory containing all of the various system images
964    // for a particular product.  If not defined, and the adb
965    // command requires this information, then the user must
966    // specify the path using "-p".
967    char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
968    if (ANDROID_PRODUCT_OUT != nullptr) {
969        gProductOutPath = ANDROID_PRODUCT_OUT;
970    }
971    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
972
973    const char* serial = getenv("ANDROID_SERIAL");
974
975    /* Validate and assign the server port */
976    const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
977    int server_port = DEFAULT_ADB_PORT;
978    if (server_port_str && strlen(server_port_str) > 0) {
979        server_port = strtol(server_port_str, nullptr, 0);
980        if (server_port <= 0 || server_port > 65535) {
981            fprintf(stderr,
982                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65536. Got \"%s\"\n",
983                    server_port_str);
984            return usage();
985        }
986    }
987
988    /* modifiers and flags */
989    while (argc > 0) {
990        if (!strcmp(argv[0],"server")) {
991            is_server = 1;
992        } else if (!strcmp(argv[0],"nodaemon")) {
993            no_daemon = 1;
994        } else if (!strcmp(argv[0], "fork-server")) {
995            /* this is a special flag used only when the ADB client launches the ADB Server */
996            is_daemon = 1;
997        } else if (!strcmp(argv[0], "--reply-fd")) {
998            if (argc < 2) return usage();
999            const char* reply_fd_str = argv[1];
1000            argc--;
1001            argv++;
1002            ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
1003            if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
1004                fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1005                return usage();
1006            }
1007        } else if (!strncmp(argv[0], "-p", 2)) {
1008            const char* product = nullptr;
1009            if (argv[0][2] == '\0') {
1010                if (argc < 2) return usage();
1011                product = argv[1];
1012                argc--;
1013                argv++;
1014            } else {
1015                product = argv[0] + 2;
1016            }
1017            gProductOutPath = find_product_out_path(product);
1018            if (gProductOutPath.empty()) {
1019                fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
1020                return usage();
1021            }
1022        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1023            if (isdigit(argv[0][2])) {
1024                serial = argv[0] + 2;
1025            } else {
1026                if (argc < 2 || argv[0][2] != '\0') return usage();
1027                serial = argv[1];
1028                argc--;
1029                argv++;
1030            }
1031        } else if (!strcmp(argv[0],"-d")) {
1032            transport_type = kTransportUsb;
1033        } else if (!strcmp(argv[0],"-e")) {
1034            transport_type = kTransportLocal;
1035        } else if (!strcmp(argv[0],"-a")) {
1036            gListenAll = 1;
1037        } else if (!strncmp(argv[0], "-H", 2)) {
1038            const char *hostname = NULL;
1039            if (argv[0][2] == '\0') {
1040                if (argc < 2) return usage();
1041                hostname = argv[1];
1042                argc--;
1043                argv++;
1044            } else {
1045                hostname = argv[0] + 2;
1046            }
1047            adb_set_tcp_name(hostname);
1048
1049        } else if (!strncmp(argv[0], "-P", 2)) {
1050            if (argv[0][2] == '\0') {
1051                if (argc < 2) return usage();
1052                server_port_str = argv[1];
1053                argc--;
1054                argv++;
1055            } else {
1056                server_port_str = argv[0] + 2;
1057            }
1058            if (strlen(server_port_str) > 0) {
1059                server_port = (int) strtol(server_port_str, NULL, 0);
1060                if (server_port <= 0 || server_port > 65535) {
1061                    fprintf(stderr,
1062                            "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1063                            server_port_str);
1064                    return usage();
1065                }
1066            } else {
1067                fprintf(stderr,
1068                "adb: port number must be a positive number less than 65536. Got empty string.\n");
1069                return usage();
1070            }
1071        } else {
1072                /* out of recognized modifiers and flags */
1073            break;
1074        }
1075        argc--;
1076        argv++;
1077    }
1078
1079    adb_set_transport(transport_type, serial);
1080    adb_set_tcp_specifics(server_port);
1081
1082    if (is_server) {
1083        if (no_daemon || is_daemon) {
1084            if (is_daemon && (ack_reply_fd == -1)) {
1085                fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1086                return usage();
1087            }
1088            r = adb_main(is_daemon, server_port, ack_reply_fd);
1089        } else {
1090            r = launch_server(server_port);
1091        }
1092        if (r) {
1093            fprintf(stderr,"* could not start server *\n");
1094        }
1095        return r;
1096    }
1097
1098    if (argc == 0) {
1099        return usage();
1100    }
1101
1102    /* handle wait-for-* prefix */
1103    if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1104        const char* service = argv[0];
1105
1106        if (!wait_for_device(service, transport_type, serial)) {
1107            return 1;
1108        }
1109
1110        // Allow a command to be run after wait-for-device,
1111        // e.g. 'adb wait-for-device shell'.
1112        if (argc == 1) {
1113            return 0;
1114        }
1115
1116        /* Fall through */
1117        argc--;
1118        argv++;
1119    }
1120
1121    /* adb_connect() commands */
1122    if (!strcmp(argv[0], "devices")) {
1123        const char *listopt;
1124        if (argc < 2) {
1125            listopt = "";
1126        } else if (argc == 2 && !strcmp(argv[1], "-l")) {
1127            listopt = argv[1];
1128        } else {
1129            fprintf(stderr, "Usage: adb devices [-l]\n");
1130            return 1;
1131        }
1132
1133        std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1134        printf("List of devices attached\n");
1135        return adb_query_command(query);
1136    }
1137    else if (!strcmp(argv[0], "connect")) {
1138        if (argc != 2) {
1139            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
1140            return 1;
1141        }
1142
1143        std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1144        return adb_query_command(query);
1145    }
1146    else if (!strcmp(argv[0], "disconnect")) {
1147        if (argc > 2) {
1148            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1149            return 1;
1150        }
1151
1152        std::string query = android::base::StringPrintf("host:disconnect:%s",
1153                                                        (argc == 2) ? argv[1] : "");
1154        return adb_query_command(query);
1155    }
1156    else if (!strcmp(argv[0], "emu")) {
1157        return adb_send_emulator_command(argc, argv, serial);
1158    }
1159    else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
1160        char h = (argv[0][0] == 'h');
1161
1162        if (h) {
1163            printf("\x1b[41;33m");
1164            fflush(stdout);
1165        }
1166
1167        if (argc < 2) {
1168            D("starting interactive shell");
1169            r = interactive_shell();
1170            if (h) {
1171                printf("\x1b[0m");
1172                fflush(stdout);
1173            }
1174            return r;
1175        }
1176
1177        std::string cmd = "shell:";
1178        --argc;
1179        ++argv;
1180        while (argc-- > 0) {
1181            // We don't escape here, just like ssh(1). http://b/20564385.
1182            cmd += *argv++;
1183            if (*argv) cmd += " ";
1184        }
1185
1186        while (true) {
1187            D("interactive shell loop. cmd=%s", cmd.c_str());
1188            std::string error;
1189            int fd = adb_connect(cmd, &error);
1190            int r;
1191            if (fd >= 0) {
1192                D("about to read_and_dump(fd=%d)", fd);
1193                read_and_dump(fd);
1194                D("read_and_dump() done.");
1195                adb_close(fd);
1196                r = 0;
1197            } else {
1198                fprintf(stderr,"error: %s\n", error.c_str());
1199                r = -1;
1200            }
1201
1202            if (h) {
1203                printf("\x1b[0m");
1204                fflush(stdout);
1205            }
1206            D("interactive shell loop. return r=%d", r);
1207            return r;
1208        }
1209    }
1210    else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
1211        int exec_in = !strcmp(argv[0], "exec-in");
1212
1213        std::string cmd = "exec:";
1214        cmd += argv[1];
1215        argc -= 2;
1216        argv += 2;
1217        while (argc-- > 0) {
1218            cmd += " " + escape_arg(*argv++);
1219        }
1220
1221        std::string error;
1222        int fd = adb_connect(cmd, &error);
1223        if (fd < 0) {
1224            fprintf(stderr, "error: %s\n", error.c_str());
1225            return -1;
1226        }
1227
1228        if (exec_in) {
1229            copy_to_file(STDIN_FILENO, fd);
1230        } else {
1231            copy_to_file(fd, STDOUT_FILENO);
1232        }
1233
1234        adb_close(fd);
1235        return 0;
1236    }
1237    else if (!strcmp(argv[0], "kill-server")) {
1238        std::string error;
1239        int fd = _adb_connect("host:kill", &error);
1240        if (fd == -2) {
1241            // Failed to make network connection to server. Don't output the
1242            // network error since that is expected.
1243            fprintf(stderr,"* server not running *\n");
1244            // Successful exit code because the server is already "killed".
1245            return 0;
1246        } else if (fd == -1) {
1247            // Some other error.
1248            fprintf(stderr, "error: %s\n", error.c_str());
1249            return 1;
1250        } else {
1251            // Successfully connected, kill command sent, okay status came back.
1252            // Server should exit() in a moment, if not already.
1253            adb_close(fd);
1254            return 0;
1255        }
1256    }
1257    else if (!strcmp(argv[0], "sideload")) {
1258        if (argc != 2) return usage();
1259        if (adb_sideload_host(argv[1])) {
1260            return 1;
1261        } else {
1262            return 0;
1263        }
1264    }
1265    else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1266        return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1267    }
1268    else if (!strcmp(argv[0], "remount") ||
1269             !strcmp(argv[0], "reboot") ||
1270             !strcmp(argv[0], "reboot-bootloader") ||
1271             !strcmp(argv[0], "usb") ||
1272             !strcmp(argv[0], "root") ||
1273             !strcmp(argv[0], "unroot") ||
1274             !strcmp(argv[0], "disable-verity") ||
1275             !strcmp(argv[0], "enable-verity")) {
1276        std::string command;
1277        if (!strcmp(argv[0], "reboot-bootloader")) {
1278            command = "reboot:bootloader";
1279        } else if (argc > 1) {
1280            command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
1281        } else {
1282            command = android::base::StringPrintf("%s:", argv[0]);
1283        }
1284        return adb_connect_command(command);
1285    }
1286    else if (!strcmp(argv[0], "bugreport")) {
1287        if (argc != 1) return usage();
1288        return send_shell_command(transport_type, serial, "shell:bugreport");
1289    }
1290    else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
1291        bool reverse = !strcmp(argv[0], "reverse");
1292        ++argv;
1293        --argc;
1294        if (argc < 1) return usage();
1295
1296        // Determine the <host-prefix> for this command.
1297        std::string host_prefix;
1298        if (reverse) {
1299            host_prefix = "reverse";
1300        } else {
1301            if (serial) {
1302                host_prefix = android::base::StringPrintf("host-serial:%s", serial);
1303            } else if (transport_type == kTransportUsb) {
1304                host_prefix = "host-usb";
1305            } else if (transport_type == kTransportLocal) {
1306                host_prefix = "host-local";
1307            } else {
1308                host_prefix = "host";
1309            }
1310        }
1311
1312        std::string cmd;
1313        if (strcmp(argv[0], "--list") == 0) {
1314            if (argc != 1) return usage();
1315            return adb_query_command(host_prefix + ":list-forward");
1316        } else if (strcmp(argv[0], "--remove-all") == 0) {
1317            if (argc != 1) return usage();
1318            cmd = host_prefix + ":killforward-all";
1319        } else if (strcmp(argv[0], "--remove") == 0) {
1320            // forward --remove <local>
1321            if (argc != 2) return usage();
1322            cmd = host_prefix + ":killforward:" + argv[1];
1323        } else if (strcmp(argv[0], "--no-rebind") == 0) {
1324            // forward --no-rebind <local> <remote>
1325            if (argc != 3) return usage();
1326            cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1327        } else {
1328            // forward <local> <remote>
1329            if (argc != 2) return usage();
1330            cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
1331        }
1332
1333        return adb_command(cmd) ? 0 : 1;
1334    }
1335    /* do_sync_*() commands */
1336    else if (!strcmp(argv[0], "ls")) {
1337        if (argc != 2) return usage();
1338        return do_sync_ls(argv[1]) ? 0 : 1;
1339    }
1340    else if (!strcmp(argv[0], "push")) {
1341        bool show_progress = false;
1342        int copy_attrs = 0;
1343        const char* lpath = NULL, *rpath = NULL;
1344
1345        parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
1346        if (!lpath || !rpath || copy_attrs != 0) return usage();
1347        return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
1348    }
1349    else if (!strcmp(argv[0], "pull")) {
1350        bool show_progress = false;
1351        int copy_attrs = 0;
1352        const char* rpath = NULL, *lpath = ".";
1353
1354        parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
1355        if (!rpath) return usage();
1356        return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
1357    }
1358    else if (!strcmp(argv[0], "install")) {
1359        if (argc < 2) return usage();
1360        return install_app(transport_type, serial, argc, argv);
1361    }
1362    else if (!strcmp(argv[0], "install-multiple")) {
1363        if (argc < 2) return usage();
1364        return install_multiple_app(transport_type, serial, argc, argv);
1365    }
1366    else if (!strcmp(argv[0], "uninstall")) {
1367        if (argc < 2) return usage();
1368        return uninstall_app(transport_type, serial, argc, argv);
1369    }
1370    else if (!strcmp(argv[0], "sync")) {
1371        std::string src;
1372        bool list_only = false;
1373        if (argc < 2) {
1374            // No local path was specified.
1375            src = "";
1376        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1377            list_only = true;
1378            if (argc == 3) {
1379                src = argv[2];
1380            } else {
1381                src = "";
1382            }
1383        } else if (argc == 2) {
1384            // A local path or "android"/"data" arg was specified.
1385            src = argv[1];
1386        } else {
1387            return usage();
1388        }
1389
1390        if (src != "" &&
1391            src != "system" && src != "data" && src != "vendor" && src != "oem") {
1392            return usage();
1393        }
1394
1395        std::string system_src_path = product_file("system");
1396        std::string data_src_path = product_file("data");
1397        std::string vendor_src_path = product_file("vendor");
1398        std::string oem_src_path = product_file("oem");
1399
1400        bool okay = true;
1401        if (okay && (src.empty() || src == "system")) {
1402            okay = do_sync_sync(system_src_path, "/system", list_only);
1403        }
1404        if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1405            okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
1406        }
1407        if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1408            okay = do_sync_sync(oem_src_path, "/oem", list_only);
1409        }
1410        if (okay && (src.empty() || src == "data")) {
1411            okay = do_sync_sync(data_src_path, "/data", list_only);
1412        }
1413        return okay ? 0 : 1;
1414    }
1415    /* passthrough commands */
1416    else if (!strcmp(argv[0],"get-state") ||
1417        !strcmp(argv[0],"get-serialno") ||
1418        !strcmp(argv[0],"get-devpath"))
1419    {
1420        return adb_query_command(format_host_command(argv[0], transport_type, serial));
1421    }
1422    /* other commands */
1423    else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
1424        return logcat(transport_type, serial, argc, argv);
1425    }
1426    else if (!strcmp(argv[0],"ppp")) {
1427        return ppp(argc, argv);
1428    }
1429    else if (!strcmp(argv[0], "start-server")) {
1430        std::string error;
1431        const int result = adb_connect("host:start-server", &error);
1432        if (result < 0) {
1433            fprintf(stderr, "error: %s\n", error.c_str());
1434        }
1435        return result;
1436    }
1437    else if (!strcmp(argv[0], "backup")) {
1438        return backup(argc, argv);
1439    }
1440    else if (!strcmp(argv[0], "restore")) {
1441        return restore(argc, argv);
1442    }
1443    else if (!strcmp(argv[0], "keygen")) {
1444        if (argc < 2) return usage();
1445        return adb_auth_keygen(argv[1]);
1446    }
1447    else if (!strcmp(argv[0], "jdwp")) {
1448        return adb_connect_command("jdwp");
1449    }
1450    /* "adb /?" is a common idiom under Windows */
1451    else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1452        help();
1453        return 0;
1454    }
1455    else if (!strcmp(argv[0], "version")) {
1456        fprintf(stdout, "%s", adb_version().c_str());
1457        return 0;
1458    }
1459    else if (!strcmp(argv[0], "features")) {
1460        return adb_query_command(format_host_command("features", transport_type, serial));
1461    }
1462
1463    usage();
1464    return 1;
1465}
1466
1467static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
1468    std::string cmd = "shell:pm";
1469
1470    while (argc-- > 0) {
1471        cmd += " " + escape_arg(*argv++);
1472    }
1473
1474    return send_shell_command(transport, serial, cmd);
1475}
1476
1477static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
1478    /* if the user choose the -k option, we refuse to do it until devices are
1479       out with the option to uninstall the remaining data somehow (adb/ui) */
1480    if (argc == 3 && strcmp(argv[1], "-k") == 0)
1481    {
1482        printf(
1483            "The -k option uninstalls the application while retaining the data/cache.\n"
1484            "At the moment, there is no way to remove the remaining data.\n"
1485            "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1486            "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1487        return -1;
1488    }
1489
1490    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1491    return pm_command(transport, serial, argc, argv);
1492}
1493
1494static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
1495    std::string cmd = "shell:rm -f " + escape_arg(filename);
1496    return send_shell_command(transport, serial, cmd);
1497}
1498
1499static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
1500    static const char *const DATA_DEST = "/data/local/tmp/%s";
1501    static const char *const SD_DEST = "/sdcard/tmp/%s";
1502    const char* where = DATA_DEST;
1503    int i;
1504    struct stat sb;
1505
1506    for (i = 1; i < argc; i++) {
1507        if (!strcmp(argv[i], "-s")) {
1508            where = SD_DEST;
1509        }
1510    }
1511
1512    // Find last APK argument.
1513    // All other arguments passed through verbatim.
1514    int last_apk = -1;
1515    for (i = argc - 1; i >= 0; i--) {
1516        const char* file = argv[i];
1517        const char* dot = strrchr(file, '.');
1518        if (dot && !strcasecmp(dot, ".apk")) {
1519            if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1520                fprintf(stderr, "Invalid APK file: %s\n", file);
1521                return -1;
1522            }
1523
1524            last_apk = i;
1525            break;
1526        }
1527    }
1528
1529    if (last_apk == -1) {
1530        fprintf(stderr, "Missing APK file\n");
1531        return -1;
1532    }
1533
1534    int result = -1;
1535    const char* apk_file = argv[last_apk];
1536    std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
1537    if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1538    argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1539    result = pm_command(transport, serial, argc, argv);
1540
1541cleanup_apk:
1542    delete_file(transport, serial, apk_dest);
1543    return result;
1544}
1545
1546static int install_multiple_app(TransportType transport, const char* serial, int argc,
1547                                const char** argv)
1548{
1549    int i;
1550    struct stat sb;
1551    uint64_t total_size = 0;
1552
1553    // Find all APK arguments starting at end.
1554    // All other arguments passed through verbatim.
1555    int first_apk = -1;
1556    for (i = argc - 1; i >= 0; i--) {
1557        const char* file = argv[i];
1558        const char* dot = strrchr(file, '.');
1559        if (dot && !strcasecmp(dot, ".apk")) {
1560            if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1561                fprintf(stderr, "Invalid APK file: %s\n", file);
1562                return -1;
1563            }
1564
1565            total_size += sb.st_size;
1566            first_apk = i;
1567        } else {
1568            break;
1569        }
1570    }
1571
1572    if (first_apk == -1) {
1573        fprintf(stderr, "Missing APK file\n");
1574        return 1;
1575    }
1576
1577    std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
1578    for (i = 1; i < first_apk; i++) {
1579        cmd += " " + escape_arg(argv[i]);
1580    }
1581
1582    // Create install session
1583    std::string error;
1584    int fd = adb_connect(cmd, &error);
1585    if (fd < 0) {
1586        fprintf(stderr, "Connect error for create: %s\n", error.c_str());
1587        return -1;
1588    }
1589    char buf[BUFSIZ];
1590    read_status_line(fd, buf, sizeof(buf));
1591    adb_close(fd);
1592
1593    int session_id = -1;
1594    if (!strncmp("Success", buf, 7)) {
1595        char* start = strrchr(buf, '[');
1596        char* end = strrchr(buf, ']');
1597        if (start && end) {
1598            *end = '\0';
1599            session_id = strtol(start + 1, NULL, 10);
1600        }
1601    }
1602    if (session_id < 0) {
1603        fprintf(stderr, "Failed to create session\n");
1604        fputs(buf, stderr);
1605        return -1;
1606    }
1607
1608    // Valid session, now stream the APKs
1609    int success = 1;
1610    for (i = first_apk; i < argc; i++) {
1611        const char* file = argv[i];
1612        if (stat(file, &sb) == -1) {
1613            fprintf(stderr, "Failed to stat %s\n", file);
1614            success = 0;
1615            goto finalize_session;
1616        }
1617
1618        std::string cmd = android::base::StringPrintf(
1619                "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
1620                static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
1621
1622        int localFd = adb_open(file, O_RDONLY);
1623        if (localFd < 0) {
1624            fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
1625            success = 0;
1626            goto finalize_session;
1627        }
1628
1629        std::string error;
1630        int remoteFd = adb_connect(cmd, &error);
1631        if (remoteFd < 0) {
1632            fprintf(stderr, "Connect error for write: %s\n", error.c_str());
1633            adb_close(localFd);
1634            success = 0;
1635            goto finalize_session;
1636        }
1637
1638        copy_to_file(localFd, remoteFd);
1639        read_status_line(remoteFd, buf, sizeof(buf));
1640
1641        adb_close(localFd);
1642        adb_close(remoteFd);
1643
1644        if (strncmp("Success", buf, 7)) {
1645            fprintf(stderr, "Failed to write %s\n", file);
1646            fputs(buf, stderr);
1647            success = 0;
1648            goto finalize_session;
1649        }
1650    }
1651
1652finalize_session:
1653    // Commit session if we streamed everything okay; otherwise abandon
1654    std::string service =
1655            android::base::StringPrintf("exec:pm install-%s %d",
1656                                        success ? "commit" : "abandon", session_id);
1657    fd = adb_connect(service, &error);
1658    if (fd < 0) {
1659        fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
1660        return -1;
1661    }
1662    read_status_line(fd, buf, sizeof(buf));
1663    adb_close(fd);
1664
1665    if (!strncmp("Success", buf, 7)) {
1666        fputs(buf, stderr);
1667        return 0;
1668    } else {
1669        fprintf(stderr, "Failed to finalize session\n");
1670        fputs(buf, stderr);
1671        return -1;
1672    }
1673}
1674