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