blob: 730dc72460dda8258edceef72c9ccd61c406a62a [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
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
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG ADB
Dan Albert33134262015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Dan Albert76649012015-02-24 15:51:19 -080021#include <assert.h>
22#include <ctype.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <errno.h>
Elliott Hughes2940ccf2015-04-17 14:07:52 -070024#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <limits.h>
26#include <stdarg.h>
Dan Albert76649012015-02-24 15:51:19 -080027#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031#include <sys/stat.h>
Dan Albert76649012015-02-24 15:51:19 -080032#include <sys/types.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
David Pursell606835a2015-09-08 17:17:02 -070034#include <memory>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070035#include <string>
Elliott Hughesdbe91ee2016-11-15 12:37:32 -080036#include <thread>
Josh Gao05786772015-10-30 16:57:19 -070037#include <vector>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070038
Elliott Hughese8b663f2016-05-26 22:43:19 -070039#include <android-base/file.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080040#include <android-base/logging.h>
Tao Wu135f4ab2016-09-16 13:01:24 -070041#include <android-base/parseint.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080042#include <android-base/stringprintf.h>
43#include <android-base/strings.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070044
Yabin Cuid325e862014-11-17 14:48:25 -080045#if !defined(_WIN32)
Josh Gao8dcdb572015-10-23 15:03:31 -070046#include <signal.h>
Elliott Hughes0fbf9612015-11-04 13:07:47 -080047#include <sys/ioctl.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080048#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080049#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050#endif
51
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080052#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080053#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080054#include "adb_client.h"
55#include "adb_io.h"
Josh Gao924d35a2016-08-30 15:39:25 -070056#include "adb_unique_fd.h"
Elliott Hughes58305772015-04-17 13:57:15 -070057#include "adb_utils.h"
Felipe Leme698e0652016-07-19 17:07:22 -070058#include "bugreport.h"
59#include "commandline.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060#include "file_sync_service.h"
David Pursell70ef7b42015-09-30 13:35:42 -070061#include "services.h"
David Pursell606835a2015-09-08 17:17:02 -070062#include "shell_service.h"
Josh Gao4602adb2016-11-15 18:55:47 -080063#include "sysdeps/chrono.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080064
Elliott Hughes3bd73c12015-05-05 13:10:43 -070065static int install_app(TransportType t, const char* serial, int argc, const char** argv);
66static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
67static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
Todd Kennedy6fa848a2015-11-03 16:53:08 -080068static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
69static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080070
Josh Gaob7b1edf2015-11-11 17:56:12 -080071static auto& gProductOutPath = *new std::string();
Matt Gumbeld7b33082012-11-14 10:16:17 -080072extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080073
Felipe Leme0d4f0502016-07-26 12:14:39 -070074DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
75
Elliott Hughes58305772015-04-17 13:57:15 -070076static std::string product_file(const char *extra) {
77 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 fprintf(stderr, "adb: Product directory not specified; "
79 "use -p or define ANDROID_PRODUCT_OUT\n");
80 exit(1);
81 }
82
Elliott Hughes58305772015-04-17 13:57:15 -070083 return android::base::StringPrintf("%s%s%s",
84 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080085}
86
Elliott Hughes58305772015-04-17 13:57:15 -070087static void help() {
Elliott Hughes4bf9bc12016-09-28 15:25:47 -070088 fprintf(stdout, "%s\n", adb_version().c_str());
Felipe Lemeb3239722016-07-29 17:57:00 -070089 // clang-format off
Elliott Hughes4bf9bc12016-09-28 15:25:47 -070090 fprintf(stdout,
91 "global options:\n"
92 " -a listen on all network interfaces, not just localhost\n"
93 " -d use USB device (error if multiple devices connected)\n"
Elliott Hughes83ab5c22017-01-13 16:58:25 -080094 " -e use TCP/IP device (error if multiple TCP/IP devices available)\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -070095 " -s SERIAL\n"
Elliott Hughes83ab5c22017-01-13 16:58:25 -080096 " use device with given serial number (overrides $ANDROID_SERIAL)\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -070097 " -p PRODUCT\n"
98 " name or path ('angler'/'out/target/product/angler');\n"
99 " default $ANDROID_PRODUCT_OUT\n"
100 " -H name of adb server host [default=localhost]\n"
101 " -P port of adb server [default=5037]\n"
102 " -L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800103 "\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700104 "general commands:\n"
105 " devices [-l] list connected devices (-l for long output)\n"
106 " help show this help message\n"
107 " version show version num\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700108 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800109 "networking:\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700110 " connect HOST[:PORT] connect to a device via TCP/IP [default port=5555]\n"
111 " disconnect [HOST[:PORT]]\n"
112 " disconnect from given TCP/IP device [default port=5555], or all\n"
113 " forward --list list all forward socket connections\n"
114 " forward [--no-rebind] LOCAL REMOTE\n"
115 " forward socket connection using:\n"
116 " tcp:<port> (<local> may be \"tcp:0\" to pick any open port)\n"
117 " localabstract:<unix domain socket name>\n"
118 " localreserved:<unix domain socket name>\n"
119 " localfilesystem:<unix domain socket name>\n"
120 " dev:<character device name>\n"
121 " jdwp:<process pid> (remote only)\n"
122 " forward --remove LOCAL remove specific forward socket connection\n"
123 " forward --remove-all remove all forward socket connections\n"
124 " ppp TTY [PARAMETER...] run PPP over USB\n"
125 " reverse --list list all reverse socket connections from device\n"
126 " reverse [--no-rebind] REMOTE LOCAL\n"
127 " reverse socket connection using:\n"
128 " tcp:<port> (<remote> may be \"tcp:0\" to pick any open port)\n"
129 " localabstract:<unix domain socket name>\n"
130 " localreserved:<unix domain socket name>\n"
131 " localfilesystem:<unix domain socket name>\n"
132 " reverse --remove REMOTE remove specific reverse socket connection\n"
133 " reverse --remove-all remove all reverse socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800134 "\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700135 "file transfer:\n"
136 " push LOCAL... REMOTE\n"
137 " copy local files/directories to device\n"
138 " pull [-a] REMOTE... LOCAL\n"
139 " copy files/dirs from device\n"
140 " -a: preserve file timestamp and mode\n"
141 " sync [DIR]\n"
142 " copy all changed files to device; if DIR is \"system\", \"vendor\", \"oem\",\n"
143 " or \"data\", only sync that partition (default all)\n"
144 " -l: list but don't copy\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800145 "\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700146 "shell:\n"
147 " shell [-e ESCAPE] [-n] [-Tt] [-x] [COMMAND...]\n"
148 " run remote shell command (interactive shell if no command given)\n"
149 " -e: choose escape character, or \"none\"; default '~'\n"
150 " -n: don't read from stdin\n"
151 " -T: disable PTY allocation\n"
152 " -t: force PTY allocation\n"
153 " -x: disable remote exit codes and stdout/stderr separation\n"
154 " emu COMMAND run emulator console command\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800155 "\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700156 "app installation:\n"
157 " install [-lrtsdg] PACKAGE\n"
158 " install-multiple [-lrtsdpg] PACKAGE...\n"
159 " push package(s) to the device and install them\n"
160 " -l: forward lock application\n"
161 " -r: replace existing application\n"
162 " -t: allow test packages\n"
163 " -s: install application on sdcard\n"
164 " -d: allow version code downgrade (debuggable packages only)\n"
165 " -p: partial application install (install-multiple only)\n"
166 " -g: grant all runtime permissions\n"
167 " uninstall [-k] PACKAGE\n"
168 " remove this app package from the device\n"
169 " '-k': keep the data and cache directories\n"
170 "\n"
171 "backup/restore:\n"
172 " backup [-f FILE] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [PACKAGE...]\n"
173 " write an archive of the device's data to FILE [default=backup.adb]\n"
174 " package list optional if -all/-shared are supplied\n"
175 " -apk/-noapk: do/don't back up .apk files (default -noapk)\n"
176 " -obb/-noobb: do/don't back up .obb files (default -noobb)\n"
177 " -shared|-noshared: do/don't back up shared storage (default -noshared)\n"
178 " -all: back up all installed applications\n"
179 " -system|-nosystem: include system apps in -all (default -system)\n"
180 " restore FILE restore device contents from FILE\n"
181 "\n"
182 "debugging:\n"
183 " bugreport [PATH]\n"
184 " write bugreport to given PATH [default=bugreport.zip];\n"
185 " if PATH is a directory, the bug report is saved in that directory.\n"
186 " devices that don't support zipped bug reports output to stdout.\n"
187 " jdwp list pids of processes hosting a JDWP transport\n"
188 " logcat show device log (logcat --help for more)\n"
189 "\n"
190 "security:\n"
191 " disable-verity disable dm-verity checking on userdebug builds\n"
192 " enable-verity re-enable dm-verity checking on userdebug builds\n"
193 " keygen FILE\n"
194 " generate adb public/private key; private key stored in FILE,\n"
195 " public key stored in FILE.pub (existing files overwritten)\n"
196 "\n"
197 "scripting:\n"
198 " wait-for[-TRANSPORT]-STATE\n"
199 " wait for device to be in the given state\n"
200 " State: device, recovery, sideload, or bootloader\n"
201 " Transport: usb, local, or any [default=any]\n"
202 " get-state print offline | bootloader | device\n"
203 " get-serialno print <serial-number>\n"
204 " get-devpath print <device-path>\n"
205 " remount\n"
206 " remount /system, /vendor, and /oem partitions read-write\n"
207 " reboot [bootloader|recovery|sideload|sideload-auto-reboot]\n"
208 " reboot the device; defaults to booting system image but\n"
209 " supports bootloader and recovery too. sideload reboots\n"
210 " into recovery and automatically starts sideload mode,\n"
211 " sideload-auto-reboot is the same but reboots after sideloading.\n"
212 " sideload OTAPACKAGE sideload the given full OTA package\n"
213 " root restart adbd with root permissions\n"
214 " unroot restart adbd without root permissions\n"
215 " usb restart adb server listening on USB\n"
216 " tcpip PORT restart adb server listening on TCP on PORT\n"
Timcd643152010-02-16 20:18:29 +0000217 "\n"
Yabin Cui1f4ec192016-04-05 13:50:44 -0700218 "internal debugging:\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700219 " start-server ensure that there is a server running\n"
220 " kill-server kill the server if it is running\n"
221 " reconnect kick connection from host side to force reconnect\n"
222 " reconnect device kick connection from device side to force reconnect\n"
223 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700224 "environment variables:\n"
Elliott Hughes4bf9bc12016-09-28 15:25:47 -0700225 " $ADB_TRACE\n"
226 " comma-separated list of debug info to log:\n"
227 " all,adb,sockets,packets,rwx,usb,sync,sysdeps,transport,jdwp\n"
228 " $ADB_VENDOR_KEYS colon-separated list of keys (files or directories)\n"
229 " $ANDROID_SERIAL serial number to connect to (see -s)\n"
230 " $ANDROID_LOG_TAGS tags to be used by logcat (see logcat --help)\n");
Felipe Lemeb3239722016-07-29 17:57:00 -0700231 // clang-format on
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800232}
233
Yabin Cuid325e862014-11-17 14:48:25 -0800234#if defined(_WIN32)
235
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700236// Implemented in sysdeps_win32.cpp.
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800237void stdin_raw_init();
238void stdin_raw_restore();
Yabin Cuid325e862014-11-17 14:48:25 -0800239
240#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100241static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800242
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800243static void stdin_raw_init() {
244 if (tcgetattr(STDIN_FILENO, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800245
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100246 termios tio;
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800247 if (tcgetattr(STDIN_FILENO, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800248
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100249 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800250
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100251 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800252 tio.c_cc[VTIME] = 0;
253 tio.c_cc[VMIN] = 1;
254
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800255 tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256}
257
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800258static void stdin_raw_restore() {
259 tcsetattr(STDIN_FILENO, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260}
261#endif
262
David Pursell606835a2015-09-08 17:17:02 -0700263// Reads from |fd| and prints received data. If |use_shell_protocol| is true
264// this expects that incoming data will use the shell protocol, in which case
265// stdout/stderr are routed independently and the remote exit code will be
266// returned.
Felipe Leme0d4f0502016-07-26 12:14:39 -0700267// if |callback| is non-null, stdout/stderr output will be handled by it.
268int read_and_dump(int fd, bool use_shell_protocol = false,
269 StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK) {
David Pursell606835a2015-09-08 17:17:02 -0700270 int exit_code = 0;
Felipe Lemed1dd1252016-06-06 16:05:36 -0700271 if (fd < 0) return exit_code;
272
David Pursell606835a2015-09-08 17:17:02 -0700273 std::unique_ptr<ShellProtocol> protocol;
274 int length = 0;
David Pursell606835a2015-09-08 17:17:02 -0700275
276 char raw_buffer[BUFSIZ];
277 char* buffer_ptr = raw_buffer;
278 if (use_shell_protocol) {
279 protocol.reset(new ShellProtocol(fd));
280 if (!protocol) {
281 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
282 return 1;
283 }
284 buffer_ptr = protocol->data();
285 }
286
Felipe Lemed1dd1252016-06-06 16:05:36 -0700287 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700288 if (use_shell_protocol) {
289 if (!protocol->Read()) {
290 break;
291 }
Felipe Leme0d4f0502016-07-26 12:14:39 -0700292 length = protocol->data_length();
David Pursell606835a2015-09-08 17:17:02 -0700293 switch (protocol->id()) {
294 case ShellProtocol::kIdStdout:
Felipe Leme0d4f0502016-07-26 12:14:39 -0700295 callback->OnStdout(buffer_ptr, length);
David Pursell606835a2015-09-08 17:17:02 -0700296 break;
297 case ShellProtocol::kIdStderr:
Felipe Leme0d4f0502016-07-26 12:14:39 -0700298 callback->OnStderr(buffer_ptr, length);
David Pursell606835a2015-09-08 17:17:02 -0700299 break;
300 case ShellProtocol::kIdExit:
301 exit_code = protocol->data()[0];
302 continue;
303 default:
304 continue;
305 }
306 length = protocol->data_length();
307 } else {
308 D("read_and_dump(): pre adb_read(fd=%d)", fd);
309 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
310 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
311 if (length <= 0) {
312 break;
313 }
Felipe Leme0d4f0502016-07-26 12:14:39 -0700314 callback->OnStdout(buffer_ptr, length);
Felipe Leme44a42672016-04-01 17:43:27 -0700315 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800316 }
David Pursell606835a2015-09-08 17:17:02 -0700317
Felipe Leme0d4f0502016-07-26 12:14:39 -0700318 return callback->Done(exit_code);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800319}
320
Jeff Sharkey960df972014-06-09 17:30:57 -0700321static void read_status_line(int fd, char* buf, size_t count)
322{
323 count--;
324 while (count > 0) {
325 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700326 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700327 break;
328 }
329
330 buf += len;
331 count -= len;
332 }
333 *buf = '\0';
334}
335
Christopher Tatec42f1bb2016-07-06 13:22:22 -0700336static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700337 if (inFd == STDIN_FILENO) {
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800338 stdin_raw_init();
Spencer Lowb7dfb792015-05-22 16:48:31 -0700339#ifdef _WIN32
340 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
341 if (old_stdin_mode == -1) {
342 fatal_errno("could not set stdin to binary");
343 }
344#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700345 }
Yabin Cuid325e862014-11-17 14:48:25 -0800346
Spencer Lowb7dfb792015-05-22 16:48:31 -0700347#ifdef _WIN32
348 if (outFd == STDOUT_FILENO) {
349 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
350 if (old_stdout_mode == -1) {
351 fatal_errno("could not set stdout to binary");
352 }
353 }
354#endif
Christopher Tatec42f1bb2016-07-06 13:22:22 -0700355}
356
357static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) {
358 if (inFd == STDIN_FILENO) {
359 stdin_raw_restore();
360#ifdef _WIN32
361 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
362 fatal_errno("could not restore stdin mode");
363 }
364#endif
365 }
366
367#ifdef _WIN32
368 if (outFd == STDOUT_FILENO) {
369 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
370 fatal_errno("could not restore stdout mode");
371 }
372 }
373#endif
374}
375
376static void copy_to_file(int inFd, int outFd) {
377 const size_t BUFSIZE = 32 * 1024;
378 char* buf = (char*) malloc(BUFSIZE);
379 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
380 int len;
381 long total = 0;
382 int old_stdin_mode = -1;
383 int old_stdout_mode = -1;
384
385 D("copy_to_file(%d -> %d)", inFd, outFd);
386
387 stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700388
Elliott Hughesa7090b92015-04-17 17:03:59 -0700389 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700390 if (inFd == STDIN_FILENO) {
391 len = unix_read(inFd, buf, BUFSIZE);
392 } else {
393 len = adb_read(inFd, buf, BUFSIZE);
394 }
Christopher Tated2f54152011-04-21 12:53:28 -0700395 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700396 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700397 break;
398 }
399 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700400 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700401 break;
402 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700403 if (outFd == STDOUT_FILENO) {
404 fwrite(buf, 1, len, stdout);
405 fflush(stdout);
406 } else {
407 adb_write(outFd, buf, len);
408 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700409 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700410 }
Yabin Cuid325e862014-11-17 14:48:25 -0800411
Christopher Tatec42f1bb2016-07-06 13:22:22 -0700412 stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700413
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700414 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700415 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700416}
417
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800418static void send_window_size_change(int fd, std::unique_ptr<ShellProtocol>& shell) {
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800419 // Old devices can't handle window size changes.
420 if (shell == nullptr) return;
421
Spencer Low2e02dc62015-11-07 17:34:39 -0800422#if defined(_WIN32)
423 struct winsize {
424 unsigned short ws_row;
425 unsigned short ws_col;
426 unsigned short ws_xpixel;
427 unsigned short ws_ypixel;
428 };
429#endif
430
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800431 winsize ws;
Spencer Low2e02dc62015-11-07 17:34:39 -0800432
433#if defined(_WIN32)
434 // If stdout is redirected to a non-console, we won't be able to get the
435 // console size, but that makes sense.
436 const intptr_t intptr_handle = _get_osfhandle(STDOUT_FILENO);
437 if (intptr_handle == -1) return;
438
439 const HANDLE handle = reinterpret_cast<const HANDLE>(intptr_handle);
440
441 CONSOLE_SCREEN_BUFFER_INFO info;
442 memset(&info, 0, sizeof(info));
443 if (!GetConsoleScreenBufferInfo(handle, &info)) return;
444
445 memset(&ws, 0, sizeof(ws));
446 // The number of visible rows, excluding offscreen scroll-back rows which are in info.dwSize.Y.
447 ws.ws_row = info.srWindow.Bottom - info.srWindow.Top + 1;
448 // If the user has disabled "Wrap text output on resize", they can make the screen buffer wider
449 // than the window, in which case we should use the width of the buffer.
450 ws.ws_col = info.dwSize.X;
451#else
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800452 if (ioctl(fd, TIOCGWINSZ, &ws) == -1) return;
Spencer Low2e02dc62015-11-07 17:34:39 -0800453#endif
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800454
455 // Send the new window size as human-readable ASCII for debugging convenience.
456 size_t l = snprintf(shell->data(), shell->data_capacity(), "%dx%d,%dx%d",
457 ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
458 shell->Write(ShellProtocol::kIdWindowSizeChange, l + 1);
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800459}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800460
David Pursell606835a2015-09-08 17:17:02 -0700461// Used to pass multiple values to the stdin read thread.
462struct StdinReadArgs {
463 int stdin_fd, write_fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700464 bool raw_stdin;
David Pursell606835a2015-09-08 17:17:02 -0700465 std::unique_ptr<ShellProtocol> protocol;
Elliott Hughes28416d62015-11-04 13:36:32 -0800466 char escape_char;
David Pursell606835a2015-09-08 17:17:02 -0700467};
468
David Pursell606835a2015-09-08 17:17:02 -0700469// Loops to read from stdin and push the data to the given FD.
470// The argument should be a pointer to a StdinReadArgs object. This function
471// will take ownership of the object and delete it when finished.
Josh Gaod9db09c2016-02-12 14:31:15 -0800472static void stdin_read_thread_loop(void* x) {
David Pursell606835a2015-09-08 17:17:02 -0700473 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800474
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800475#if !defined(_WIN32)
476 // Mask SIGTTIN in case we're in a backgrounded process.
Josh Gao8dcdb572015-10-23 15:03:31 -0700477 sigset_t sigset;
478 sigemptyset(&sigset);
479 sigaddset(&sigset, SIGTTIN);
480 pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
481#endif
482
Spencer Low2e02dc62015-11-07 17:34:39 -0800483#if defined(_WIN32)
484 // _get_interesting_input_record_uncached() causes unix_read_interruptible()
485 // to return -1 with errno == EINTR if the window size changes.
486#else
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800487 // Unblock SIGWINCH for this thread, so our read(2) below will be
488 // interrupted if the window size changes.
489 sigset_t mask;
490 sigemptyset(&mask);
491 sigaddset(&mask, SIGWINCH);
492 pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
493#endif
494
495 // Set up the initial window size.
496 send_window_size_change(args->stdin_fd, args->protocol);
497
Elliott Hughes28416d62015-11-04 13:36:32 -0800498 char raw_buffer[BUFSIZ];
David Pursell606835a2015-09-08 17:17:02 -0700499 char* buffer_ptr = raw_buffer;
500 size_t buffer_size = sizeof(raw_buffer);
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800501 if (args->protocol != nullptr) {
David Pursell606835a2015-09-08 17:17:02 -0700502 buffer_ptr = args->protocol->data();
503 buffer_size = args->protocol->data_capacity();
504 }
505
Elliott Hughes28416d62015-11-04 13:36:32 -0800506 // If we need to parse escape sequences, make life easy.
507 if (args->raw_stdin && args->escape_char != '\0') {
508 buffer_size = 1;
509 }
510
511 enum EscapeState { kMidFlow, kStartOfLine, kInEscape };
512 EscapeState state = kStartOfLine;
513
Elliott Hughesaa245492015-08-03 10:38:08 -0700514 while (true) {
Spencer Low2e02dc62015-11-07 17:34:39 -0800515 // Use unix_read_interruptible() rather than adb_read() for stdin.
516 D("stdin_read_thread_loop(): pre unix_read_interruptible(fdi=%d,...)", args->stdin_fd);
517 int r = unix_read_interruptible(args->stdin_fd, buffer_ptr,
518 buffer_size);
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800519 if (r == -1 && errno == EINTR) {
520 send_window_size_change(args->stdin_fd, args->protocol);
521 continue;
522 }
Spencer Low2e02dc62015-11-07 17:34:39 -0800523 D("stdin_read_thread_loop(): post unix_read_interruptible(fdi=%d,...)", args->stdin_fd);
David Pursell1ed57f02015-10-06 15:30:03 -0700524 if (r <= 0) {
525 // Only devices using the shell protocol know to close subprocess
526 // stdin. For older devices we want to just leave the connection
527 // open, otherwise an unpredictable amount of return data could
528 // be lost due to the FD closing before all data has been received.
529 if (args->protocol) {
530 args->protocol->Write(ShellProtocol::kIdCloseStdin, 0);
531 }
532 break;
533 }
Elliott Hughes28416d62015-11-04 13:36:32 -0800534 // If we made stdin raw, check input for escape sequences. In
David Pursell1ed57f02015-10-06 15:30:03 -0700535 // this situation signals like Ctrl+C are sent remotely rather than
536 // interpreted locally so this provides an emergency out if the remote
537 // process starts ignoring the signal. SSH also does this, see the
538 // "escape characters" section on the ssh man page for more info.
Elliott Hughes28416d62015-11-04 13:36:32 -0800539 if (args->raw_stdin && args->escape_char != '\0') {
540 char ch = buffer_ptr[0];
541 if (ch == args->escape_char) {
542 if (state == kStartOfLine) {
543 state = kInEscape;
544 // Swallow the escape character.
545 continue;
546 } else {
547 state = kMidFlow;
548 }
549 } else {
550 if (state == kInEscape) {
551 if (ch == '.') {
552 fprintf(stderr,"\r\n[ disconnected ]\r\n");
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800553 stdin_raw_restore();
David Pursell1ed57f02015-10-06 15:30:03 -0700554 exit(0);
Elliott Hughes28416d62015-11-04 13:36:32 -0800555 } else {
556 // We swallowed an escape character that wasn't part of
557 // a valid escape sequence; time to cough it up.
558 buffer_ptr[0] = args->escape_char;
559 buffer_ptr[1] = ch;
560 ++r;
David Pursell1ed57f02015-10-06 15:30:03 -0700561 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800562 }
Elliott Hughes28416d62015-11-04 13:36:32 -0800563 state = (ch == '\n' || ch == '\r') ? kStartOfLine : kMidFlow;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800564 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800565 }
David Pursell606835a2015-09-08 17:17:02 -0700566 if (args->protocol) {
567 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
568 break;
569 }
570 } else {
571 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
572 break;
573 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800574 }
575 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800576}
577
David Pursell1ed57f02015-10-06 15:30:03 -0700578// Returns a shell service string with the indicated arguments and command.
579static std::string ShellServiceString(bool use_shell_protocol,
580 const std::string& type_arg,
581 const std::string& command) {
582 std::vector<std::string> args;
583 if (use_shell_protocol) {
584 args.push_back(kShellServiceArgShellProtocol);
Elliott Hughesc2252df2015-11-18 12:45:48 -0800585
586 const char* terminal_type = getenv("TERM");
587 if (terminal_type != nullptr) {
588 args.push_back(std::string("TERM=") + terminal_type);
589 }
David Pursell1ed57f02015-10-06 15:30:03 -0700590 }
591 if (!type_arg.empty()) {
592 args.push_back(type_arg);
593 }
594
595 // Shell service string can look like: shell[,arg1,arg2,...]:[command].
596 return android::base::StringPrintf("shell%s%s:%s",
597 args.empty() ? "" : ",",
598 android::base::Join(args, ',').c_str(),
599 command.c_str());
600}
601
602// Connects to a shell on the device and read/writes data.
603//
604// Note: currently this function doesn't properly clean up resources; the
605// FD connected to the adb server is never closed and the stdin read thread
606// may never exit.
607//
608// On success returns the remote exit code if |use_shell_protocol| is true,
609// 0 otherwise. On failure returns 1.
610static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
Elliott Hughes28416d62015-11-04 13:36:32 -0800611 char escape_char,
David Pursell1ed57f02015-10-06 15:30:03 -0700612 const std::string& command) {
613 std::string service_string = ShellServiceString(use_shell_protocol,
614 type_arg, command);
615
616 // Make local stdin raw if the device allocates a PTY, which happens if:
617 // 1. We are explicitly asking for a PTY shell, or
618 // 2. We don't specify shell type and are starting an interactive session.
619 bool raw_stdin = (type_arg == kShellServiceArgPty ||
620 (type_arg.empty() && command.empty()));
621
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700622 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700623 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700624 if (fd < 0) {
625 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800626 return 1;
627 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800628
David Pursell606835a2015-09-08 17:17:02 -0700629 StdinReadArgs* args = new StdinReadArgs;
630 if (!args) {
631 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700632 return 1;
633 }
David Pursell1ed57f02015-10-06 15:30:03 -0700634 args->stdin_fd = STDIN_FILENO;
David Pursell606835a2015-09-08 17:17:02 -0700635 args->write_fd = fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700636 args->raw_stdin = raw_stdin;
Elliott Hughes28416d62015-11-04 13:36:32 -0800637 args->escape_char = escape_char;
David Pursell606835a2015-09-08 17:17:02 -0700638 if (use_shell_protocol) {
639 args->protocol.reset(new ShellProtocol(args->write_fd));
640 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700641
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800642 if (raw_stdin) stdin_raw_init();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800643
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800644#if !defined(_WIN32)
645 // Ensure our process is notified if the local window size changes.
646 // We use sigaction(2) to ensure that the SA_RESTART flag is not set,
647 // because the whole reason we're sending signals is to unblock the read(2)!
648 // That also means we don't need to do anything in the signal handler:
649 // the side effect of delivering the signal is all we need.
650 struct sigaction sa;
651 memset(&sa, 0, sizeof(sa));
652 sa.sa_handler = [](int) {};
653 sa.sa_flags = 0;
654 sigaction(SIGWINCH, &sa, nullptr);
655
656 // Now block SIGWINCH in this thread (the main thread) and all threads spawned
657 // from it. The stdin read thread will unblock this signal to ensure that it's
658 // the thread that receives the signal.
659 sigset_t mask;
660 sigemptyset(&mask);
661 sigaddset(&mask, SIGWINCH);
662 pthread_sigmask(SIG_BLOCK, &mask, nullptr);
663#endif
664
665 // TODO: combine read_and_dump with stdin_read_thread to make life simpler?
Josh Gaoe1dacfc2017-04-12 17:00:49 -0700666 std::thread(stdin_read_thread_loop, args).detach();
667 int exit_code = read_and_dump(fd, use_shell_protocol);
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700668
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800669 // TODO: properly exit stdin_read_thread_loop and close |fd|.
David Pursell1ed57f02015-10-06 15:30:03 -0700670
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800671 // TODO: we should probably install signal handlers for this.
672 // TODO: can we use atexit? even on Windows?
673 if (raw_stdin) stdin_raw_restore();
David Pursell1ed57f02015-10-06 15:30:03 -0700674
David Pursell606835a2015-09-08 17:17:02 -0700675 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800676}
677
Josh Gaof3f6a1d2016-01-31 19:12:26 -0800678static int adb_shell(int argc, const char** argv) {
David Pursell0aacbbe2016-01-21 19:56:50 -0800679 FeatureSet features;
Josh Gaof3f6a1d2016-01-31 19:12:26 -0800680 std::string error;
Josh Gaof3f6a1d2016-01-31 19:12:26 -0800681 if (!adb_get_feature_set(&features, &error)) {
682 fprintf(stderr, "error: %s\n", error.c_str());
David Pursell0aacbbe2016-01-21 19:56:50 -0800683 return 1;
684 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800685
Elliott Hughescabfa112016-10-19 14:47:11 -0700686 enum PtyAllocationMode { kPtyAuto, kPtyNo, kPtyYes, kPtyDefinitely };
687
688 // Defaults.
689 char escape_char = '~'; // -e
690 bool use_shell_protocol = CanUseFeature(features, kFeatureShell2); // -x
691 PtyAllocationMode tty = use_shell_protocol ? kPtyAuto : kPtyDefinitely; // -t/-T
Elliott Hughes6452a892015-04-29 12:28:13 -0700692
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800693 // Parse shell-specific command-line options.
Elliott Hughescabfa112016-10-19 14:47:11 -0700694 argv[0] = "adb shell"; // So getopt(3) error messages start "adb shell".
695 optind = 1; // argv[0] is always "shell", so set `optind` appropriately.
696 int opt;
697 while ((opt = getopt(argc, const_cast<char**>(argv), "+e:ntTx")) != -1) {
698 switch (opt) {
699 case 'e':
700 if (!(strlen(optarg) == 1 || strcmp(optarg, "none") == 0)) {
701 fprintf(stderr, "error: -e requires a single-character argument or 'none'\n");
702 return 1;
703 }
704 escape_char = (strcmp(optarg, "none") == 0) ? 0 : optarg[0];
705 break;
706 case 'n':
707 close_stdin();
708 break;
709 case 'x':
710 // This option basically asks for historical behavior, so set options that
711 // correspond to the historical defaults. This is slightly weird in that -Tx
712 // is fine (because we'll undo the -T) but -xT isn't, but that does seem to
713 // be our least worst choice...
714 use_shell_protocol = false;
715 tty = kPtyDefinitely;
716 escape_char = '~';
717 break;
718 case 't':
719 // Like ssh, -t arguments are cumulative so that multiple -t's
720 // are needed to force a PTY.
721 tty = (tty >= kPtyYes) ? kPtyDefinitely : kPtyYes;
722 break;
723 case 'T':
724 tty = kPtyNo;
725 break;
726 default:
727 // getopt(3) already printed an error message for us.
Elliott Hughes28416d62015-11-04 13:36:32 -0800728 return 1;
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800729 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700730 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800731
Elliott Hughescabfa112016-10-19 14:47:11 -0700732 bool is_interactive = (optind == argc);
David Pursell57dd5ae2016-01-27 16:07:52 -0800733
Elliott Hughescabfa112016-10-19 14:47:11 -0700734 std::string shell_type_arg = kShellServiceArgPty;
735 if (tty == kPtyNo) {
736 shell_type_arg = kShellServiceArgRaw;
737 } else if (tty == kPtyAuto) {
738 // If stdin isn't a TTY, default to a raw shell; this lets
739 // things like `adb shell < my_script.sh` work as expected.
740 // Non-interactive shells should also not have a pty.
741 if (!unix_isatty(STDIN_FILENO) || !is_interactive) {
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800742 shell_type_arg = kShellServiceArgRaw;
Elliott Hughescabfa112016-10-19 14:47:11 -0700743 }
744 } else if (tty == kPtyYes) {
745 // A single -t arg isn't enough to override implicit -T.
746 if (!unix_isatty(STDIN_FILENO)) {
747 fprintf(stderr,
748 "Remote PTY will not be allocated because stdin is not a terminal.\n"
749 "Use multiple -t options to force remote PTY allocation.\n");
750 shell_type_arg = kShellServiceArgRaw;
751 }
752 }
753
754 D("shell -e 0x%x t=%d use_shell_protocol=%s shell_type_arg=%s\n",
755 escape_char, tty,
756 use_shell_protocol ? "true" : "false",
757 (shell_type_arg == kShellServiceArgPty) ? "pty" : "raw");
758
759 // Raw mode is only supported when talking to a new device *and* using the shell protocol.
760 if (!use_shell_protocol) {
761 if (shell_type_arg != kShellServiceArgPty) {
762 fprintf(stderr, "error: %s only supports allocating a pty\n",
763 !CanUseFeature(features, kFeatureShell2) ? "device" : "-x");
764 return 1;
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800765 } else {
Elliott Hughescabfa112016-10-19 14:47:11 -0700766 // If we're not using the shell protocol, the type argument must be empty.
767 shell_type_arg = "";
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800768 }
David Pursell71c83122015-09-14 15:33:50 -0700769 }
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800770
771 std::string command;
Elliott Hughescabfa112016-10-19 14:47:11 -0700772 if (optind < argc) {
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800773 // We don't escape here, just like ssh(1). http://b/20564385.
Elliott Hughescabfa112016-10-19 14:47:11 -0700774 command = android::base::Join(std::vector<const char*>(argv + optind, argv + argc), ' ');
Elliott Hughesc15b17f2015-11-03 11:18:40 -0800775 }
776
Elliott Hughes28416d62015-11-04 13:36:32 -0800777 return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
David Pursell71c83122015-09-14 15:33:50 -0700778}
779
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700780static int adb_download_buffer(const char* service, const char* filename) {
781 std::string content;
782 if (!android::base::ReadFileToString(filename, &content)) {
783 fprintf(stderr, "error: couldn't read %s: %s\n", filename, strerror(errno));
784 return -1;
785 }
786
787 const uint8_t* data = reinterpret_cast<const uint8_t*>(content.data());
788 unsigned sz = content.size();
789
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700790 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700791 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700792 if (fd < 0) {
793 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800794 return -1;
795 }
796
797 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800798 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800799
Elliott Hughes6452a892015-04-29 12:28:13 -0700800 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800801 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800802
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700803 const char* x = strrchr(service, ':');
804 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800805
Elliott Hughes6452a892015-04-29 12:28:13 -0700806 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800807 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700808 if (!WriteFdExactly(fd, ptr, xfer)) {
809 std::string error;
810 adb_status(fd, &error);
811 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Spencer Low351ecd12015-10-14 17:32:44 -0700812 adb_close(fd);
Doug Zongker447f0612012-01-09 14:54:53 -0800813 return -1;
814 }
815 sz -= xfer;
816 ptr += xfer;
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700817 printf("sending: '%s' %4d%% \r", filename, (int)(100LL - ((100LL * sz) / (total))));
818 fflush(stdout);
Doug Zongker447f0612012-01-09 14:54:53 -0800819 }
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700820 printf("\n");
Doug Zongker447f0612012-01-09 14:54:53 -0800821
Elliott Hughese67f1f82015-04-30 17:32:03 -0700822 if (!adb_status(fd, &error)) {
823 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Spencer Low351ecd12015-10-14 17:32:44 -0700824 adb_close(fd);
Doug Zongker447f0612012-01-09 14:54:53 -0800825 return -1;
826 }
827
828 adb_close(fd);
829 return 0;
830}
831
Doug Zongker71fe5842014-06-26 15:35:36 -0700832#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
833
834/*
835 * The sideload-host protocol serves the data in a file (given on the
836 * command line) to the client, using a simple protocol:
837 *
838 * - The connect message includes the total number of bytes in the
839 * file and a block size chosen by us.
840 *
841 * - The other side sends the desired block number as eight decimal
842 * digits (eg "00000023" for block 23). Blocks are numbered from
843 * zero.
844 *
845 * - We send back the data of the requested block. The last block is
846 * likely to be partial; when the last block is requested we only
847 * send the part of the block that exists, it's not padded up to the
848 * block size.
849 *
850 * - When the other side sends "DONEDONE" instead of a block number,
851 * we hang up.
852 */
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700853static int adb_sideload_host(const char* filename) {
854 fprintf(stderr, "opening '%s'...\n", filename);
855 struct stat sb;
856 if (stat(filename, &sb) == -1) {
857 fprintf(stderr, "failed to stat file %s: %s\n", filename, strerror(errno));
858 return -1;
859 }
860 unique_fd package_fd(adb_open(filename, O_RDONLY));
861 if (package_fd == -1) {
862 fprintf(stderr, "failed to open file %s: %s\n", filename, strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700863 return -1;
864 }
865
Elliott Hughes14415142016-06-15 14:45:34 -0700866 fprintf(stderr, "connecting...\n");
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700867 std::string service = android::base::StringPrintf(
868 "sideload-host:%d:%d", static_cast<int>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700869 std::string error;
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700870 unique_fd device_fd(adb_connect(service, &error));
871 if (device_fd < 0) {
872 // Try falling back to the older (<= K) sideload method. Maybe this
Doug Zongker71fe5842014-06-26 15:35:36 -0700873 // is an older device that doesn't support sideload-host.
Elliott Hughes14415142016-06-15 14:45:34 -0700874 fprintf(stderr, "falling back to older sideload method...\n");
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700875 return adb_download_buffer("sideload", filename);
Doug Zongker71fe5842014-06-26 15:35:36 -0700876 }
877
Elliott Hughese8b663f2016-05-26 22:43:19 -0700878 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700879 adb_setsockopt(device_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
880
881 char buf[SIDELOAD_HOST_BLOCK_SIZE];
Doug Zongker71fe5842014-06-26 15:35:36 -0700882
Elliott Hughese8b663f2016-05-26 22:43:19 -0700883 size_t xfer = 0;
884 int last_percent = -1;
Elliott Hughesa7090b92015-04-17 17:03:59 -0700885 while (true) {
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700886 if (!ReadFdExactly(device_fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700887 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Elliott Hughese8b663f2016-05-26 22:43:19 -0700888 return -1;
Doug Zongker71fe5842014-06-26 15:35:36 -0700889 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700890 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700891
Elliott Hughes6452a892015-04-29 12:28:13 -0700892 if (strcmp("DONEDONE", buf) == 0) {
Elliott Hughese8b663f2016-05-26 22:43:19 -0700893 printf("\rTotal xfer: %.2fx%*s\n",
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700894 static_cast<double>(xfer) / (sb.st_size ? sb.st_size : 1),
895 static_cast<int>(strlen(filename) + 10), "");
Elliott Hughese8b663f2016-05-26 22:43:19 -0700896 return 0;
Doug Zongker71fe5842014-06-26 15:35:36 -0700897 }
898
Doug Zongker71fe5842014-06-26 15:35:36 -0700899 int block = strtol(buf, NULL, 10);
900
901 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700902 if (offset >= static_cast<size_t>(sb.st_size)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700903 fprintf(stderr, "* attempt to read block %d past end\n", block);
Elliott Hughese8b663f2016-05-26 22:43:19 -0700904 return -1;
Doug Zongker71fe5842014-06-26 15:35:36 -0700905 }
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700906
Doug Zongker71fe5842014-06-26 15:35:36 -0700907 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700908 if ((offset + SIDELOAD_HOST_BLOCK_SIZE) > static_cast<size_t>(sb.st_size)) {
909 to_write = sb.st_size - offset;
Doug Zongker71fe5842014-06-26 15:35:36 -0700910 }
911
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700912 if (adb_lseek(package_fd, offset, SEEK_SET) != static_cast<int>(offset)) {
913 fprintf(stderr, "* failed to seek to package block: %s\n", strerror(errno));
914 return -1;
915 }
916 if (!ReadFdExactly(package_fd, buf, to_write)) {
917 fprintf(stderr, "* failed to read package block: %s\n", strerror(errno));
918 return -1;
919 }
920
921 if (!WriteFdExactly(device_fd, buf, to_write)) {
922 adb_status(device_fd, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700923 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Elliott Hughese8b663f2016-05-26 22:43:19 -0700924 return -1;
Doug Zongker71fe5842014-06-26 15:35:36 -0700925 }
926 xfer += to_write;
927
928 // For normal OTA packages, we expect to transfer every byte
929 // twice, plus a bit of overhead (one read during
930 // verification, one read of each byte for installation, plus
931 // extra access to things like the zip central directory).
932 // This estimate of the completion becomes 100% when we've
933 // transferred ~2.13 (=100/47) times the package size.
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700934 int percent = static_cast<int>(xfer * 47LL / (sb.st_size ? sb.st_size : 1));
Doug Zongker71fe5842014-06-26 15:35:36 -0700935 if (percent != last_percent) {
Elliott Hughesee1ac7102017-03-21 17:14:18 -0700936 printf("\rserving: '%s' (~%d%%) ", filename, percent);
Doug Zongker71fe5842014-06-26 15:35:36 -0700937 fflush(stdout);
938 last_percent = percent;
939 }
940 }
Doug Zongker71fe5842014-06-26 15:35:36 -0700941}
942
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800943/**
944 * Run ppp in "notty" mode against a resource listed as the first parameter
945 * eg:
946 *
947 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
948 *
949 */
Elliott Hughes58305772015-04-17 13:57:15 -0700950static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800951#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800952 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
953 return -1;
954#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800955 if (argc < 2) {
956 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
957 argv[0]);
958
959 return 1;
960 }
961
Dan Albertbac34742015-02-25 17:51:28 -0800962 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700963 std::string error;
964 int fd = adb_connect(adb_service_name, &error);
965 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800966 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700967 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800968 return 1;
969 }
970
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700971 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800972
973 if (pid < 0) {
974 perror("from fork()");
975 return 1;
976 } else if (pid == 0) {
977 int err;
978 int i;
979 const char **ppp_args;
980
981 // copy args
982 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
983 ppp_args[0] = "pppd";
984 for (i = 2 ; i < argc ; i++) {
985 //argv[2] and beyond become ppp_args[1] and beyond
986 ppp_args[i - 1] = argv[i];
987 }
988 ppp_args[i-1] = NULL;
989
990 // child side
991
992 dup2(fd, STDIN_FILENO);
993 dup2(fd, STDOUT_FILENO);
994 adb_close(STDERR_FILENO);
995 adb_close(fd);
996
997 err = execvp("pppd", (char * const *)ppp_args);
998
999 if (err < 0) {
1000 perror("execing pppd");
1001 }
1002 exit(-1);
1003 } else {
1004 // parent side
1005
1006 adb_close(fd);
1007 return 0;
1008 }
Yabin Cuie77b6a02014-11-11 09:24:11 -08001009#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001010}
1011
Josh Gao08881e72016-04-13 12:14:16 -07001012static bool wait_for_device(const char* service, TransportType t, const char* serial) {
1013 std::vector<std::string> components = android::base::Split(service, "-");
1014 if (components.size() < 3 || components.size() > 4) {
Leo Sartre1fbc9db2015-11-27 18:56:48 +01001015 fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service);
1016 return false;
1017 }
1018
Elliott Hughes2b101112015-05-04 19:29:32 -07001019 // Was the caller vague about what they'd like us to wait for?
1020 // If so, check they weren't more specific in their choice of transport type.
Josh Gao08881e72016-04-13 12:14:16 -07001021 if (components.size() == 3) {
1022 auto it = components.begin() + 2;
Elliott Hughes2b101112015-05-04 19:29:32 -07001023 if (t == kTransportUsb) {
Josh Gao08881e72016-04-13 12:14:16 -07001024 components.insert(it, "usb");
Elliott Hughes2b101112015-05-04 19:29:32 -07001025 } else if (t == kTransportLocal) {
Josh Gao08881e72016-04-13 12:14:16 -07001026 components.insert(it, "local");
Elliott Hughes2b101112015-05-04 19:29:32 -07001027 } else {
Josh Gao08881e72016-04-13 12:14:16 -07001028 components.insert(it, "any");
Elliott Hughes2b101112015-05-04 19:29:32 -07001029 }
Josh Gao08881e72016-04-13 12:14:16 -07001030 } else if (components[2] != "any" && components[2] != "local" && components[2] != "usb") {
1031 fprintf(stderr, "adb: unknown type %s; expected 'any', 'local', or 'usb'\n",
1032 components[2].c_str());
Leo Sartre1fbc9db2015-11-27 18:56:48 +01001033 return false;
1034 }
1035
Josh Gao86441c32016-04-13 12:18:58 -07001036 if (components[3] != "any" && components[3] != "bootloader" && components[3] != "device" &&
1037 components[3] != "recovery" && components[3] != "sideload") {
Josh Gao08881e72016-04-13 12:14:16 -07001038 fprintf(stderr,
1039 "adb: unknown state %s; "
Josh Gao86441c32016-04-13 12:18:58 -07001040 "expected 'any', 'bootloader', 'device', 'recovery', or 'sideload'\n",
Josh Gao08881e72016-04-13 12:14:16 -07001041 components[3].c_str());
1042 return false;
1043 }
1044
1045 std::string cmd = format_host_command(android::base::Join(components, "-").c_str(), t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -07001046 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -07001047}
1048
Josh Gao06c73ae2016-03-04 15:16:18 -08001049static bool adb_root(const char* command) {
1050 std::string error;
Josh Gao06c73ae2016-03-04 15:16:18 -08001051
Elliott Hughese8b663f2016-05-26 22:43:19 -07001052 unique_fd fd(adb_connect(android::base::StringPrintf("%s:", command), &error));
1053 if (fd < 0) {
Josh Gao06c73ae2016-03-04 15:16:18 -08001054 fprintf(stderr, "adb: unable to connect for %s: %s\n", command, error.c_str());
1055 return false;
1056 }
1057
1058 // Figure out whether we actually did anything.
1059 char buf[256];
1060 char* cur = buf;
1061 ssize_t bytes_left = sizeof(buf);
1062 while (bytes_left > 0) {
Elliott Hughese8b663f2016-05-26 22:43:19 -07001063 ssize_t bytes_read = adb_read(fd, cur, bytes_left);
Josh Gao06c73ae2016-03-04 15:16:18 -08001064 if (bytes_read == 0) {
1065 break;
1066 } else if (bytes_read < 0) {
1067 fprintf(stderr, "adb: error while reading for %s: %s\n", command, strerror(errno));
1068 return false;
1069 }
1070 cur += bytes_read;
1071 bytes_left -= bytes_read;
1072 }
1073
1074 if (bytes_left == 0) {
1075 fprintf(stderr, "adb: unexpected output length for %s\n", command);
1076 return false;
1077 }
1078
1079 fflush(stdout);
1080 WriteFdExactly(STDOUT_FILENO, buf, sizeof(buf) - bytes_left);
1081 if (cur != buf && strstr(buf, "restarting") == nullptr) {
1082 return true;
1083 }
1084
Josh Gao05824732016-06-16 14:00:09 -07001085 // Give adbd some time to kill itself and come back up.
1086 // We can't use wait-for-device because devices (e.g. adb over network) might not come back.
Josh Gao4602adb2016-11-15 18:55:47 -08001087 std::this_thread::sleep_for(3s);
Josh Gao05824732016-06-16 14:00:09 -07001088 return true;
Josh Gao06c73ae2016-03-04 15:16:18 -08001089}
1090
Felipe Leme698e0652016-07-19 17:07:22 -07001091int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
Felipe Leme0d4f0502016-07-26 12:14:39 -07001092 bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001093 int fd;
David Pursell0aacbbe2016-01-21 19:56:50 -08001094 bool use_shell_protocol = false;
1095
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001096 while (true) {
David Pursell0aacbbe2016-01-21 19:56:50 -08001097 bool attempt_connection = true;
1098
Felipe Leme0d4f0502016-07-26 12:14:39 -07001099 // Use shell protocol if it's supported and the caller doesn't explicitly
1100 // disable it.
David Pursell0aacbbe2016-01-21 19:56:50 -08001101 if (!disable_shell_protocol) {
1102 FeatureSet features;
Josh Gaof3f6a1d2016-01-31 19:12:26 -08001103 std::string error;
1104 if (adb_get_feature_set(&features, &error)) {
David Pursell0aacbbe2016-01-21 19:56:50 -08001105 use_shell_protocol = CanUseFeature(features, kFeatureShell2);
1106 } else {
1107 // Device was unreachable.
1108 attempt_connection = false;
1109 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001110 }
David Pursell0aacbbe2016-01-21 19:56:50 -08001111
1112 if (attempt_connection) {
1113 std::string error;
1114 std::string service_string = ShellServiceString(use_shell_protocol, "", command);
1115
1116 fd = adb_connect(service_string, &error);
1117 if (fd >= 0) {
1118 break;
1119 }
1120 }
1121
Felipe Leme0d4f0502016-07-26 12:14:39 -07001122 fprintf(stderr, "- waiting for device -\n");
Josh Gaob6117c42016-02-24 15:16:17 -08001123 if (!wait_for_device("wait-for-device", transport_type, serial)) {
1124 return 1;
1125 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001126 }
1127
Felipe Leme0d4f0502016-07-26 12:14:39 -07001128 int exit_code = read_and_dump(fd, use_shell_protocol, callback);
David Pursell71c83122015-09-14 15:33:50 -07001129
1130 if (adb_close(fd) < 0) {
1131 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001132 }
David Pursell71c83122015-09-14 15:33:50 -07001133
1134 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001135}
1136
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001137static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001138 char* log_tags = getenv("ANDROID_LOG_TAGS");
1139 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001140
David Pursell70ef7b42015-09-30 13:35:42 -07001141 std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001142
Jeff Sharkeyfd546e82014-06-10 11:31:24 -07001143 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001144 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -08001145 }
1146
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001147 --argc;
1148 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001149 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001150 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001151 }
1152
David Pursell70ef7b42015-09-30 13:35:42 -07001153 // No need for shell protocol with logcat, always disable for simplicity.
1154 return send_shell_command(transport, serial, cmd, true);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001155}
1156
Christopher Tatec42f1bb2016-07-06 13:22:22 -07001157static void write_zeros(int bytes, int fd) {
1158 int old_stdin_mode = -1;
1159 int old_stdout_mode = -1;
1160 char* buf = (char*) calloc(1, bytes);
1161 if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros");
1162
1163 D("write_zeros(%d) -> %d", bytes, fd);
1164
1165 stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
1166
1167 if (fd == STDOUT_FILENO) {
1168 fwrite(buf, 1, bytes, stdout);
1169 fflush(stdout);
1170 } else {
1171 adb_write(fd, buf, bytes);
1172 }
1173
1174 stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
1175
1176 D("write_zeros() finished");
1177 free(buf);
1178}
1179
Dan Albertbac34742015-02-25 17:51:28 -08001180static int backup(int argc, const char** argv) {
Elliott Hughes24f165f2015-08-21 20:31:31 -07001181 const char* filename = "backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -07001182
Christopher Tatec9cd3b92011-06-01 17:56:23 -07001183 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001184 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -07001185 if (!strcmp("-f", argv[i])) {
1186 if (i == argc-1) {
Elliott Hughes56e68132015-11-13 11:04:10 -08001187 fprintf(stderr, "adb: backup -f passed with no filename.\n");
1188 return EXIT_FAILURE;
Christopher Tatec9cd3b92011-06-01 17:56:23 -07001189 }
1190 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001191 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -07001192 argv[i++] = argv[j++];
1193 }
1194 argc -= 2;
1195 argv[argc] = NULL;
1196 }
Christopher Tated2f54152011-04-21 12:53:28 -07001197 }
1198
Elliott Hughes56e68132015-11-13 11:04:10 -08001199 // Bare "adb backup" or "adb backup -f filename" are not valid invocations ---
1200 // a list of packages is required.
1201 if (argc < 2) {
1202 fprintf(stderr, "adb: backup either needs a list of packages or -all/-shared.\n");
1203 return EXIT_FAILURE;
1204 }
Christopher Tatebb86bc52011-08-22 17:12:08 -07001205
Christopher Tateb1dfffe2011-12-08 19:04:34 -08001206 adb_unlink(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001207 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -07001208 if (outFd < 0) {
Elliott Hughes56e68132015-11-13 11:04:10 -08001209 fprintf(stderr, "adb: backup unable to create file '%s': %s\n", filename, strerror(errno));
1210 return EXIT_FAILURE;
Christopher Tated2f54152011-04-21 12:53:28 -07001211 }
1212
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001213 std::string cmd = "backup:";
1214 --argc;
1215 ++argv;
1216 while (argc-- > 0) {
1217 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -07001218 }
1219
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001220 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001221 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001222 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -07001223 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001224 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -07001225 adb_close(outFd);
Elliott Hughes56e68132015-11-13 11:04:10 -08001226 return EXIT_FAILURE;
Christopher Tated2f54152011-04-21 12:53:28 -07001227 }
1228
Elliott Hughes56e68132015-11-13 11:04:10 -08001229 printf("Now unlock your device and confirm the backup operation...\n");
1230 fflush(stdout);
1231
Christopher Tated2f54152011-04-21 12:53:28 -07001232 copy_to_file(fd, outFd);
1233
1234 adb_close(fd);
1235 adb_close(outFd);
Elliott Hughes56e68132015-11-13 11:04:10 -08001236 return EXIT_SUCCESS;
Christopher Tated2f54152011-04-21 12:53:28 -07001237}
1238
Dan Albertbac34742015-02-25 17:51:28 -08001239static int restore(int argc, const char** argv) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001240 if (argc != 2) return usage("restore requires an argument");
Christopher Tate702967a2011-05-17 15:52:54 -07001241
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001242 const char* filename = argv[1];
1243 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -07001244 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001245 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -07001246 return -1;
1247 }
1248
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001249 std::string error;
1250 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -07001251 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001252 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -07001253 adb_close(tarFd);
1254 return -1;
1255 }
1256
Christopher Tatebffa4ca2012-01-06 15:43:03 -08001257 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -07001258 copy_to_file(tarFd, fd);
1259
Christopher Tatec42f1bb2016-07-06 13:22:22 -07001260 // Provide an in-band EOD marker in case the archive file is malformed
1261 write_zeros(512*2, fd);
1262
Josh Gao5767d0d2016-03-04 15:51:03 -08001263 // Wait until the other side finishes, or it'll get sent SIGHUP.
1264 copy_to_file(fd, STDOUT_FILENO);
1265
Christopher Tate702967a2011-05-17 15:52:54 -07001266 adb_close(fd);
1267 adb_close(tarFd);
1268 return 0;
1269}
1270
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001271/* <hint> may be:
1272 * - A simple product name
1273 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001274 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1275 * e.g., "out/target/product/sooner"
1276 * - An absolute path to the PRODUCT_OUT dir
1277 * e.g., "/src/device/out/target/product/sooner"
1278 *
1279 * Given <hint>, try to construct an absolute path to the
1280 * ANDROID_PRODUCT_OUT dir.
1281 */
Elliott Hughes5c742702015-07-30 17:42:01 -07001282static std::string find_product_out_path(const std::string& hint) {
1283 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -07001284 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001285 }
1286
Elliott Hughes58305772015-04-17 13:57:15 -07001287 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -07001288 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -07001289 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001290 }
1291
Chih-Hung Hsieh8f7b9e32016-07-27 16:25:51 -07001292 // If any of the OS_PATH_SEPARATORS is found, assume it's a relative path;
Elliott Hughes58305772015-04-17 13:57:15 -07001293 // make it absolute.
Chih-Hung Hsieh8f7b9e32016-07-27 16:25:51 -07001294 // NOLINT: Do not complain if OS_PATH_SEPARATORS has only one character.
1295 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) { // NOLINT
Elliott Hughesa7090b92015-04-17 17:03:59 -07001296 std::string cwd;
1297 if (!getcwd(&cwd)) {
Felipe Lemeb3239722016-07-29 17:57:00 -07001298 perror("adb: getcwd failed");
Elliott Hughes58305772015-04-17 13:57:15 -07001299 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001300 }
Elliott Hughes5c742702015-07-30 17:42:01 -07001301 return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001302 }
1303
Elliott Hughes58305772015-04-17 13:57:15 -07001304 // It's a string without any slashes. Try to do something with it.
1305 //
1306 // Try to find the root of the build tree, and build a PRODUCT_OUT
1307 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -07001308 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -07001309 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -07001310 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -07001311 return "";
1312 }
Elliott Hughesa7090b92015-04-17 17:03:59 -07001313
1314 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -07001315 path += OS_PATH_SEPARATOR_STR;
1316 path += "out";
1317 path += OS_PATH_SEPARATOR_STR;
1318 path += "target";
1319 path += OS_PATH_SEPARATOR_STR;
1320 path += "product";
1321 path += OS_PATH_SEPARATOR_STR;
1322 path += hint;
1323 if (!directory_exists(path)) {
1324 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -07001325 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -07001326 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001327 }
Elliott Hughes58305772015-04-17 13:57:15 -07001328 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001329}
1330
Josh Gao05786772015-10-30 16:57:19 -07001331static void parse_push_pull_args(const char** arg, int narg,
1332 std::vector<const char*>* srcs,
1333 const char** dst, bool* copy_attrs) {
1334 *copy_attrs = false;
Mark Lindner76f2a932014-03-11 17:55:59 -07001335
Josh Gao05786772015-10-30 16:57:19 -07001336 srcs->clear();
1337 bool ignore_flags = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001338 while (narg > 0) {
Josh Gao05786772015-10-30 16:57:19 -07001339 if (ignore_flags || *arg[0] != '-') {
1340 srcs->push_back(*arg);
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001341 } else {
Josh Gao05786772015-10-30 16:57:19 -07001342 if (!strcmp(*arg, "-p")) {
1343 // Silently ignore for backwards compatibility.
1344 } else if (!strcmp(*arg, "-a")) {
1345 *copy_attrs = true;
1346 } else if (!strcmp(*arg, "--")) {
1347 ignore_flags = true;
1348 } else {
1349 fprintf(stderr, "adb: unrecognized option '%s'\n", *arg);
1350 exit(1);
1351 }
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001352 }
Mark Lindner76f2a932014-03-11 17:55:59 -07001353 ++arg;
1354 --narg;
1355 }
1356
Josh Gao05786772015-10-30 16:57:19 -07001357 if (srcs->size() > 1) {
1358 *dst = srcs->back();
1359 srcs->pop_back();
Mark Lindner76f2a932014-03-11 17:55:59 -07001360 }
1361}
1362
Elliott Hughes6452a892015-04-29 12:28:13 -07001363static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001364 std::string error;
1365 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001366 if (fd < 0) {
1367 fprintf(stderr, "error: %s\n", error.c_str());
1368 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001369 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001370 read_and_dump(fd);
1371 adb_close(fd);
1372 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001373}
1374
Elliott Hughes6452a892015-04-29 12:28:13 -07001375static int adb_query_command(const std::string& command) {
1376 std::string result;
1377 std::string error;
1378 if (!adb_query(command, &result, &error)) {
1379 fprintf(stderr, "error: %s\n", error.c_str());
1380 return 1;
1381 }
1382 printf("%s\n", result.c_str());
1383 return 0;
1384}
1385
Spencer Lowa13df302015-09-07 16:20:13 -07001386// Disallow stdin, stdout, and stderr.
1387static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1388#ifdef _WIN32
1389 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1390 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1391 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1392 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1393#else
1394 return ack_reply_fd > 2;
1395#endif
1396}
1397
Todd Kennedy248722e2016-07-20 16:22:37 -07001398static bool _use_legacy_install() {
1399 FeatureSet features;
1400 std::string error;
1401 if (!adb_get_feature_set(&features, &error)) {
1402 fprintf(stderr, "error: %s\n", error.c_str());
1403 return true;
1404 }
1405 return !CanUseFeature(features, kFeatureCmd);
1406}
1407
Elliott Hughescabfa112016-10-19 14:47:11 -07001408int adb_commandline(int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001409 int no_daemon = 0;
1410 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001411 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001412 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001413 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001414 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001415
Elliott Hughes65433da2015-11-18 18:07:48 -08001416#if !defined(_WIN32)
1417 // We'd rather have EPIPE than SIGPIPE.
1418 signal(SIGPIPE, SIG_IGN);
1419#endif
1420
Elliott Hughes58305772015-04-17 13:57:15 -07001421 // If defined, this should be an absolute path to
1422 // the directory containing all of the various system images
1423 // for a particular product. If not defined, and the adb
1424 // command requires this information, then the user must
1425 // specify the path using "-p".
1426 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1427 if (ANDROID_PRODUCT_OUT != nullptr) {
1428 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001429 }
1430 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1431
Josh Gao9c869b52016-08-25 16:00:22 -07001432 const char* server_host_str = nullptr;
1433 const char* server_port_str = nullptr;
1434 const char* server_socket_str = nullptr;
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001435
Elliott Hughes8d28e192015-10-07 14:55:10 -07001436 // We need to check for -d and -e before we look at $ANDROID_SERIAL.
1437 const char* serial = nullptr;
1438
Riley Andrews98f58e82014-12-05 17:37:24 -08001439 while (argc > 0) {
1440 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001441 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001442 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001443 no_daemon = 1;
1444 } else if (!strcmp(argv[0], "fork-server")) {
1445 /* this is a special flag used only when the ADB client launches the ADB Server */
1446 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001447 } else if (!strcmp(argv[0], "--reply-fd")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001448 if (argc < 2) return usage("--reply-fd requires an argument");
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001449 const char* reply_fd_str = argv[1];
1450 argc--;
1451 argv++;
1452 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001453 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001454 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001455 return 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001456 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001457 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001458 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001459 if (argv[0][2] == '\0') {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001460 if (argc < 2) return usage("-p requires an argument");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001461 product = argv[1];
1462 argc--;
1463 argv++;
1464 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001465 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001466 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001467 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001468 if (gProductOutPath.empty()) {
1469 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001470 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001471 }
1472 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1473 if (isdigit(argv[0][2])) {
1474 serial = argv[0] + 2;
1475 } else {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001476 if (argc < 2 || argv[0][2] != '\0') return usage("-s requires an argument");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001477 serial = argv[1];
1478 argc--;
1479 argv++;
1480 }
1481 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001482 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001483 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001484 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001485 } else if (!strcmp(argv[0],"-a")) {
1486 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001487 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001488 if (argv[0][2] == '\0') {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001489 if (argc < 2) return usage("-H requires an argument");
Josh Gao9c869b52016-08-25 16:00:22 -07001490 server_host_str = argv[1];
Matt Gumbeld7b33082012-11-14 10:16:17 -08001491 argc--;
1492 argv++;
1493 } else {
Josh Gao9c869b52016-08-25 16:00:22 -07001494 server_host_str = argv[0] + 2;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001495 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001496 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001497 if (argv[0][2] == '\0') {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001498 if (argc < 2) return usage("-P requires an argument");
Matt Gumbeld7b33082012-11-14 10:16:17 -08001499 server_port_str = argv[1];
1500 argc--;
1501 argv++;
1502 } else {
1503 server_port_str = argv[0] + 2;
1504 }
Josh Gao9c869b52016-08-25 16:00:22 -07001505 } else if (!strcmp(argv[0], "-L")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001506 if (argc < 2) return usage("-L requires an argument");
Josh Gao9c869b52016-08-25 16:00:22 -07001507 server_socket_str = argv[1];
1508 argc--;
1509 argv++;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001510 } else {
Josh Gao9c869b52016-08-25 16:00:22 -07001511 /* out of recognized modifiers and flags */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001512 break;
1513 }
1514 argc--;
1515 argv++;
1516 }
1517
Josh Gao9c869b52016-08-25 16:00:22 -07001518 if ((server_host_str || server_port_str) && server_socket_str) {
1519 fprintf(stderr, "adb: -L is incompatible with -H or -P\n");
1520 exit(1);
1521 }
1522
1523 // If -L, -H, or -P are specified, ignore environment variables.
1524 // Otherwise, prefer ADB_SERVER_SOCKET over ANDROID_ADB_SERVER_ADDRESS/PORT.
Tao Wu135f4ab2016-09-16 13:01:24 -07001525 if (!server_host_str && !server_port_str && !server_socket_str) {
1526 server_socket_str = getenv("ADB_SERVER_SOCKET");
Josh Gao9c869b52016-08-25 16:00:22 -07001527 }
1528
1529 if (!server_socket_str) {
1530 // tcp:1234 and tcp:localhost:1234 are different with -a, so don't default to localhost
1531 server_host_str = server_host_str ? server_host_str : getenv("ANDROID_ADB_SERVER_ADDRESS");
1532
Tao Wu135f4ab2016-09-16 13:01:24 -07001533 int server_port = DEFAULT_ADB_PORT;
Josh Gao9c869b52016-08-25 16:00:22 -07001534 server_port_str = server_port_str ? server_port_str : getenv("ANDROID_ADB_SERVER_PORT");
Tao Wu135f4ab2016-09-16 13:01:24 -07001535 if (server_port_str && strlen(server_port_str) > 0) {
1536 if (!android::base::ParseInt(server_port_str, &server_port, 1, 65535)) {
1537 fprintf(stderr,
1538 "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive"
1539 " number less than 65535. Got \"%s\"\n",
1540 server_port_str);
1541 exit(1);
1542 }
1543 }
Josh Gao9c869b52016-08-25 16:00:22 -07001544
1545 int rc;
1546 char* temp;
1547 if (server_host_str) {
Tao Wu135f4ab2016-09-16 13:01:24 -07001548 rc = asprintf(&temp, "tcp:%s:%d", server_host_str, server_port);
Josh Gao9c869b52016-08-25 16:00:22 -07001549 } else {
Tao Wu135f4ab2016-09-16 13:01:24 -07001550 rc = asprintf(&temp, "tcp:%d", server_port);
Josh Gao9c869b52016-08-25 16:00:22 -07001551 }
1552 if (rc < 0) {
1553 fatal("failed to allocate server socket specification");
1554 }
1555 server_socket_str = temp;
1556 }
1557
1558 adb_set_socket_spec(server_socket_str);
1559
Elliott Hughes8d28e192015-10-07 14:55:10 -07001560 // If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
1561 if (transport_type == kTransportAny && serial == nullptr) {
1562 serial = getenv("ANDROID_SERIAL");
1563 }
1564
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001565 adb_set_transport(transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001566
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001567 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001568 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001569 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001570 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001571 return 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001572 }
Josh Gao9c869b52016-08-25 16:00:22 -07001573 r = adb_server_main(is_daemon, server_socket_str, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001574 } else {
Josh Gao9c869b52016-08-25 16:00:22 -07001575 r = launch_server(server_socket_str);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001576 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001577 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001578 fprintf(stderr,"* could not start server *\n");
1579 }
1580 return r;
1581 }
1582
Riley Andrews98f58e82014-12-05 17:37:24 -08001583 if (argc == 0) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001584 help();
1585 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001586 }
1587
Riley Andrewsc8514c82014-12-05 17:32:46 -08001588 /* handle wait-for-* prefix */
1589 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001590 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001591
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001592 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001593 return 1;
1594 }
1595
Elliott Hughes2b101112015-05-04 19:29:32 -07001596 // Allow a command to be run after wait-for-device,
1597 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001598 if (argc == 1) {
1599 return 0;
1600 }
1601
1602 /* Fall through */
1603 argc--;
1604 argv++;
1605 }
1606
1607 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001608 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001609 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001610 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001611 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001612 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001613 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001614 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001615 fprintf(stderr, "Usage: adb devices [-l]\n");
1616 return 1;
1617 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001618
1619 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1620 printf("List of devices attached\n");
1621 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001622 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001623 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001624 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001625 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001626 return 1;
1627 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001628
1629 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1630 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001631 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001632 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001633 if (argc > 2) {
1634 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1635 return 1;
1636 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001637
1638 std::string query = android::base::StringPrintf("host:disconnect:%s",
1639 (argc == 2) ? argv[1] : "");
1640 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001641 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001642 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001643 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001644 }
Elliott Hughesc15b17f2015-11-03 11:18:40 -08001645 else if (!strcmp(argv[0], "shell")) {
Josh Gaof3f6a1d2016-01-31 19:12:26 -08001646 return adb_shell(argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001647 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001648 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001649 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001650
Zach Riggleccafc792016-04-14 17:18:04 -04001651 if (argc < 2) {
1652 fprintf(stderr, "Usage: adb %s command\n", argv[0]);
1653 return 1;
1654 }
1655
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001656 std::string cmd = "exec:";
1657 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001658 argc -= 2;
1659 argv += 2;
1660 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001661 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001662 }
1663
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001664 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001665 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001666 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001667 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001668 return -1;
1669 }
1670
1671 if (exec_in) {
1672 copy_to_file(STDIN_FILENO, fd);
1673 } else {
1674 copy_to_file(fd, STDOUT_FILENO);
1675 }
1676
1677 adb_close(fd);
1678 return 0;
1679 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001680 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001681 std::string error;
1682 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001683 if (fd == -2) {
1684 // Failed to make network connection to server. Don't output the
1685 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001686 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001687 // Successful exit code because the server is already "killed".
1688 return 0;
1689 } else if (fd == -1) {
1690 // Some other error.
1691 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001692 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001693 } else {
1694 // Successfully connected, kill command sent, okay status came back.
1695 // Server should exit() in a moment, if not already.
Spencer Low351ecd12015-10-14 17:32:44 -07001696 ReadOrderlyShutdown(fd);
Spencer Lowf18fc082015-08-11 17:05:02 -07001697 adb_close(fd);
1698 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001699 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001700 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001701 else if (!strcmp(argv[0], "sideload")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001702 if (argc != 2) return usage("sideload requires an argument");
Doug Zongker71fe5842014-06-26 15:35:36 -07001703 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001704 return 1;
1705 } else {
1706 return 0;
1707 }
1708 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001709 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1710 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1711 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001712 else if (!strcmp(argv[0], "remount") ||
1713 !strcmp(argv[0], "reboot") ||
1714 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001715 !strcmp(argv[0], "usb") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001716 !strcmp(argv[0], "disable-verity") ||
1717 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001718 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001719 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001720 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001721 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001722 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001723 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001724 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001725 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001726 return adb_connect_command(command);
Josh Gao06c73ae2016-03-04 15:16:18 -08001727 } else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
1728 return adb_root(argv[0]) ? 0 : 1;
1729 } else if (!strcmp(argv[0], "bugreport")) {
Felipe Leme698e0652016-07-19 17:07:22 -07001730 Bugreport bugreport;
1731 return bugreport.DoIt(transport_type, serial, argc, argv);
Felipe Leme44a42672016-04-01 17:43:27 -07001732 } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001733 bool reverse = !strcmp(argv[0], "reverse");
1734 ++argv;
1735 --argc;
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001736 if (argc < 1) return usage("%s requires an argument", argv[0]);
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001737
1738 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001739 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001740 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001741 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001742 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001743 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001744 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001745 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001746 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001747 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001748 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001749 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001750 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001751 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001752 }
1753
David Purselleaae97e2016-04-07 11:25:48 -07001754 std::string cmd, error;
Elliott Hughes424af022015-05-29 17:55:19 -07001755 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001756 if (argc != 1) return usage("--list doesn't take any arguments");
Elliott Hughes424af022015-05-29 17:55:19 -07001757 return adb_query_command(host_prefix + ":list-forward");
1758 } else if (strcmp(argv[0], "--remove-all") == 0) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001759 if (argc != 1) return usage("--remove-all doesn't take any arguments");
Elliott Hughes424af022015-05-29 17:55:19 -07001760 cmd = host_prefix + ":killforward-all";
1761 } else if (strcmp(argv[0], "--remove") == 0) {
1762 // forward --remove <local>
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001763 if (argc != 2) return usage("--remove requires an argument");
Elliott Hughes424af022015-05-29 17:55:19 -07001764 cmd = host_prefix + ":killforward:" + argv[1];
1765 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1766 // forward --no-rebind <local> <remote>
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001767 if (argc != 3) return usage("--no-rebind takes two arguments");
David Purselleaae97e2016-04-07 11:25:48 -07001768 if (forward_targets_are_valid(argv[1], argv[2], &error)) {
1769 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1770 }
Elliott Hughes424af022015-05-29 17:55:19 -07001771 } else {
1772 // forward <local> <remote>
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001773 if (argc != 2) return usage("forward takes two arguments");
David Purselleaae97e2016-04-07 11:25:48 -07001774 if (forward_targets_are_valid(argv[0], argv[1], &error)) {
1775 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
1776 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001777 }
1778
David Purselleaae97e2016-04-07 11:25:48 -07001779 if (!error.empty()) {
1780 fprintf(stderr, "error: %s\n", error.c_str());
1781 return 1;
1782 }
1783
1784 int fd = adb_connect(cmd, &error);
1785 if (fd < 0 || !adb_status(fd, &error)) {
1786 adb_close(fd);
1787 fprintf(stderr, "error: %s\n", error.c_str());
1788 return 1;
1789 }
1790
1791 // Server or device may optionally return a resolved TCP port number.
1792 std::string resolved_port;
1793 if (ReadProtocolString(fd, &resolved_port, &error) && !resolved_port.empty()) {
1794 printf("%s\n", resolved_port.c_str());
1795 }
1796
1797 ReadOrderlyShutdown(fd);
1798 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001799 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001800 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001801 else if (!strcmp(argv[0], "ls")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001802 if (argc != 2) return usage("ls requires an argument");
Elliott Hughesaa245492015-08-03 10:38:08 -07001803 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001804 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001805 else if (!strcmp(argv[0], "push")) {
Josh Gao05786772015-10-30 16:57:19 -07001806 bool copy_attrs = false;
1807 std::vector<const char*> srcs;
1808 const char* dst = nullptr;
Mark Lindner76f2a932014-03-11 17:55:59 -07001809
Josh Gao05786772015-10-30 16:57:19 -07001810 parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs);
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001811 if (srcs.empty() || !dst) return usage("push requires an argument");
Josh Gao05786772015-10-30 16:57:19 -07001812 return do_sync_push(srcs, dst) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001813 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001814 else if (!strcmp(argv[0], "pull")) {
Josh Gao05786772015-10-30 16:57:19 -07001815 bool copy_attrs = false;
1816 std::vector<const char*> srcs;
1817 const char* dst = ".";
Mark Lindner76f2a932014-03-11 17:55:59 -07001818
Josh Gao05786772015-10-30 16:57:19 -07001819 parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs);
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001820 if (srcs.empty()) return usage("pull requires an argument");
Josh Gao05786772015-10-30 16:57:19 -07001821 return do_sync_pull(srcs, dst, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001822 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001823 else if (!strcmp(argv[0], "install")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001824 if (argc < 2) return usage("install requires an argument");
Todd Kennedy248722e2016-07-20 16:22:37 -07001825 if (_use_legacy_install()) {
1826 return install_app_legacy(transport_type, serial, argc, argv);
David Pursell0aacbbe2016-01-21 19:56:50 -08001827 }
Todd Kennedy248722e2016-07-20 16:22:37 -07001828 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001829 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001830 else if (!strcmp(argv[0], "install-multiple")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001831 if (argc < 2) return usage("install-multiple requires an argument");
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001832 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001833 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001834 else if (!strcmp(argv[0], "uninstall")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001835 if (argc < 2) return usage("uninstall requires an argument");
Todd Kennedy248722e2016-07-20 16:22:37 -07001836 if (_use_legacy_install()) {
1837 return uninstall_app_legacy(transport_type, serial, argc, argv);
David Pursell0aacbbe2016-01-21 19:56:50 -08001838 }
Todd Kennedy248722e2016-07-20 16:22:37 -07001839 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001840 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001841 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001842 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001843 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001844 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001845 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001846 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001847 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001848 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001849 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001850 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001851 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001852 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001853 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001854 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001855 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001856 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001857 } else {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001858 return usage("usage: adb sync [-l] [PARTITION]");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001859 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001860
Elliott Hughesd236d072015-04-21 10:17:07 -07001861 if (src != "" &&
1862 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001863 return usage("don't know how to sync %s partition", src.c_str());
Elliott Hughes58305772015-04-17 13:57:15 -07001864 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001865
Elliott Hughes58305772015-04-17 13:57:15 -07001866 std::string system_src_path = product_file("system");
1867 std::string data_src_path = product_file("data");
1868 std::string vendor_src_path = product_file("vendor");
1869 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001870
Elliott Hughesaa245492015-08-03 10:38:08 -07001871 bool okay = true;
1872 if (okay && (src.empty() || src == "system")) {
1873 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001874 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001875 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1876 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001877 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001878 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1879 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001880 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001881 if (okay && (src.empty() || src == "data")) {
1882 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001883 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001884 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001885 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001886 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001887 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001888 !strcmp(argv[0],"get-serialno") ||
1889 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001890 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001891 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001892 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001893 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001894 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001895 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001896 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001897 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001898 return ppp(argc, argv);
1899 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001900 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001901 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001902 const int result = adb_connect("host:start-server", &error);
1903 if (result < 0) {
1904 fprintf(stderr, "error: %s\n", error.c_str());
1905 }
1906 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001907 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001908 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001909 return backup(argc, argv);
1910 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001911 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001912 return restore(argc, argv);
1913 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001914 else if (!strcmp(argv[0], "keygen")) {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001915 if (argc != 2) return usage("keygen requires an argument");
Yabin Cuiaed3c612015-09-22 15:52:57 -07001916 // Always print key generation information for keygen command.
1917 adb_trace_enable(AUTH);
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001918 return adb_auth_keygen(argv[1]);
1919 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001920 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001921 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001922 }
Josh Gaob463baf2016-05-13 18:18:23 -07001923 else if (!strcmp(argv[0], "track-jdwp")) {
1924 return adb_connect_command("track-jdwp");
1925 }
1926 else if (!strcmp(argv[0], "track-devices")) {
1927 return adb_connect_command("host:track-devices");
1928 }
1929
1930
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001931 /* "adb /?" is a common idiom under Windows */
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001932 else if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001933 help();
1934 return 0;
1935 }
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001936 else if (!strcmp(argv[0], "--version") || !strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001937 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001938 return 0;
Josh Gao5d1756c2017-02-22 17:07:01 -08001939 } else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001940 // Only list the features common to both the adb client and the device.
David Pursell0aacbbe2016-01-21 19:56:50 -08001941 FeatureSet features;
Josh Gaof3f6a1d2016-01-31 19:12:26 -08001942 std::string error;
1943 if (!adb_get_feature_set(&features, &error)) {
1944 fprintf(stderr, "error: %s\n", error.c_str());
David Pursell0aacbbe2016-01-21 19:56:50 -08001945 return 1;
1946 }
1947
David Pursell4e2fd362015-09-22 10:43:08 -07001948 for (const std::string& name : features) {
David Pursell70ef7b42015-09-30 13:35:42 -07001949 if (CanUseFeature(features, name)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001950 printf("%s\n", name.c_str());
1951 }
1952 }
1953 return 0;
Josh Gao5d1756c2017-02-22 17:07:01 -08001954 } else if (!strcmp(argv[0], "host-features")) {
1955 return adb_query_command("host:host-features");
Yabin Cui1f4ec192016-04-05 13:50:44 -07001956 } else if (!strcmp(argv[0], "reconnect")) {
1957 if (argc == 1) {
1958 return adb_query_command("host:reconnect");
Josh Gao22d2b3e2016-10-27 14:01:08 -07001959 } else if (argc == 2) {
1960 if (!strcmp(argv[1], "device")) {
1961 std::string err;
1962 adb_connect("reconnect", &err);
1963 return 0;
1964 } else if (!strcmp(argv[1], "offline")) {
1965 std::string err;
1966 return adb_query_command("host:reconnect-offline");
1967 } else {
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001968 return usage("usage: adb reconnect [device|offline]");
Josh Gao22d2b3e2016-10-27 14:01:08 -07001969 }
Yabin Cui1f4ec192016-04-05 13:50:44 -07001970 }
Dan Albert90d4b732015-05-20 18:58:41 -07001971 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001972
Elliott Hughes2ec36b02017-02-06 16:20:30 -08001973 usage("unknown command %s", argv[0]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001974 return 1;
1975}
1976
Todd Kennedy6fa848a2015-11-03 16:53:08 -08001977static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
1978 // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device
1979 std::string cmd = "cmd package";
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001980 while (argc-- > 0) {
Todd Kennedy6fa848a2015-11-03 16:53:08 -08001981 // deny the '-k' option until the remaining data/cache can be removed with adb/UI
1982 if (strcmp(*argv, "-k") == 0) {
1983 printf(
1984 "The -k option uninstalls the application while retaining the data/cache.\n"
1985 "At the moment, there is no way to remove the remaining data.\n"
1986 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1987 "If you truly wish to continue, execute 'adb shell cmd package uninstall -k'.\n");
1988 return EXIT_FAILURE;
1989 }
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001990 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001991 }
1992
David Pursell70ef7b42015-09-30 13:35:42 -07001993 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001994}
1995
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001996static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Todd Kennedy6fa848a2015-11-03 16:53:08 -08001997 // The last argument must be the APK file
1998 const char* file = argv[argc - 1];
Elliott Hughes72884782016-10-24 18:29:21 -07001999 if (!android::base::EndsWithIgnoreCase(file, ".apk")) {
2000 fprintf(stderr, "Filename doesn't end .apk: %s\n", file);
2001 return EXIT_FAILURE;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002002 }
2003
Elliott Hughes72884782016-10-24 18:29:21 -07002004 struct stat sb;
2005 if (stat(file, &sb) == -1) {
2006 fprintf(stderr, "Failed to stat %s: %s\n", file, strerror(errno));
2007 return 1;
Kenny Root597ea5b2011-08-05 11:19:45 -07002008 }
2009
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002010 int localFd = adb_open(file, O_RDONLY);
2011 if (localFd < 0) {
2012 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
2013 return 1;
2014 }
Kenny Root597ea5b2011-08-05 11:19:45 -07002015
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002016 std::string error;
2017 std::string cmd = "exec:cmd package";
2018
2019 // don't copy the APK name, but, copy the rest of the arguments as-is
2020 while (argc-- > 1) {
2021 cmd += " " + escape_arg(std::string(*argv++));
2022 }
2023
2024 // add size parameter [required for streaming installs]
2025 // do last to override any user specified value
2026 cmd += " " + android::base::StringPrintf("-S %" PRIu64, static_cast<uint64_t>(sb.st_size));
2027
2028 int remoteFd = adb_connect(cmd, &error);
2029 if (remoteFd < 0) {
2030 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
2031 adb_close(localFd);
2032 return 1;
2033 }
2034
2035 char buf[BUFSIZ];
2036 copy_to_file(localFd, remoteFd);
2037 read_status_line(remoteFd, buf, sizeof(buf));
2038
2039 adb_close(localFd);
2040 adb_close(remoteFd);
2041
2042 if (strncmp("Success", buf, 7)) {
Elliott Hughesfe018852015-12-17 14:04:38 -08002043 fprintf(stderr, "Failed to install %s: %s", file, buf);
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002044 return 1;
2045 }
2046 fputs(buf, stderr);
2047 return 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07002048}
2049
Elliott Hughes3bd73c12015-05-05 13:10:43 -07002050static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07002051 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07002052{
Jeff Sharkey960df972014-06-09 17:30:57 -07002053 // Find all APK arguments starting at end.
2054 // All other arguments passed through verbatim.
2055 int first_apk = -1;
Elliott Hughes72884782016-10-24 18:29:21 -07002056 uint64_t total_size = 0;
2057 for (int i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08002058 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07002059
Elliott Hughes72884782016-10-24 18:29:21 -07002060 if (android::base::EndsWithIgnoreCase(file, ".apk")) {
2061 struct stat sb;
2062 if (stat(file, &sb) != -1) total_size += sb.st_size;
Jeff Sharkey960df972014-06-09 17:30:57 -07002063 first_apk = i;
2064 } else {
2065 break;
2066 }
Kenny Root597ea5b2011-08-05 11:19:45 -07002067 }
2068
Jeff Sharkey960df972014-06-09 17:30:57 -07002069 if (first_apk == -1) {
Elliott Hughes72884782016-10-24 18:29:21 -07002070 fprintf(stderr, "No APK file on command line\n");
Jeff Sharkey960df972014-06-09 17:30:57 -07002071 return 1;
2072 }
Kenny Root597ea5b2011-08-05 11:19:45 -07002073
Todd Kennedy248722e2016-07-20 16:22:37 -07002074 std::string install_cmd;
2075 if (_use_legacy_install()) {
2076 install_cmd = "exec:pm";
2077 } else {
2078 install_cmd = "exec:cmd package";
2079 }
2080
2081 std::string cmd = android::base::StringPrintf("%s install-create -S %" PRIu64, install_cmd.c_str(), total_size);
Elliott Hughes72884782016-10-24 18:29:21 -07002082 for (int i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07002083 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07002084 }
2085
2086 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002087 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07002088 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07002089 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002090 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002091 return EXIT_FAILURE;
Jeff Sharkey960df972014-06-09 17:30:57 -07002092 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07002093 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07002094 read_status_line(fd, buf, sizeof(buf));
2095 adb_close(fd);
2096
2097 int session_id = -1;
2098 if (!strncmp("Success", buf, 7)) {
2099 char* start = strrchr(buf, '[');
2100 char* end = strrchr(buf, ']');
2101 if (start && end) {
2102 *end = '\0';
2103 session_id = strtol(start + 1, NULL, 10);
2104 }
2105 }
2106 if (session_id < 0) {
2107 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07002108 fputs(buf, stderr);
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002109 return EXIT_FAILURE;
Jeff Sharkey960df972014-06-09 17:30:57 -07002110 }
2111
2112 // Valid session, now stream the APKs
2113 int success = 1;
Elliott Hughes72884782016-10-24 18:29:21 -07002114 for (int i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08002115 const char* file = argv[i];
Elliott Hughes72884782016-10-24 18:29:21 -07002116 struct stat sb;
Jeff Sharkey960df972014-06-09 17:30:57 -07002117 if (stat(file, &sb) == -1) {
Elliott Hughes72884782016-10-24 18:29:21 -07002118 fprintf(stderr, "Failed to stat %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07002119 success = 0;
2120 goto finalize_session;
2121 }
2122
Elliott Hughes2940ccf2015-04-17 14:07:52 -07002123 std::string cmd = android::base::StringPrintf(
Todd Kennedy248722e2016-07-20 16:22:37 -07002124 "%s install-write -S %" PRIu64 " %d %d_%s -",
Colin Cross58021d12017-02-23 21:23:05 -08002125 install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i,
2126 android::base::Basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07002127
2128 int localFd = adb_open(file, O_RDONLY);
2129 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002130 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07002131 success = 0;
2132 goto finalize_session;
2133 }
2134
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002135 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07002136 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07002137 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002138 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07002139 adb_close(localFd);
2140 success = 0;
2141 goto finalize_session;
2142 }
2143
2144 copy_to_file(localFd, remoteFd);
2145 read_status_line(remoteFd, buf, sizeof(buf));
2146
2147 adb_close(localFd);
2148 adb_close(remoteFd);
2149
2150 if (strncmp("Success", buf, 7)) {
2151 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07002152 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07002153 success = 0;
2154 goto finalize_session;
2155 }
2156 }
2157
2158finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07002159 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07002160 std::string service =
Todd Kennedy248722e2016-07-20 16:22:37 -07002161 android::base::StringPrintf("%s install-%s %d",
2162 install_cmd.c_str(), success ? "commit" : "abandon", session_id);
Elliott Hughes6452a892015-04-29 12:28:13 -07002163 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07002164 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07002165 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002166 return EXIT_FAILURE;
Jeff Sharkey960df972014-06-09 17:30:57 -07002167 }
2168 read_status_line(fd, buf, sizeof(buf));
2169 adb_close(fd);
2170
2171 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07002172 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07002173 return 0;
2174 } else {
2175 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07002176 fputs(buf, stderr);
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002177 return EXIT_FAILURE;
Jeff Sharkey960df972014-06-09 17:30:57 -07002178 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002179}
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002180
2181static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
2182 std::string cmd = "pm";
2183
2184 while (argc-- > 0) {
2185 cmd += " " + escape_arg(*argv++);
2186 }
2187
2188 return send_shell_command(transport, serial, cmd, false);
2189}
2190
2191static int uninstall_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
2192 /* if the user choose the -k option, we refuse to do it until devices are
2193 out with the option to uninstall the remaining data somehow (adb/ui) */
2194 int i;
2195 for (i = 1; i < argc; i++) {
2196 if (!strcmp(argv[i], "-k")) {
2197 printf(
2198 "The -k option uninstalls the application while retaining the data/cache.\n"
2199 "At the moment, there is no way to remove the remaining data.\n"
2200 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
2201 "If you truly wish to continue, execute 'adb shell pm uninstall -k'\n.");
2202 return EXIT_FAILURE;
2203 }
2204 }
2205
2206 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
2207 return pm_command(transport, serial, argc, argv);
2208}
2209
2210static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
2211 std::string cmd = "rm -f " + escape_arg(filename);
2212 return send_shell_command(transport, serial, cmd, false);
2213}
2214
2215static int install_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) {
2216 static const char *const DATA_DEST = "/data/local/tmp/%s";
2217 static const char *const SD_DEST = "/sdcard/tmp/%s";
2218 const char* where = DATA_DEST;
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002219
Elliott Hughes72884782016-10-24 18:29:21 -07002220 for (int i = 1; i < argc; i++) {
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002221 if (!strcmp(argv[i], "-s")) {
2222 where = SD_DEST;
2223 }
2224 }
2225
2226 // Find last APK argument.
2227 // All other arguments passed through verbatim.
2228 int last_apk = -1;
Elliott Hughes72884782016-10-24 18:29:21 -07002229 for (int i = argc - 1; i >= 0; i--) {
2230 if (android::base::EndsWithIgnoreCase(argv[i], ".apk")) {
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002231 last_apk = i;
2232 break;
2233 }
2234 }
2235
2236 if (last_apk == -1) {
Elliott Hughes72884782016-10-24 18:29:21 -07002237 fprintf(stderr, "No APK file on command line\n");
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002238 return EXIT_FAILURE;
2239 }
2240
2241 int result = -1;
2242 std::vector<const char*> apk_file = {argv[last_apk]};
2243 std::string apk_dest = android::base::StringPrintf(
Colin Cross58021d12017-02-23 21:23:05 -08002244 where, android::base::Basename(argv[last_apk]).c_str());
Todd Kennedy6fa848a2015-11-03 16:53:08 -08002245 if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk;
2246 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
2247 result = pm_command(transport, serial, argc, argv);
2248
2249cleanup_apk:
2250 delete_file(transport, serial, apk_dest);
2251 return result;
2252}