commandline.cpp revision 0e42c2a4ad06be7601377da0b3abc2cc2ad86cbf
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 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 <memory>
35#include <string>
36#include <vector>
37
38#include <base/logging.h>
39#include <base/stringprintf.h>
40#include <base/strings.h>
41
42#if !defined(_WIN32)
43#include <signal.h>
44#include <sys/ioctl.h>
45#include <termios.h>
46#include <unistd.h>
47#endif
48
49#include "adb.h"
50#include "adb_auth.h"
51#include "adb_client.h"
52#include "adb_io.h"
53#include "adb_utils.h"
54#include "file_sync_service.h"
55#include "services.h"
56#include "shell_service.h"
57#include "transport.h"
58
59static int install_app(TransportType t, const char* serial, int argc, const char** argv);
60static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
61static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
62static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
63static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
64
65static std::string gProductOutPath;
66extern int gListenAll;
67
68static std::string product_file(const char *extra) {
69    if (gProductOutPath.empty()) {
70        fprintf(stderr, "adb: Product directory not specified; "
71                "use -p or define ANDROID_PRODUCT_OUT\n");
72        exit(1);
73    }
74
75    return android::base::StringPrintf("%s%s%s",
76                                       gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
77}
78
79static void help() {
80    fprintf(stderr, "%s\n", adb_version().c_str());
81    fprintf(stderr,
82        " -a                            - directs adb to listen on all interfaces for a connection\n"
83        " -d                            - directs command to the only connected USB device\n"
84        "                                 returns an error if more than one USB device is present.\n"
85        " -e                            - directs command to the only running emulator.\n"
86        "                                 returns an error if more than one emulator is running.\n"
87        " -s <specific device>          - directs command to the device or emulator with the given\n"
88        "                                 serial number or qualifier. Overrides ANDROID_SERIAL\n"
89        "                                 environment variable.\n"
90        " -p <product name or path>     - simple product name like 'sooner', or\n"
91        "                                 a relative/absolute path to a product\n"
92        "                                 out directory like 'out/target/product/sooner'.\n"
93        "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
94        "                                 environment variable is used, which must\n"
95        "                                 be an absolute path.\n"
96        " -H                            - Name of adb server host (default: localhost)\n"
97        " -P                            - Port of adb server (default: 5037)\n"
98        " devices [-l]                  - list all connected devices\n"
99        "                                 ('-l' will also list device qualifiers)\n"
100        " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
101        "                                 Port 5555 is used by default if no port number is specified.\n"
102        " disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.\n"
103        "                                 Port 5555 is used by default if no port number is specified.\n"
104        "                                 Using this command with no additional arguments\n"
105        "                                 will disconnect from all connected TCP/IP devices.\n"
106        "\n"
107        "device commands:\n"
108        "  adb push <local>... <remote>\n"
109        "                               - copy files/dirs to device\n"
110        "  adb pull [-a] <remote>... <local>\n"
111        "                               - copy files/dirs from device\n"
112        "                                 (-a preserves file timestamp and mode)\n"
113        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
114        "                                 (-l means list but don't copy)\n"
115        "  adb shell [-e escape] [-Tt] [-x] [command]\n"
116        "                               - run remote shell command (interactive shell if no command given)\n"
117        "                                 (-e: choose escape character, or \"none\"; default '~')\n"
118        "                                 (-T: disable PTY allocation)\n"
119        "                                 (-t: force PTY allocation)\n"
120        "                                 (-x: disable remote exit codes and stdout/stderr separation)\n"
121        "  adb emu <command>            - run emulator console command\n"
122        "  adb logcat [ <filter-spec> ] - View device log\n"
123        "  adb forward --list           - list all forward socket connections.\n"
124        "                                 the format is a list of lines with the following format:\n"
125        "                                    <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
126        "  adb forward <local> <remote> - forward socket connections\n"
127        "                                 forward specs are one of: \n"
128        "                                   tcp:<port>\n"
129        "                                   localabstract:<unix domain socket name>\n"
130        "                                   localreserved:<unix domain socket name>\n"
131        "                                   localfilesystem:<unix domain socket name>\n"
132        "                                   dev:<character device name>\n"
133        "                                   jdwp:<process pid> (remote only)\n"
134        "  adb forward --no-rebind <local> <remote>\n"
135        "                               - same as 'adb forward <local> <remote>' but fails\n"
136        "                                 if <local> is already forwarded\n"
137        "  adb forward --remove <local> - remove a specific forward socket connection\n"
138        "  adb forward --remove-all     - remove all forward socket connections\n"
139        "  adb reverse --list           - list all reverse socket connections from device\n"
140        "  adb reverse <remote> <local> - reverse socket connections\n"
141        "                                 reverse specs are one of:\n"
142        "                                   tcp:<port>\n"
143        "                                   localabstract:<unix domain socket name>\n"
144        "                                   localreserved:<unix domain socket name>\n"
145        "                                   localfilesystem:<unix domain socket name>\n"
146        "  adb reverse --no-rebind <remote> <local>\n"
147        "                               - same as 'adb reverse <remote> <local>' but fails\n"
148        "                                 if <remote> is already reversed.\n"
149        "  adb reverse --remove <remote>\n"
150        "                               - remove a specific reversed socket connection\n"
151        "  adb reverse --remove-all     - remove all reversed socket connections from device\n"
152        "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
153        "  adb install [-lrtsdg] <file>\n"
154        "                               - push this package file to the device and install it\n"
155        "                                 (-l: forward lock application)\n"
156        "                                 (-r: replace existing application)\n"
157        "                                 (-t: allow test packages)\n"
158        "                                 (-s: install application on sdcard)\n"
159        "                                 (-d: allow version code downgrade)\n"
160        "                                 (-g: grant all runtime permissions)\n"
161        "  adb install-multiple [-lrtsdpg] <file...>\n"
162        "                               - push this package file to the device and install it\n"
163        "                                 (-l: forward lock application)\n"
164        "                                 (-r: replace existing application)\n"
165        "                                 (-t: allow test packages)\n"
166        "                                 (-s: install application on sdcard)\n"
167        "                                 (-d: allow version code downgrade)\n"
168        "                                 (-p: partial application install)\n"
169        "                                 (-g: grant all runtime permissions)\n"
170        "  adb uninstall [-k] <package> - remove this app package from the device\n"
171        "                                 ('-k' means keep the data and cache directories)\n"
172        "  adb bugreport                - return all information from the device\n"
173        "                                 that should be included in a bug report.\n"
174        "\n"
175        "  adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
176        "                               - write an archive of the device's data to <file>.\n"
177        "                                 If no -f option is supplied then the data is written\n"
178        "                                 to \"backup.ab\" in the current directory.\n"
179        "                                 (-apk|-noapk enable/disable backup of the .apks themselves\n"
180        "                                    in the archive; the default is noapk.)\n"
181        "                                 (-obb|-noobb enable/disable backup of any installed apk expansion\n"
182        "                                    (aka .obb) files associated with each application; the default\n"
183        "                                    is noobb.)\n"
184        "                                 (-shared|-noshared enable/disable backup of the device's\n"
185        "                                    shared storage / SD card contents; the default is noshared.)\n"
186        "                                 (-all means to back up all installed applications)\n"
187        "                                 (-system|-nosystem toggles whether -all automatically includes\n"
188        "                                    system applications; the default is to include system apps)\n"
189        "                                 (<packages...> is the list of applications to be backed up.  If\n"
190        "                                    the -all or -shared flags are passed, then the package\n"
191        "                                    list is optional.  Applications explicitly given on the\n"
192        "                                    command line will be included even if -nosystem would\n"
193        "                                    ordinarily cause them to be omitted.)\n"
194        "\n"
195        "  adb restore <file>           - restore device contents from the <file> backup archive\n"
196        "\n"
197        "  adb disable-verity           - disable dm-verity checking on USERDEBUG builds\n"
198        "  adb enable-verity            - re-enable dm-verity checking on USERDEBUG builds\n"
199        "  adb keygen <file>            - generate adb public/private key. The private key is stored in <file>,\n"
200        "                                 and the public key is stored in <file>.pub. Any existing files\n"
201        "                                 are overwritten.\n"
202        "  adb help                     - show this help message\n"
203        "  adb version                  - show version num\n"
204        "\n"
205        "scripting:\n"
206        "  adb wait-for-device          - block until device is online\n"
207        "  adb start-server             - ensure that there is a server running\n"
208        "  adb kill-server              - kill the server if it is running\n"
209        "  adb get-state                - prints: offline | bootloader | device\n"
210        "  adb get-serialno             - prints: <serial-number>\n"
211        "  adb get-devpath              - prints: <device-path>\n"
212        "  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
213        "  adb reboot [bootloader|recovery]\n"
214        "                               - reboots the device, optionally into the bootloader or recovery program.\n"
215        "  adb reboot sideload          - reboots the device into the sideload mode in recovery program (adb root required).\n"
216        "  adb reboot sideload-auto-reboot\n"
217        "                               - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
218        "  adb sideload <file>          - sideloads the given package\n"
219        "  adb root                     - restarts the adbd daemon with root permissions\n"
220        "  adb unroot                   - restarts the adbd daemon without root permissions\n"
221        "  adb usb                      - restarts the adbd daemon listening on USB\n"
222        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port\n"
223        "\n"
224        "networking:\n"
225        "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
226        " Note: you should not automatically start a PPP connection.\n"
227        " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
228        " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
229        "\n"
230        "adb sync notes: adb sync [ <directory> ]\n"
231        "  <localdir> can be interpreted in several ways:\n"
232        "\n"
233        "  - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.\n"
234        "\n"
235        "  - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
236        "    is updated.\n"
237        "\n"
238        "environment variables:\n"
239        "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
240        "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
241        "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
242        "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
243        );
244}
245
246static int usage() {
247    help();
248    return 1;
249}
250
251#if defined(_WIN32)
252
253// Implemented in sysdeps_win32.cpp.
254void stdin_raw_init();
255void stdin_raw_restore();
256
257#else
258static termios g_saved_terminal_state;
259
260static void stdin_raw_init() {
261    if (tcgetattr(STDIN_FILENO, &g_saved_terminal_state)) return;
262
263    termios tio;
264    if (tcgetattr(STDIN_FILENO, &tio)) return;
265
266    cfmakeraw(&tio);
267
268    // No timeout but request at least one character per read.
269    tio.c_cc[VTIME] = 0;
270    tio.c_cc[VMIN] = 1;
271
272    tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
273}
274
275static void stdin_raw_restore() {
276    tcsetattr(STDIN_FILENO, TCSAFLUSH, &g_saved_terminal_state);
277}
278#endif
279
280// Reads from |fd| and prints received data. If |use_shell_protocol| is true
281// this expects that incoming data will use the shell protocol, in which case
282// stdout/stderr are routed independently and the remote exit code will be
283// returned.
284static int read_and_dump(int fd, bool use_shell_protocol=false) {
285    int exit_code = 0;
286    std::unique_ptr<ShellProtocol> protocol;
287    int length = 0;
288    FILE* outfile = stdout;
289
290    char raw_buffer[BUFSIZ];
291    char* buffer_ptr = raw_buffer;
292    if (use_shell_protocol) {
293        protocol.reset(new ShellProtocol(fd));
294        if (!protocol) {
295            LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
296            return 1;
297        }
298        buffer_ptr = protocol->data();
299    }
300
301    while (fd >= 0) {
302        if (use_shell_protocol) {
303            if (!protocol->Read()) {
304                break;
305            }
306            switch (protocol->id()) {
307                case ShellProtocol::kIdStdout:
308                    outfile = stdout;
309                    break;
310                case ShellProtocol::kIdStderr:
311                    outfile = stderr;
312                    break;
313                case ShellProtocol::kIdExit:
314                    exit_code = protocol->data()[0];
315                    continue;
316                default:
317                    continue;
318            }
319            length = protocol->data_length();
320        } else {
321            D("read_and_dump(): pre adb_read(fd=%d)", fd);
322            length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
323            D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
324            if (length <= 0) {
325                break;
326            }
327        }
328
329        fwrite(buffer_ptr, 1, length, outfile);
330        fflush(outfile);
331    }
332
333    return exit_code;
334}
335
336static void read_status_line(int fd, char* buf, size_t count)
337{
338    count--;
339    while (count > 0) {
340        int len = adb_read(fd, buf, count);
341        if (len <= 0) {
342            break;
343        }
344
345        buf += len;
346        count -= len;
347    }
348    *buf = '\0';
349}
350
351static void copy_to_file(int inFd, int outFd) {
352    const size_t BUFSIZE = 32 * 1024;
353    char* buf = (char*) malloc(BUFSIZE);
354    if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
355    int len;
356    long total = 0;
357#ifdef _WIN32
358    int old_stdin_mode = -1;
359    int old_stdout_mode = -1;
360#endif
361
362    D("copy_to_file(%d -> %d)", inFd, outFd);
363
364    if (inFd == STDIN_FILENO) {
365        stdin_raw_init();
366#ifdef _WIN32
367        old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
368        if (old_stdin_mode == -1) {
369            fatal_errno("could not set stdin to binary");
370        }
371#endif
372    }
373
374#ifdef _WIN32
375    if (outFd == STDOUT_FILENO) {
376        old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
377        if (old_stdout_mode == -1) {
378            fatal_errno("could not set stdout to binary");
379        }
380    }
381#endif
382
383    while (true) {
384        if (inFd == STDIN_FILENO) {
385            len = unix_read(inFd, buf, BUFSIZE);
386        } else {
387            len = adb_read(inFd, buf, BUFSIZE);
388        }
389        if (len == 0) {
390            D("copy_to_file() : read 0 bytes; exiting");
391            break;
392        }
393        if (len < 0) {
394            D("copy_to_file(): read failed: %s", strerror(errno));
395            break;
396        }
397        if (outFd == STDOUT_FILENO) {
398            fwrite(buf, 1, len, stdout);
399            fflush(stdout);
400        } else {
401            adb_write(outFd, buf, len);
402        }
403        total += len;
404    }
405
406    if (inFd == STDIN_FILENO) {
407        stdin_raw_restore();
408#ifdef _WIN32
409        if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
410            fatal_errno("could not restore stdin mode");
411        }
412#endif
413    }
414
415#ifdef _WIN32
416    if (outFd == STDOUT_FILENO) {
417        if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
418            fatal_errno("could not restore stdout mode");
419        }
420    }
421#endif
422
423    D("copy_to_file() finished after %lu bytes", total);
424    free(buf);
425}
426
427static std::string format_host_command(const char* command,
428                                       TransportType type, const char* serial) {
429    if (serial) {
430        return android::base::StringPrintf("host-serial:%s:%s", serial, command);
431    }
432
433    const char* prefix = "host";
434    if (type == kTransportUsb) {
435        prefix = "host-usb";
436    } else if (type == kTransportLocal) {
437        prefix = "host-local";
438    }
439    return android::base::StringPrintf("%s:%s", prefix, command);
440}
441
442// Returns the FeatureSet for the indicated transport.
443static FeatureSet GetFeatureSet(TransportType transport_type, const char* serial) {
444    std::string result, error;
445    if (adb_query(format_host_command("features", transport_type, serial), &result, &error)) {
446        return StringToFeatureSet(result);
447    }
448    return FeatureSet();
449}
450
451static void send_window_size_change(int fd, std::unique_ptr<ShellProtocol>& shell) {
452#if !defined(_WIN32)
453    // Old devices can't handle window size changes.
454    if (shell == nullptr) return;
455
456    winsize ws;
457    if (ioctl(fd, TIOCGWINSZ, &ws) == -1) return;
458
459    // Send the new window size as human-readable ASCII for debugging convenience.
460    size_t l = snprintf(shell->data(), shell->data_capacity(), "%dx%d,%dx%d",
461                        ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
462    shell->Write(ShellProtocol::kIdWindowSizeChange, l + 1);
463#endif
464}
465
466// Used to pass multiple values to the stdin read thread.
467struct StdinReadArgs {
468    int stdin_fd, write_fd;
469    bool raw_stdin;
470    std::unique_ptr<ShellProtocol> protocol;
471};
472
473// Loops to read from stdin and push the data to the given FD.
474// The argument should be a pointer to a StdinReadArgs object. This function
475// will take ownership of the object and delete it when finished.
476static void* stdin_read_thread_loop(void* x) {
477    std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
478    int state = 0;
479
480#if !defined(_WIN32)
481    // Mask SIGTTIN in case we're in a backgrounded process.
482    sigset_t sigset;
483    sigemptyset(&sigset);
484    sigaddset(&sigset, SIGTTIN);
485    pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
486#endif
487
488#if !defined(_WIN32)
489    // Unblock SIGWINCH for this thread, so our read(2) below will be
490    // interrupted if the window size changes.
491    sigset_t mask;
492    sigemptyset(&mask);
493    sigaddset(&mask, SIGWINCH);
494    pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
495#endif
496
497    // Set up the initial window size.
498    send_window_size_change(args->stdin_fd, args->protocol);
499
500    char raw_buffer[1024];
501    char* buffer_ptr = raw_buffer;
502    size_t buffer_size = sizeof(raw_buffer);
503    if (args->protocol != nullptr) {
504        buffer_ptr = args->protocol->data();
505        buffer_size = args->protocol->data_capacity();
506    }
507
508    while (true) {
509        // Use unix_read() rather than adb_read() for stdin.
510        D("stdin_read_thread_loop(): pre unix_read(fdi=%d,...)", args->stdin_fd);
511#if !defined(_WIN32)
512#undef read
513        int r = read(args->stdin_fd, buffer_ptr, buffer_size);
514        if (r == -1 && errno == EINTR) {
515            send_window_size_change(args->stdin_fd, args->protocol);
516            continue;
517        }
518#define read ___xxx_read
519#else
520        int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
521#endif
522        D("stdin_read_thread_loop(): post unix_read(fdi=%d,...)", args->stdin_fd);
523        if (r <= 0) {
524            // Only devices using the shell protocol know to close subprocess
525            // stdin. For older devices we want to just leave the connection
526            // open, otherwise an unpredictable amount of return data could
527            // be lost due to the FD closing before all data has been received.
528            if (args->protocol) {
529                args->protocol->Write(ShellProtocol::kIdCloseStdin, 0);
530            }
531            break;
532        }
533        // If we made stdin raw, check input for the "~." escape sequence. In
534        // this situation signals like Ctrl+C are sent remotely rather than
535        // interpreted locally so this provides an emergency out if the remote
536        // process starts ignoring the signal. SSH also does this, see the
537        // "escape characters" section on the ssh man page for more info.
538        if (args->raw_stdin) {
539            for (int n = 0; n < r; n++) {
540                switch (buffer_ptr[n]) {
541                case '\n':
542                    state = 1;
543                    break;
544                case '\r':
545                    state = 1;
546                    break;
547                case '~':
548                    if (state == 1) {
549                        state++;
550                    } else {
551                        state = 0;
552                    }
553                    break;
554                case '.':
555                    if (state == 2) {
556                        fprintf(stderr,"\r\n* disconnect *\r\n");
557                        stdin_raw_restore();
558                        exit(0);
559                    }
560                default:
561                    state = 0;
562                }
563            }
564        }
565        if (args->protocol) {
566            if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
567                break;
568            }
569        } else {
570            if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
571                break;
572            }
573        }
574    }
575
576    return nullptr;
577}
578
579// Returns a shell service string with the indicated arguments and command.
580static std::string ShellServiceString(bool use_shell_protocol,
581                                      const std::string& type_arg,
582                                      const std::string& command) {
583    std::vector<std::string> args;
584    if (use_shell_protocol) {
585        args.push_back(kShellServiceArgShellProtocol);
586    }
587    if (!type_arg.empty()) {
588        args.push_back(type_arg);
589    }
590
591    // Shell service string can look like: shell[,arg1,arg2,...]:[command].
592    return android::base::StringPrintf("shell%s%s:%s",
593                                       args.empty() ? "" : ",",
594                                       android::base::Join(args, ',').c_str(),
595                                       command.c_str());
596}
597
598// Connects to a shell on the device and read/writes data.
599//
600// Note: currently this function doesn't properly clean up resources; the
601// FD connected to the adb server is never closed and the stdin read thread
602// may never exit.
603//
604// On success returns the remote exit code if |use_shell_protocol| is true,
605// 0 otherwise. On failure returns 1.
606static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
607                       const std::string& command) {
608    std::string service_string = ShellServiceString(use_shell_protocol,
609                                                    type_arg, command);
610
611    // Make local stdin raw if the device allocates a PTY, which happens if:
612    //   1. We are explicitly asking for a PTY shell, or
613    //   2. We don't specify shell type and are starting an interactive session.
614    bool raw_stdin = (type_arg == kShellServiceArgPty ||
615                      (type_arg.empty() && command.empty()));
616
617    std::string error;
618    int fd = adb_connect(service_string, &error);
619    if (fd < 0) {
620        fprintf(stderr,"error: %s\n", error.c_str());
621        return 1;
622    }
623
624    StdinReadArgs* args = new StdinReadArgs;
625    if (!args) {
626        LOG(ERROR) << "couldn't allocate StdinReadArgs object";
627        return 1;
628    }
629    args->stdin_fd = STDIN_FILENO;
630    args->write_fd = fd;
631    args->raw_stdin = raw_stdin;
632    if (use_shell_protocol) {
633        args->protocol.reset(new ShellProtocol(args->write_fd));
634    }
635
636    if (raw_stdin) stdin_raw_init();
637
638#if !defined(_WIN32)
639    // Ensure our process is notified if the local window size changes.
640    // We use sigaction(2) to ensure that the SA_RESTART flag is not set,
641    // because the whole reason we're sending signals is to unblock the read(2)!
642    // That also means we don't need to do anything in the signal handler:
643    // the side effect of delivering the signal is all we need.
644    struct sigaction sa;
645    memset(&sa, 0, sizeof(sa));
646    sa.sa_handler = [](int) {};
647    sa.sa_flags = 0;
648    sigaction(SIGWINCH, &sa, nullptr);
649
650    // Now block SIGWINCH in this thread (the main thread) and all threads spawned
651    // from it. The stdin read thread will unblock this signal to ensure that it's
652    // the thread that receives the signal.
653    sigset_t mask;
654    sigemptyset(&mask);
655    sigaddset(&mask, SIGWINCH);
656    pthread_sigmask(SIG_BLOCK, &mask, nullptr);
657#endif
658
659    // TODO: combine read_and_dump with stdin_read_thread to make life simpler?
660    int exit_code = 1;
661    if (!adb_thread_create(stdin_read_thread_loop, args)) {
662        PLOG(ERROR) << "error starting stdin read thread";
663        delete args;
664    } else {
665        exit_code = read_and_dump(fd, use_shell_protocol);
666    }
667
668    // TODO: properly exit stdin_read_thread_loop and close |fd|.
669
670    // TODO: we should probably install signal handlers for this.
671    // TODO: can we use atexit? even on Windows?
672    if (raw_stdin) stdin_raw_restore();
673
674    return exit_code;
675}
676
677static int adb_shell(int argc, const char** argv,
678                     TransportType transport_type, const char* serial) {
679    FeatureSet features = GetFeatureSet(transport_type, serial);
680
681    bool use_shell_protocol = CanUseFeature(features, kFeatureShell2);
682    if (!use_shell_protocol) {
683        D("shell protocol not supported, using raw data transfer");
684    } else {
685        D("using shell protocol");
686    }
687
688    // Parse shell-specific command-line options.
689    // argv[0] is always "shell".
690    --argc;
691    ++argv;
692    int t_arg_count = 0;
693    while (argc) {
694        if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
695            if (!CanUseFeature(features, kFeatureShell2)) {
696                fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
697                return 1;
698            }
699            // Like ssh, -t arguments are cumulative so that multiple -t's
700            // are needed to force a PTY.
701            if (argv[0][1] == 't') {
702                ++t_arg_count;
703            } else {
704                t_arg_count = -1;
705            }
706            --argc;
707            ++argv;
708        } else if (!strcmp(argv[0], "-x")) {
709            use_shell_protocol = false;
710            --argc;
711            ++argv;
712        } else {
713            break;
714        }
715    }
716
717    std::string shell_type_arg;
718    if (CanUseFeature(features, kFeatureShell2)) {
719        if (t_arg_count < 0) {
720            shell_type_arg = kShellServiceArgRaw;
721        } else if (t_arg_count == 0) {
722            // If stdin isn't a TTY, default to a raw shell; this lets
723            // things like `adb shell < my_script.sh` work as expected.
724            // Otherwise leave |shell_type_arg| blank which uses PTY for
725            // interactive shells and raw for non-interactive.
726            if (!unix_isatty(STDIN_FILENO)) {
727                shell_type_arg = kShellServiceArgRaw;
728            }
729        } else if (t_arg_count == 1) {
730            // A single -t arg isn't enough to override implicit -T.
731            if (!unix_isatty(STDIN_FILENO)) {
732                fprintf(stderr,
733                        "Remote PTY will not be allocated because stdin is not a terminal.\n"
734                        "Use multiple -t options to force remote PTY allocation.\n");
735                shell_type_arg = kShellServiceArgRaw;
736            } else {
737                shell_type_arg = kShellServiceArgPty;
738            }
739        } else {
740            shell_type_arg = kShellServiceArgPty;
741        }
742    }
743
744    std::string command;
745    if (argc) {
746        // We don't escape here, just like ssh(1). http://b/20564385.
747        command = android::base::Join(std::vector<const char*>(argv, argv + argc), ' ');
748    }
749
750    return RemoteShell(use_shell_protocol, shell_type_arg, command);
751}
752
753static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
754                               bool show_progress)
755{
756    std::string error;
757    int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
758    if (fd < 0) {
759        fprintf(stderr,"error: %s\n", error.c_str());
760        return -1;
761    }
762
763    int opt = CHUNK_SIZE;
764    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
765
766    unsigned total = sz;
767    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
768
769    if (show_progress) {
770        const char* x = strrchr(service, ':');
771        if (x) service = x + 1;
772    }
773
774    while (sz > 0) {
775        unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
776        if (!WriteFdExactly(fd, ptr, xfer)) {
777            std::string error;
778            adb_status(fd, &error);
779            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
780            adb_close(fd);
781            return -1;
782        }
783        sz -= xfer;
784        ptr += xfer;
785        if (show_progress) {
786            printf("sending: '%s' %4d%%    \r", fn, (int)(100LL - ((100LL * sz) / (total))));
787            fflush(stdout);
788        }
789    }
790    if (show_progress) {
791        printf("\n");
792    }
793
794    if (!adb_status(fd, &error)) {
795        fprintf(stderr,"* error response '%s' *\n", error.c_str());
796        adb_close(fd);
797        return -1;
798    }
799
800    adb_close(fd);
801    return 0;
802}
803
804#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
805
806/*
807 * The sideload-host protocol serves the data in a file (given on the
808 * command line) to the client, using a simple protocol:
809 *
810 * - The connect message includes the total number of bytes in the
811 *   file and a block size chosen by us.
812 *
813 * - The other side sends the desired block number as eight decimal
814 *   digits (eg "00000023" for block 23).  Blocks are numbered from
815 *   zero.
816 *
817 * - We send back the data of the requested block.  The last block is
818 *   likely to be partial; when the last block is requested we only
819 *   send the part of the block that exists, it's not padded up to the
820 *   block size.
821 *
822 * - When the other side sends "DONEDONE" instead of a block number,
823 *   we hang up.
824 */
825static int adb_sideload_host(const char* fn) {
826    unsigned sz;
827    size_t xfer = 0;
828    int status;
829    int last_percent = -1;
830    int opt = SIDELOAD_HOST_BLOCK_SIZE;
831
832    printf("loading: '%s'", fn);
833    fflush(stdout);
834    uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
835    if (data == 0) {
836        printf("\n");
837        fprintf(stderr, "* cannot read '%s' *\n", fn);
838        return -1;
839    }
840
841    std::string service =
842            android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
843    std::string error;
844    int fd = adb_connect(service, &error);
845    if (fd < 0) {
846        // Try falling back to the older sideload method.  Maybe this
847        // is an older device that doesn't support sideload-host.
848        printf("\n");
849        status = adb_download_buffer("sideload", fn, data, sz, true);
850        goto done;
851    }
852
853    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
854
855    while (true) {
856        char buf[9];
857        if (!ReadFdExactly(fd, buf, 8)) {
858            fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
859            status = -1;
860            goto done;
861        }
862        buf[8] = '\0';
863
864        if (strcmp("DONEDONE", buf) == 0) {
865            status = 0;
866            break;
867        }
868
869        int block = strtol(buf, NULL, 10);
870
871        size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
872        if (offset >= sz) {
873            fprintf(stderr, "* attempt to read block %d past end\n", block);
874            status = -1;
875            goto done;
876        }
877        uint8_t* start = data + offset;
878        size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
879        size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
880        if (offset_end > sz) {
881            to_write = sz - offset;
882        }
883
884        if(!WriteFdExactly(fd, start, to_write)) {
885            adb_status(fd, &error);
886            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
887            status = -1;
888            goto done;
889        }
890        xfer += to_write;
891
892        // For normal OTA packages, we expect to transfer every byte
893        // twice, plus a bit of overhead (one read during
894        // verification, one read of each byte for installation, plus
895        // extra access to things like the zip central directory).
896        // This estimate of the completion becomes 100% when we've
897        // transferred ~2.13 (=100/47) times the package size.
898        int percent = (int)(xfer * 47LL / (sz ? sz : 1));
899        if (percent != last_percent) {
900            printf("\rserving: '%s'  (~%d%%)    ", fn, percent);
901            fflush(stdout);
902            last_percent = percent;
903        }
904    }
905
906    printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
907
908  done:
909    if (fd >= 0) adb_close(fd);
910    free(data);
911    return status;
912}
913
914/**
915 * Run ppp in "notty" mode against a resource listed as the first parameter
916 * eg:
917 *
918 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
919 *
920 */
921static int ppp(int argc, const char** argv) {
922#if defined(_WIN32)
923    fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
924    return -1;
925#else
926    if (argc < 2) {
927        fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
928                argv[0]);
929
930        return 1;
931    }
932
933    const char* adb_service_name = argv[1];
934    std::string error;
935    int fd = adb_connect(adb_service_name, &error);
936    if (fd < 0) {
937        fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
938                adb_service_name, error.c_str());
939        return 1;
940    }
941
942    pid_t pid = fork();
943
944    if (pid < 0) {
945        perror("from fork()");
946        return 1;
947    } else if (pid == 0) {
948        int err;
949        int i;
950        const char **ppp_args;
951
952        // copy args
953        ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
954        ppp_args[0] = "pppd";
955        for (i = 2 ; i < argc ; i++) {
956            //argv[2] and beyond become ppp_args[1] and beyond
957            ppp_args[i - 1] = argv[i];
958        }
959        ppp_args[i-1] = NULL;
960
961        // child side
962
963        dup2(fd, STDIN_FILENO);
964        dup2(fd, STDOUT_FILENO);
965        adb_close(STDERR_FILENO);
966        adb_close(fd);
967
968        err = execvp("pppd", (char * const *)ppp_args);
969
970        if (err < 0) {
971            perror("execing pppd");
972        }
973        exit(-1);
974    } else {
975        // parent side
976
977        adb_close(fd);
978        return 0;
979    }
980#endif /* !defined(_WIN32) */
981}
982
983static bool wait_for_device(const char* service, TransportType t, const char* serial) {
984    // Was the caller vague about what they'd like us to wait for?
985    // If so, check they weren't more specific in their choice of transport type.
986    if (strcmp(service, "wait-for-device") == 0) {
987        if (t == kTransportUsb) {
988            service = "wait-for-usb";
989        } else if (t == kTransportLocal) {
990            service = "wait-for-local";
991        } else {
992            service = "wait-for-any";
993        }
994    }
995
996    std::string cmd = format_host_command(service, t, serial);
997    return adb_command(cmd);
998}
999
1000// Connects to the device "shell" service with |command| and prints the
1001// resulting output.
1002static int send_shell_command(TransportType transport_type, const char* serial,
1003                              const std::string& command,
1004                              bool disable_shell_protocol) {
1005    // Only use shell protocol if it's supported and the caller doesn't want
1006    // to explicitly disable it.
1007    bool use_shell_protocol = false;
1008    if (!disable_shell_protocol) {
1009        FeatureSet features = GetFeatureSet(transport_type, serial);
1010        use_shell_protocol = CanUseFeature(features, kFeatureShell2);
1011    }
1012
1013    std::string service_string = ShellServiceString(use_shell_protocol, "",
1014                                                    command);
1015
1016    int fd;
1017    while (true) {
1018        std::string error;
1019        fd = adb_connect(service_string, &error);
1020        if (fd >= 0) {
1021            break;
1022        }
1023        fprintf(stderr,"- waiting for device -\n");
1024        adb_sleep_ms(1000);
1025        wait_for_device("wait-for-device", transport_type, serial);
1026    }
1027
1028    int exit_code = read_and_dump(fd, use_shell_protocol);
1029
1030    if (adb_close(fd) < 0) {
1031        PLOG(ERROR) << "failure closing FD " << fd;
1032    }
1033
1034    return exit_code;
1035}
1036
1037static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
1038    char* log_tags = getenv("ANDROID_LOG_TAGS");
1039    std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
1040
1041    std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
1042
1043    if (!strcmp(argv[0], "longcat")) {
1044        cmd += " -v long";
1045    }
1046
1047    --argc;
1048    ++argv;
1049    while (argc-- > 0) {
1050        cmd += " " + escape_arg(*argv++);
1051    }
1052
1053    // No need for shell protocol with logcat, always disable for simplicity.
1054    return send_shell_command(transport, serial, cmd, true);
1055}
1056
1057static int backup(int argc, const char** argv) {
1058    const char* filename = "backup.ab";
1059
1060    /* find, extract, and use any -f argument */
1061    for (int i = 1; i < argc; i++) {
1062        if (!strcmp("-f", argv[i])) {
1063            if (i == argc-1) {
1064                fprintf(stderr, "adb: -f passed with no filename\n");
1065                return usage();
1066            }
1067            filename = argv[i+1];
1068            for (int j = i+2; j <= argc; ) {
1069                argv[i++] = argv[j++];
1070            }
1071            argc -= 2;
1072            argv[argc] = NULL;
1073        }
1074    }
1075
1076    /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
1077    if (argc < 2) return usage();
1078
1079    adb_unlink(filename);
1080    int outFd = adb_creat(filename, 0640);
1081    if (outFd < 0) {
1082        fprintf(stderr, "adb: unable to open file %s\n", filename);
1083        return -1;
1084    }
1085
1086    std::string cmd = "backup:";
1087    --argc;
1088    ++argv;
1089    while (argc-- > 0) {
1090        cmd += " " + escape_arg(*argv++);
1091    }
1092
1093    D("backup. filename=%s cmd=%s", filename, cmd.c_str());
1094    std::string error;
1095    int fd = adb_connect(cmd, &error);
1096    if (fd < 0) {
1097        fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
1098        adb_close(outFd);
1099        return -1;
1100    }
1101
1102    printf("Now unlock your device and confirm the backup operation.\n");
1103    copy_to_file(fd, outFd);
1104
1105    adb_close(fd);
1106    adb_close(outFd);
1107    return 0;
1108}
1109
1110static int restore(int argc, const char** argv) {
1111    if (argc != 2) return usage();
1112
1113    const char* filename = argv[1];
1114    int tarFd = adb_open(filename, O_RDONLY);
1115    if (tarFd < 0) {
1116        fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
1117        return -1;
1118    }
1119
1120    std::string error;
1121    int fd = adb_connect("restore:", &error);
1122    if (fd < 0) {
1123        fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
1124        adb_close(tarFd);
1125        return -1;
1126    }
1127
1128    printf("Now unlock your device and confirm the restore operation.\n");
1129    copy_to_file(tarFd, fd);
1130
1131    adb_close(fd);
1132    adb_close(tarFd);
1133    return 0;
1134}
1135
1136/* <hint> may be:
1137 * - A simple product name
1138 *   e.g., "sooner"
1139 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1140 *   e.g., "out/target/product/sooner"
1141 * - An absolute path to the PRODUCT_OUT dir
1142 *   e.g., "/src/device/out/target/product/sooner"
1143 *
1144 * Given <hint>, try to construct an absolute path to the
1145 * ANDROID_PRODUCT_OUT dir.
1146 */
1147static std::string find_product_out_path(const std::string& hint) {
1148    if (hint.empty()) {
1149        return "";
1150    }
1151
1152    // If it's already absolute, don't bother doing any work.
1153    if (adb_is_absolute_host_path(hint.c_str())) {
1154        return hint;
1155    }
1156
1157    // If there are any slashes in it, assume it's a relative path;
1158    // make it absolute.
1159    if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
1160        std::string cwd;
1161        if (!getcwd(&cwd)) {
1162            fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
1163            return "";
1164        }
1165        return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
1166    }
1167
1168    // It's a string without any slashes.  Try to do something with it.
1169    //
1170    // Try to find the root of the build tree, and build a PRODUCT_OUT
1171    // path from there.
1172    char* top = getenv("ANDROID_BUILD_TOP");
1173    if (top == nullptr) {
1174        fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
1175        return "";
1176    }
1177
1178    std::string path = top;
1179    path += OS_PATH_SEPARATOR_STR;
1180    path += "out";
1181    path += OS_PATH_SEPARATOR_STR;
1182    path += "target";
1183    path += OS_PATH_SEPARATOR_STR;
1184    path += "product";
1185    path += OS_PATH_SEPARATOR_STR;
1186    path += hint;
1187    if (!directory_exists(path)) {
1188        fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
1189                        "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
1190        return "";
1191    }
1192    return path;
1193}
1194
1195static void parse_push_pull_args(const char** arg, int narg,
1196                                 std::vector<const char*>* srcs,
1197                                 const char** dst, bool* copy_attrs) {
1198    *copy_attrs = false;
1199
1200    srcs->clear();
1201    bool ignore_flags = false;
1202    while (narg > 0) {
1203        if (ignore_flags || *arg[0] != '-') {
1204            srcs->push_back(*arg);
1205        } else {
1206            if (!strcmp(*arg, "-p")) {
1207                // Silently ignore for backwards compatibility.
1208            } else if (!strcmp(*arg, "-a")) {
1209                *copy_attrs = true;
1210            } else if (!strcmp(*arg, "--")) {
1211                ignore_flags = true;
1212            } else {
1213                fprintf(stderr, "adb: unrecognized option '%s'\n", *arg);
1214                exit(1);
1215            }
1216        }
1217        ++arg;
1218        --narg;
1219    }
1220
1221    if (srcs->size() > 1) {
1222        *dst = srcs->back();
1223        srcs->pop_back();
1224    }
1225}
1226
1227static int adb_connect_command(const std::string& command) {
1228    std::string error;
1229    int fd = adb_connect(command, &error);
1230    if (fd < 0) {
1231        fprintf(stderr, "error: %s\n", error.c_str());
1232        return 1;
1233    }
1234    read_and_dump(fd);
1235    adb_close(fd);
1236    return 0;
1237}
1238
1239static int adb_query_command(const std::string& command) {
1240    std::string result;
1241    std::string error;
1242    if (!adb_query(command, &result, &error)) {
1243        fprintf(stderr, "error: %s\n", error.c_str());
1244        return 1;
1245    }
1246    printf("%s\n", result.c_str());
1247    return 0;
1248}
1249
1250// Disallow stdin, stdout, and stderr.
1251static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1252#ifdef _WIN32
1253    const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1254    return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1255           (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1256           (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1257#else
1258    return ack_reply_fd > 2;
1259#endif
1260}
1261
1262int adb_commandline(int argc, const char **argv) {
1263    int no_daemon = 0;
1264    int is_daemon = 0;
1265    int is_server = 0;
1266    int r;
1267    TransportType transport_type = kTransportAny;
1268    int ack_reply_fd = -1;
1269
1270    // If defined, this should be an absolute path to
1271    // the directory containing all of the various system images
1272    // for a particular product.  If not defined, and the adb
1273    // command requires this information, then the user must
1274    // specify the path using "-p".
1275    char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1276    if (ANDROID_PRODUCT_OUT != nullptr) {
1277        gProductOutPath = ANDROID_PRODUCT_OUT;
1278    }
1279    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1280
1281    /* Validate and assign the server port */
1282    const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
1283    int server_port = DEFAULT_ADB_PORT;
1284    if (server_port_str && strlen(server_port_str) > 0) {
1285        server_port = strtol(server_port_str, nullptr, 0);
1286        if (server_port <= 0 || server_port > 65535) {
1287            fprintf(stderr,
1288                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65536. Got \"%s\"\n",
1289                    server_port_str);
1290            return usage();
1291        }
1292    }
1293
1294    // We need to check for -d and -e before we look at $ANDROID_SERIAL.
1295    const char* serial = nullptr;
1296
1297    while (argc > 0) {
1298        if (!strcmp(argv[0],"server")) {
1299            is_server = 1;
1300        } else if (!strcmp(argv[0],"nodaemon")) {
1301            no_daemon = 1;
1302        } else if (!strcmp(argv[0], "fork-server")) {
1303            /* this is a special flag used only when the ADB client launches the ADB Server */
1304            is_daemon = 1;
1305        } else if (!strcmp(argv[0], "--reply-fd")) {
1306            if (argc < 2) return usage();
1307            const char* reply_fd_str = argv[1];
1308            argc--;
1309            argv++;
1310            ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
1311            if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
1312                fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1313                return usage();
1314            }
1315        } else if (!strncmp(argv[0], "-p", 2)) {
1316            const char* product = nullptr;
1317            if (argv[0][2] == '\0') {
1318                if (argc < 2) return usage();
1319                product = argv[1];
1320                argc--;
1321                argv++;
1322            } else {
1323                product = argv[0] + 2;
1324            }
1325            gProductOutPath = find_product_out_path(product);
1326            if (gProductOutPath.empty()) {
1327                fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
1328                return usage();
1329            }
1330        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1331            if (isdigit(argv[0][2])) {
1332                serial = argv[0] + 2;
1333            } else {
1334                if (argc < 2 || argv[0][2] != '\0') return usage();
1335                serial = argv[1];
1336                argc--;
1337                argv++;
1338            }
1339        } else if (!strcmp(argv[0],"-d")) {
1340            transport_type = kTransportUsb;
1341        } else if (!strcmp(argv[0],"-e")) {
1342            transport_type = kTransportLocal;
1343        } else if (!strcmp(argv[0],"-a")) {
1344            gListenAll = 1;
1345        } else if (!strncmp(argv[0], "-H", 2)) {
1346            const char *hostname = NULL;
1347            if (argv[0][2] == '\0') {
1348                if (argc < 2) return usage();
1349                hostname = argv[1];
1350                argc--;
1351                argv++;
1352            } else {
1353                hostname = argv[0] + 2;
1354            }
1355            adb_set_tcp_name(hostname);
1356
1357        } else if (!strncmp(argv[0], "-P", 2)) {
1358            if (argv[0][2] == '\0') {
1359                if (argc < 2) return usage();
1360                server_port_str = argv[1];
1361                argc--;
1362                argv++;
1363            } else {
1364                server_port_str = argv[0] + 2;
1365            }
1366            if (strlen(server_port_str) > 0) {
1367                server_port = (int) strtol(server_port_str, NULL, 0);
1368                if (server_port <= 0 || server_port > 65535) {
1369                    fprintf(stderr,
1370                            "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1371                            server_port_str);
1372                    return usage();
1373                }
1374            } else {
1375                fprintf(stderr,
1376                "adb: port number must be a positive number less than 65536. Got empty string.\n");
1377                return usage();
1378            }
1379        } else {
1380                /* out of recognized modifiers and flags */
1381            break;
1382        }
1383        argc--;
1384        argv++;
1385    }
1386
1387    // If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
1388    if (transport_type == kTransportAny && serial == nullptr) {
1389        serial = getenv("ANDROID_SERIAL");
1390    }
1391
1392    adb_set_transport(transport_type, serial);
1393    adb_set_tcp_specifics(server_port);
1394
1395    if (is_server) {
1396        if (no_daemon || is_daemon) {
1397            if (is_daemon && (ack_reply_fd == -1)) {
1398                fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1399                return usage();
1400            }
1401            r = adb_main(is_daemon, server_port, ack_reply_fd);
1402        } else {
1403            r = launch_server(server_port);
1404        }
1405        if (r) {
1406            fprintf(stderr,"* could not start server *\n");
1407        }
1408        return r;
1409    }
1410
1411    if (argc == 0) {
1412        return usage();
1413    }
1414
1415    /* handle wait-for-* prefix */
1416    if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1417        const char* service = argv[0];
1418
1419        if (!wait_for_device(service, transport_type, serial)) {
1420            return 1;
1421        }
1422
1423        // Allow a command to be run after wait-for-device,
1424        // e.g. 'adb wait-for-device shell'.
1425        if (argc == 1) {
1426            return 0;
1427        }
1428
1429        /* Fall through */
1430        argc--;
1431        argv++;
1432    }
1433
1434    /* adb_connect() commands */
1435    if (!strcmp(argv[0], "devices")) {
1436        const char *listopt;
1437        if (argc < 2) {
1438            listopt = "";
1439        } else if (argc == 2 && !strcmp(argv[1], "-l")) {
1440            listopt = argv[1];
1441        } else {
1442            fprintf(stderr, "Usage: adb devices [-l]\n");
1443            return 1;
1444        }
1445
1446        std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1447        printf("List of devices attached\n");
1448        return adb_query_command(query);
1449    }
1450    else if (!strcmp(argv[0], "connect")) {
1451        if (argc != 2) {
1452            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
1453            return 1;
1454        }
1455
1456        std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1457        return adb_query_command(query);
1458    }
1459    else if (!strcmp(argv[0], "disconnect")) {
1460        if (argc > 2) {
1461            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1462            return 1;
1463        }
1464
1465        std::string query = android::base::StringPrintf("host:disconnect:%s",
1466                                                        (argc == 2) ? argv[1] : "");
1467        return adb_query_command(query);
1468    }
1469    else if (!strcmp(argv[0], "emu")) {
1470        return adb_send_emulator_command(argc, argv, serial);
1471    }
1472    else if (!strcmp(argv[0], "shell")) {
1473        return adb_shell(argc, argv, transport_type, serial);
1474    }
1475    else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
1476        int exec_in = !strcmp(argv[0], "exec-in");
1477
1478        std::string cmd = "exec:";
1479        cmd += argv[1];
1480        argc -= 2;
1481        argv += 2;
1482        while (argc-- > 0) {
1483            cmd += " " + escape_arg(*argv++);
1484        }
1485
1486        std::string error;
1487        int fd = adb_connect(cmd, &error);
1488        if (fd < 0) {
1489            fprintf(stderr, "error: %s\n", error.c_str());
1490            return -1;
1491        }
1492
1493        if (exec_in) {
1494            copy_to_file(STDIN_FILENO, fd);
1495        } else {
1496            copy_to_file(fd, STDOUT_FILENO);
1497        }
1498
1499        adb_close(fd);
1500        return 0;
1501    }
1502    else if (!strcmp(argv[0], "kill-server")) {
1503        std::string error;
1504        int fd = _adb_connect("host:kill", &error);
1505        if (fd == -2) {
1506            // Failed to make network connection to server. Don't output the
1507            // network error since that is expected.
1508            fprintf(stderr,"* server not running *\n");
1509            // Successful exit code because the server is already "killed".
1510            return 0;
1511        } else if (fd == -1) {
1512            // Some other error.
1513            fprintf(stderr, "error: %s\n", error.c_str());
1514            return 1;
1515        } else {
1516            // Successfully connected, kill command sent, okay status came back.
1517            // Server should exit() in a moment, if not already.
1518            ReadOrderlyShutdown(fd);
1519            adb_close(fd);
1520            return 0;
1521        }
1522    }
1523    else if (!strcmp(argv[0], "sideload")) {
1524        if (argc != 2) return usage();
1525        if (adb_sideload_host(argv[1])) {
1526            return 1;
1527        } else {
1528            return 0;
1529        }
1530    }
1531    else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1532        return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1533    }
1534    else if (!strcmp(argv[0], "remount") ||
1535             !strcmp(argv[0], "reboot") ||
1536             !strcmp(argv[0], "reboot-bootloader") ||
1537             !strcmp(argv[0], "usb") ||
1538             !strcmp(argv[0], "root") ||
1539             !strcmp(argv[0], "unroot") ||
1540             !strcmp(argv[0], "disable-verity") ||
1541             !strcmp(argv[0], "enable-verity")) {
1542        std::string command;
1543        if (!strcmp(argv[0], "reboot-bootloader")) {
1544            command = "reboot:bootloader";
1545        } else if (argc > 1) {
1546            command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
1547        } else {
1548            command = android::base::StringPrintf("%s:", argv[0]);
1549        }
1550        return adb_connect_command(command);
1551    }
1552    else if (!strcmp(argv[0], "bugreport")) {
1553        if (argc != 1) return usage();
1554        // No need for shell protocol with bugreport, always disable for
1555        // simplicity.
1556        return send_shell_command(transport_type, serial, "bugreport", true);
1557    }
1558    else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
1559        bool reverse = !strcmp(argv[0], "reverse");
1560        ++argv;
1561        --argc;
1562        if (argc < 1) return usage();
1563
1564        // Determine the <host-prefix> for this command.
1565        std::string host_prefix;
1566        if (reverse) {
1567            host_prefix = "reverse";
1568        } else {
1569            if (serial) {
1570                host_prefix = android::base::StringPrintf("host-serial:%s", serial);
1571            } else if (transport_type == kTransportUsb) {
1572                host_prefix = "host-usb";
1573            } else if (transport_type == kTransportLocal) {
1574                host_prefix = "host-local";
1575            } else {
1576                host_prefix = "host";
1577            }
1578        }
1579
1580        std::string cmd;
1581        if (strcmp(argv[0], "--list") == 0) {
1582            if (argc != 1) return usage();
1583            return adb_query_command(host_prefix + ":list-forward");
1584        } else if (strcmp(argv[0], "--remove-all") == 0) {
1585            if (argc != 1) return usage();
1586            cmd = host_prefix + ":killforward-all";
1587        } else if (strcmp(argv[0], "--remove") == 0) {
1588            // forward --remove <local>
1589            if (argc != 2) return usage();
1590            cmd = host_prefix + ":killforward:" + argv[1];
1591        } else if (strcmp(argv[0], "--no-rebind") == 0) {
1592            // forward --no-rebind <local> <remote>
1593            if (argc != 3) return usage();
1594            cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1595        } else {
1596            // forward <local> <remote>
1597            if (argc != 2) return usage();
1598            cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
1599        }
1600
1601        return adb_command(cmd) ? 0 : 1;
1602    }
1603    /* do_sync_*() commands */
1604    else if (!strcmp(argv[0], "ls")) {
1605        if (argc != 2) return usage();
1606        return do_sync_ls(argv[1]) ? 0 : 1;
1607    }
1608    else if (!strcmp(argv[0], "push")) {
1609        bool copy_attrs = false;
1610        std::vector<const char*> srcs;
1611        const char* dst = nullptr;
1612
1613        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs);
1614        if (srcs.empty() || !dst) return usage();
1615        return do_sync_push(srcs, dst) ? 0 : 1;
1616    }
1617    else if (!strcmp(argv[0], "pull")) {
1618        bool copy_attrs = false;
1619        std::vector<const char*> srcs;
1620        const char* dst = ".";
1621
1622        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs);
1623        if (srcs.empty()) return usage();
1624        return do_sync_pull(srcs, dst, copy_attrs) ? 0 : 1;
1625    }
1626    else if (!strcmp(argv[0], "install")) {
1627        if (argc < 2) return usage();
1628        FeatureSet features = GetFeatureSet(transport_type, serial);
1629        if (CanUseFeature(features, kFeatureCmd)) {
1630            return install_app(transport_type, serial, argc, argv);
1631        }
1632        return install_app_legacy(transport_type, serial, argc, argv);
1633    }
1634    else if (!strcmp(argv[0], "install-multiple")) {
1635        if (argc < 2) return usage();
1636        return install_multiple_app(transport_type, serial, argc, argv);
1637    }
1638    else if (!strcmp(argv[0], "uninstall")) {
1639        if (argc < 2) return usage();
1640        FeatureSet features = GetFeatureSet(transport_type, serial);
1641        if (CanUseFeature(features, kFeatureCmd)) {
1642            return uninstall_app(transport_type, serial, argc, argv);
1643        }
1644        return uninstall_app_legacy(transport_type, serial, argc, argv);
1645    }
1646    else if (!strcmp(argv[0], "sync")) {
1647        std::string src;
1648        bool list_only = false;
1649        if (argc < 2) {
1650            // No local path was specified.
1651            src = "";
1652        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1653            list_only = true;
1654            if (argc == 3) {
1655                src = argv[2];
1656            } else {
1657                src = "";
1658            }
1659        } else if (argc == 2) {
1660            // A local path or "android"/"data" arg was specified.
1661            src = argv[1];
1662        } else {
1663            return usage();
1664        }
1665
1666        if (src != "" &&
1667            src != "system" && src != "data" && src != "vendor" && src != "oem") {
1668            return usage();
1669        }
1670
1671        std::string system_src_path = product_file("system");
1672        std::string data_src_path = product_file("data");
1673        std::string vendor_src_path = product_file("vendor");
1674        std::string oem_src_path = product_file("oem");
1675
1676        bool okay = true;
1677        if (okay && (src.empty() || src == "system")) {
1678            okay = do_sync_sync(system_src_path, "/system", list_only);
1679        }
1680        if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1681            okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
1682        }
1683        if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1684            okay = do_sync_sync(oem_src_path, "/oem", list_only);
1685        }
1686        if (okay && (src.empty() || src == "data")) {
1687            okay = do_sync_sync(data_src_path, "/data", list_only);
1688        }
1689        return okay ? 0 : 1;
1690    }
1691    /* passthrough commands */
1692    else if (!strcmp(argv[0],"get-state") ||
1693        !strcmp(argv[0],"get-serialno") ||
1694        !strcmp(argv[0],"get-devpath"))
1695    {
1696        return adb_query_command(format_host_command(argv[0], transport_type, serial));
1697    }
1698    /* other commands */
1699    else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
1700        return logcat(transport_type, serial, argc, argv);
1701    }
1702    else if (!strcmp(argv[0],"ppp")) {
1703        return ppp(argc, argv);
1704    }
1705    else if (!strcmp(argv[0], "start-server")) {
1706        std::string error;
1707        const int result = adb_connect("host:start-server", &error);
1708        if (result < 0) {
1709            fprintf(stderr, "error: %s\n", error.c_str());
1710        }
1711        return result;
1712    }
1713    else if (!strcmp(argv[0], "backup")) {
1714        return backup(argc, argv);
1715    }
1716    else if (!strcmp(argv[0], "restore")) {
1717        return restore(argc, argv);
1718    }
1719    else if (!strcmp(argv[0], "keygen")) {
1720        if (argc < 2) return usage();
1721        // Always print key generation information for keygen command.
1722        adb_trace_enable(AUTH);
1723        return adb_auth_keygen(argv[1]);
1724    }
1725    else if (!strcmp(argv[0], "jdwp")) {
1726        return adb_connect_command("jdwp");
1727    }
1728    /* "adb /?" is a common idiom under Windows */
1729    else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1730        help();
1731        return 0;
1732    }
1733    else if (!strcmp(argv[0], "version")) {
1734        fprintf(stdout, "%s", adb_version().c_str());
1735        return 0;
1736    }
1737    else if (!strcmp(argv[0], "features")) {
1738        // Only list the features common to both the adb client and the device.
1739        FeatureSet features = GetFeatureSet(transport_type, serial);
1740        for (const std::string& name : features) {
1741            if (CanUseFeature(features, name)) {
1742                printf("%s\n", name.c_str());
1743            }
1744        }
1745        return 0;
1746    }
1747
1748    usage();
1749    return 1;
1750}
1751
1752static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
1753    // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device
1754    std::string cmd = "cmd package";
1755    while (argc-- > 0) {
1756        // deny the '-k' option until the remaining data/cache can be removed with adb/UI
1757        if (strcmp(*argv, "-k") == 0) {
1758            printf(
1759                "The -k option uninstalls the application while retaining the data/cache.\n"
1760                "At the moment, there is no way to remove the remaining data.\n"
1761                "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1762                "If you truly wish to continue, execute 'adb shell cmd package uninstall -k'.\n");
1763            return EXIT_FAILURE;
1764        }
1765        cmd += " " + escape_arg(*argv++);
1766    }
1767
1768    return send_shell_command(transport, serial, cmd, false);
1769}
1770
1771static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
1772    // The last argument must be the APK file
1773    const char* file = argv[argc - 1];
1774    const char* dot = strrchr(file, '.');
1775    bool found_apk = false;
1776    struct stat sb;
1777    if (dot && !strcasecmp(dot, ".apk")) {
1778        if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1779            fprintf(stderr, "Invalid APK file: %s\n", file);
1780            return EXIT_FAILURE;
1781        }
1782        found_apk = true;
1783    }
1784
1785    if (!found_apk) {
1786        fprintf(stderr, "Missing APK file\n");
1787        return EXIT_FAILURE;
1788    }
1789
1790    int localFd = adb_open(file, O_RDONLY);
1791    if (localFd < 0) {
1792        fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
1793        return 1;
1794    }
1795
1796    std::string error;
1797    std::string cmd = "exec:cmd package";
1798
1799    // don't copy the APK name, but, copy the rest of the arguments as-is
1800    while (argc-- > 1) {
1801        cmd += " " + escape_arg(std::string(*argv++));
1802    }
1803
1804    // add size parameter [required for streaming installs]
1805    // do last to override any user specified value
1806    cmd += " " + android::base::StringPrintf("-S %" PRIu64, static_cast<uint64_t>(sb.st_size));
1807
1808    int remoteFd = adb_connect(cmd, &error);
1809    if (remoteFd < 0) {
1810        fprintf(stderr, "Connect error for write: %s\n", error.c_str());
1811        adb_close(localFd);
1812        return 1;
1813    }
1814
1815    char buf[BUFSIZ];
1816    copy_to_file(localFd, remoteFd);
1817    read_status_line(remoteFd, buf, sizeof(buf));
1818
1819    adb_close(localFd);
1820    adb_close(remoteFd);
1821
1822    if (strncmp("Success", buf, 7)) {
1823        fprintf(stderr, "Failed to write %s\n", file);
1824        fputs(buf, stderr);
1825        return 1;
1826    }
1827    fputs(buf, stderr);
1828    return 0;
1829}
1830
1831static int install_multiple_app(TransportType transport, const char* serial, int argc,
1832                                const char** argv)
1833{
1834    int i;
1835    struct stat sb;
1836    uint64_t total_size = 0;
1837
1838    // Find all APK arguments starting at end.
1839    // All other arguments passed through verbatim.
1840    int first_apk = -1;
1841    for (i = argc - 1; i >= 0; i--) {
1842        const char* file = argv[i];
1843        const char* dot = strrchr(file, '.');
1844        if (dot && !strcasecmp(dot, ".apk")) {
1845            if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1846                fprintf(stderr, "Invalid APK file: %s\n", file);
1847                return EXIT_FAILURE;
1848            }
1849
1850            total_size += sb.st_size;
1851            first_apk = i;
1852        } else {
1853            break;
1854        }
1855    }
1856
1857    if (first_apk == -1) {
1858        fprintf(stderr, "Missing APK file\n");
1859        return 1;
1860    }
1861
1862    std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
1863    for (i = 1; i < first_apk; i++) {
1864        cmd += " " + escape_arg(argv[i]);
1865    }
1866
1867    // Create install session
1868    std::string error;
1869    int fd = adb_connect(cmd, &error);
1870    if (fd < 0) {
1871        fprintf(stderr, "Connect error for create: %s\n", error.c_str());
1872        return EXIT_FAILURE;
1873    }
1874    char buf[BUFSIZ];
1875    read_status_line(fd, buf, sizeof(buf));
1876    adb_close(fd);
1877
1878    int session_id = -1;
1879    if (!strncmp("Success", buf, 7)) {
1880        char* start = strrchr(buf, '[');
1881        char* end = strrchr(buf, ']');
1882        if (start && end) {
1883            *end = '\0';
1884            session_id = strtol(start + 1, NULL, 10);
1885        }
1886    }
1887    if (session_id < 0) {
1888        fprintf(stderr, "Failed to create session\n");
1889        fputs(buf, stderr);
1890        return EXIT_FAILURE;
1891    }
1892
1893    // Valid session, now stream the APKs
1894    int success = 1;
1895    for (i = first_apk; i < argc; i++) {
1896        const char* file = argv[i];
1897        if (stat(file, &sb) == -1) {
1898            fprintf(stderr, "Failed to stat %s\n", file);
1899            success = 0;
1900            goto finalize_session;
1901        }
1902
1903        std::string cmd = android::base::StringPrintf(
1904                "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
1905                static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
1906
1907        int localFd = adb_open(file, O_RDONLY);
1908        if (localFd < 0) {
1909            fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
1910            success = 0;
1911            goto finalize_session;
1912        }
1913
1914        std::string error;
1915        int remoteFd = adb_connect(cmd, &error);
1916        if (remoteFd < 0) {
1917            fprintf(stderr, "Connect error for write: %s\n", error.c_str());
1918            adb_close(localFd);
1919            success = 0;
1920            goto finalize_session;
1921        }
1922
1923        copy_to_file(localFd, remoteFd);
1924        read_status_line(remoteFd, buf, sizeof(buf));
1925
1926        adb_close(localFd);
1927        adb_close(remoteFd);
1928
1929        if (strncmp("Success", buf, 7)) {
1930            fprintf(stderr, "Failed to write %s\n", file);
1931            fputs(buf, stderr);
1932            success = 0;
1933            goto finalize_session;
1934        }
1935    }
1936
1937finalize_session:
1938    // Commit session if we streamed everything okay; otherwise abandon
1939    std::string service =
1940            android::base::StringPrintf("exec:pm install-%s %d",
1941                                        success ? "commit" : "abandon", session_id);
1942    fd = adb_connect(service, &error);
1943    if (fd < 0) {
1944        fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
1945        return EXIT_FAILURE;
1946    }
1947    read_status_line(fd, buf, sizeof(buf));
1948    adb_close(fd);
1949
1950    if (!strncmp("Success", buf, 7)) {
1951        fputs(buf, stderr);
1952        return 0;
1953    } else {
1954        fprintf(stderr, "Failed to finalize session\n");
1955        fputs(buf, stderr);
1956        return EXIT_FAILURE;
1957    }
1958}
1959
1960static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
1961    std::string cmd = "pm";
1962
1963    while (argc-- > 0) {
1964        cmd += " " + escape_arg(*argv++);
1965    }
1966
1967    return send_shell_command(transport, serial, cmd, false);
1968}
1969
1970static int uninstall_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
1971    /* if the user choose the -k option, we refuse to do it until devices are
1972       out with the option to uninstall the remaining data somehow (adb/ui) */
1973    int i;
1974    for (i = 1; i < argc; i++) {
1975        if (!strcmp(argv[i], "-k")) {
1976            printf(
1977                "The -k option uninstalls the application while retaining the data/cache.\n"
1978                "At the moment, there is no way to remove the remaining data.\n"
1979                "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1980                "If you truly wish to continue, execute 'adb shell pm uninstall -k'\n.");
1981            return EXIT_FAILURE;
1982        }
1983    }
1984
1985    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1986    return pm_command(transport, serial, argc, argv);
1987}
1988
1989static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
1990    std::string cmd = "rm -f " + escape_arg(filename);
1991    return send_shell_command(transport, serial, cmd, false);
1992}
1993
1994static int install_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
1995    static const char *const DATA_DEST = "/data/local/tmp/%s";
1996    static const char *const SD_DEST = "/sdcard/tmp/%s";
1997    const char* where = DATA_DEST;
1998    int i;
1999    struct stat sb;
2000
2001    for (i = 1; i < argc; i++) {
2002        if (!strcmp(argv[i], "-s")) {
2003            where = SD_DEST;
2004        }
2005    }
2006
2007    // Find last APK argument.
2008    // All other arguments passed through verbatim.
2009    int last_apk = -1;
2010    for (i = argc - 1; i >= 0; i--) {
2011        const char* file = argv[i];
2012        const char* dot = strrchr(file, '.');
2013        if (dot && !strcasecmp(dot, ".apk")) {
2014            if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
2015                fprintf(stderr, "Invalid APK file: %s\n", file);
2016                return EXIT_FAILURE;
2017            }
2018
2019            last_apk = i;
2020            break;
2021        }
2022    }
2023
2024    if (last_apk == -1) {
2025        fprintf(stderr, "Missing APK file\n");
2026        return EXIT_FAILURE;
2027    }
2028
2029    int result = -1;
2030    std::vector<const char*> apk_file = {argv[last_apk]};
2031    std::string apk_dest = android::base::StringPrintf(
2032        where, adb_basename(argv[last_apk]).c_str());
2033    if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk;
2034    argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
2035    result = pm_command(transport, serial, argc, argv);
2036
2037cleanup_apk:
2038    delete_file(transport, serial, apk_dest);
2039    return result;
2040}
2041