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