blob: d28748042a2033a641fe56aeef034d26779a0a6f [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
Dan Albert33134262015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
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>
36
David Pursell606835a2015-09-08 17:17:02 -070037#include <base/logging.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070038#include <base/stringprintf.h>
39
Yabin Cuid325e862014-11-17 14:48:25 -080040#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080042#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043#endif
44
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080045#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080046#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080047#include "adb_client.h"
48#include "adb_io.h"
Elliott Hughes58305772015-04-17 13:57:15 -070049#include "adb_utils.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050#include "file_sync_service.h"
David Pursell606835a2015-09-08 17:17:02 -070051#include "shell_service.h"
52#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053
Elliott Hughes3bd73c12015-05-05 13:10:43 -070054static int install_app(TransportType t, const char* serial, int argc, const char** argv);
55static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
56static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080057
Elliott Hughes58305772015-04-17 13:57:15 -070058static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080059extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060
Elliott Hughes58305772015-04-17 13:57:15 -070061static std::string product_file(const char *extra) {
62 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063 fprintf(stderr, "adb: Product directory not specified; "
64 "use -p or define ANDROID_PRODUCT_OUT\n");
65 exit(1);
66 }
67
Elliott Hughes58305772015-04-17 13:57:15 -070068 return android::base::StringPrintf("%s%s%s",
69 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080070}
71
Elliott Hughes58305772015-04-17 13:57:15 -070072static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070073 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080074 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080075 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080076 " -d - directs command to the only connected USB device\n"
77 " returns an error if more than one USB device is present.\n"
78 " -e - directs command to the only running emulator.\n"
79 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070080 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070081 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070082 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080083 " -p <product name or path> - simple product name like 'sooner', or\n"
84 " a relative/absolute path to a product\n"
85 " out directory like 'out/target/product/sooner'.\n"
86 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
87 " environment variable is used, which must\n"
88 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080089 " -H - Name of adb server host (default: localhost)\n"
90 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070091 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070092 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040093 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
94 " Port 5555 is used by default if no port number is specified.\n"
95 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
96 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +020097 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040098 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080099 "\n"
100 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700101 " adb push [-p] <local> <remote>\n"
102 " - copy file/dir to device\n"
103 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700104 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700105 " - copy file/dir from device\n"
106 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700107 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800108 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600109 " (-l means list but don't copy)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800110 " adb shell - run remote shell interactively\n"
111 " adb shell <command> - run remote shell command\n"
112 " adb emu <command> - run emulator console command\n"
113 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100114 " adb forward --list - list all forward socket connections.\n"
115 " the format is a list of lines with the following format:\n"
116 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800117 " adb forward <local> <remote> - forward socket connections\n"
118 " forward specs are one of: \n"
119 " tcp:<port>\n"
120 " localabstract:<unix domain socket name>\n"
121 " localreserved:<unix domain socket name>\n"
122 " localfilesystem:<unix domain socket name>\n"
123 " dev:<character device name>\n"
124 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100125 " adb forward --no-rebind <local> <remote>\n"
126 " - same as 'adb forward <local> <remote>' but fails\n"
127 " if <local> is already forwarded\n"
128 " adb forward --remove <local> - remove a specific forward socket connection\n"
129 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100130 " adb reverse --list - list all reverse socket connections from device\n"
131 " adb reverse <remote> <local> - reverse socket connections\n"
132 " reverse specs are one of:\n"
133 " tcp:<port>\n"
134 " localabstract:<unix domain socket name>\n"
135 " localreserved:<unix domain socket name>\n"
136 " localfilesystem:<unix domain socket name>\n"
137 " adb reverse --norebind <remote> <local>\n"
138 " - same as 'adb reverse <remote> <local>' but fails\n"
139 " if <remote> is already reversed.\n"
140 " adb reverse --remove <remote>\n"
141 " - remove a specific reversed socket connection\n"
142 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700144 " adb install [-lrtsd] <file>\n"
145 " adb install-multiple [-lrtsdp] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700146 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700147 " (-l: forward lock application)\n"
148 " (-r: replace existing application)\n"
149 " (-t: allow test packages)\n"
150 " (-s: install application on sdcard)\n"
151 " (-d: allow version code downgrade)\n"
152 " (-p: partial application install)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800153 " adb uninstall [-k] <package> - remove this app package from the device\n"
154 " ('-k' means keep the data and cache directories)\n"
155 " adb bugreport - return all information from the device\n"
156 " that should be included in a bug report.\n"
157 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800158 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700159 " - write an archive of the device's data to <file>.\n"
160 " If no -f option is supplied then the data is written\n"
161 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700162 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700163 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800164 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
165 " (aka .obb) files associated with each application; the default\n"
166 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700167 " (-shared|-noshared enable/disable backup of the device's\n"
168 " shared storage / SD card contents; the default is noshared.)\n"
169 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700170 " (-system|-nosystem toggles whether -all automatically includes\n"
171 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700172 " (<packages...> is the list of applications to be backed up. If\n"
173 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700174 " list is optional. Applications explicitly given on the\n"
175 " command line will be included even if -nosystem would\n"
176 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700177 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700178 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700179 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800180 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
181 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800182 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
183 " and the public key is stored in <file>.pub. Any existing files\n"
184 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800185 " adb help - show this help message\n"
186 " adb version - show version num\n"
187 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800188 "scripting:\n"
189 " adb wait-for-device - block until device is online\n"
190 " adb start-server - ensure that there is a server running\n"
191 " adb kill-server - kill the server if it is running\n"
192 " adb get-state - prints: offline | bootloader | device\n"
193 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700194 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000195 " adb remount - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
Tao Bao175b7bb2015-03-29 11:22:34 -0700196 " adb reboot [bootloader|recovery]\n"
197 " - reboots the device, optionally into the bootloader or recovery program.\n"
198 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
199 " adb reboot sideload-auto-reboot\n"
200 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700201 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700202 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500203 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800204 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000205 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700206 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800207 "networking:\n"
208 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500209 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800210 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
211 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
212 "\n"
213 "adb sync notes: adb sync [ <directory> ]\n"
214 " <localdir> can be interpreted in several ways:\n"
215 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000216 " - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800217 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000218 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800219 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000220 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700221 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000222 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
223 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
224 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
225 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800226 );
227}
228
Elliott Hughes58305772015-04-17 13:57:15 -0700229static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800230 help();
231 return 1;
232}
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.
Spencer Low50184062015-03-01 15:06:21 -0800237void stdin_raw_init(int fd);
238void stdin_raw_restore(int fd);
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
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100243static void stdin_raw_init(int fd) {
244 if (tcgetattr(fd, &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;
247 if (tcgetattr(fd, &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
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100255 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256}
257
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100258static void stdin_raw_restore(int fd) {
259 tcsetattr(fd, 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.
267static int read_and_dump(int fd, bool use_shell_protocol=false) {
268 int exit_code = 0;
269 std::unique_ptr<ShellProtocol> protocol;
270 int length = 0;
271 FILE* outfile = stdout;
272
273 char raw_buffer[BUFSIZ];
274 char* buffer_ptr = raw_buffer;
275 if (use_shell_protocol) {
276 protocol.reset(new ShellProtocol(fd));
277 if (!protocol) {
278 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
279 return 1;
280 }
281 buffer_ptr = protocol->data();
282 }
283
Elliott Hughes5677c232015-05-07 23:37:40 -0700284 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700285 if (use_shell_protocol) {
286 if (!protocol->Read()) {
287 break;
288 }
289 switch (protocol->id()) {
290 case ShellProtocol::kIdStdout:
291 outfile = stdout;
292 break;
293 case ShellProtocol::kIdStderr:
294 outfile = stderr;
295 break;
296 case ShellProtocol::kIdExit:
297 exit_code = protocol->data()[0];
298 continue;
299 default:
300 continue;
301 }
302 length = protocol->data_length();
303 } else {
304 D("read_and_dump(): pre adb_read(fd=%d)", fd);
305 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
306 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
307 if (length <= 0) {
308 break;
309 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800310 }
311
David Pursell606835a2015-09-08 17:17:02 -0700312 fwrite(buffer_ptr, 1, length, outfile);
313 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800314 }
David Pursell606835a2015-09-08 17:17:02 -0700315
316 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800317}
318
Jeff Sharkey960df972014-06-09 17:30:57 -0700319static void read_status_line(int fd, char* buf, size_t count)
320{
321 count--;
322 while (count > 0) {
323 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700324 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700325 break;
326 }
327
328 buf += len;
329 count -= len;
330 }
331 *buf = '\0';
332}
333
Christopher Tated2f54152011-04-21 12:53:28 -0700334static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700335 const size_t BUFSIZE = 32 * 1024;
336 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700337 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700338 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700339 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700340#ifdef _WIN32
341 int old_stdin_mode = -1;
342 int old_stdout_mode = -1;
343#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700344
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700345 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800346
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700347 if (inFd == STDIN_FILENO) {
348 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700349#ifdef _WIN32
350 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
351 if (old_stdin_mode == -1) {
352 fatal_errno("could not set stdin to binary");
353 }
354#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700355 }
Yabin Cuid325e862014-11-17 14:48:25 -0800356
Spencer Lowb7dfb792015-05-22 16:48:31 -0700357#ifdef _WIN32
358 if (outFd == STDOUT_FILENO) {
359 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
360 if (old_stdout_mode == -1) {
361 fatal_errno("could not set stdout to binary");
362 }
363 }
364#endif
365
Elliott Hughesa7090b92015-04-17 17:03:59 -0700366 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700367 if (inFd == STDIN_FILENO) {
368 len = unix_read(inFd, buf, BUFSIZE);
369 } else {
370 len = adb_read(inFd, buf, BUFSIZE);
371 }
Christopher Tated2f54152011-04-21 12:53:28 -0700372 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700373 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700374 break;
375 }
376 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700377 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700378 break;
379 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700380 if (outFd == STDOUT_FILENO) {
381 fwrite(buf, 1, len, stdout);
382 fflush(stdout);
383 } else {
384 adb_write(outFd, buf, len);
385 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700386 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700387 }
Yabin Cuid325e862014-11-17 14:48:25 -0800388
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700389 if (inFd == STDIN_FILENO) {
390 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700391#ifdef _WIN32
392 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
393 fatal_errno("could not restore stdin mode");
394 }
395#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700396 }
Yabin Cuid325e862014-11-17 14:48:25 -0800397
Spencer Lowb7dfb792015-05-22 16:48:31 -0700398#ifdef _WIN32
399 if (outFd == STDOUT_FILENO) {
400 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
401 fatal_errno("could not restore stdout mode");
402 }
403 }
404#endif
405
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700406 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700407 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700408}
409
David Pursell606835a2015-09-08 17:17:02 -0700410namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800411
David Pursell606835a2015-09-08 17:17:02 -0700412// Used to pass multiple values to the stdin read thread.
413struct StdinReadArgs {
414 int stdin_fd, write_fd;
415 std::unique_ptr<ShellProtocol> protocol;
416};
417
418} // namespace
419
420// Loops to read from stdin and push the data to the given FD.
421// The argument should be a pointer to a StdinReadArgs object. This function
422// will take ownership of the object and delete it when finished.
423static void* stdin_read_thread(void* x) {
424 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
425 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800426
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700427 adb_thread_setname("stdin reader");
428
David Pursell606835a2015-09-08 17:17:02 -0700429 char raw_buffer[1024];
430 char* buffer_ptr = raw_buffer;
431 size_t buffer_size = sizeof(raw_buffer);
432 if (args->protocol) {
433 buffer_ptr = args->protocol->data();
434 buffer_size = args->protocol->data_capacity();
435 }
436
Elliott Hughesaa245492015-08-03 10:38:08 -0700437 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700438 // Use unix_read() rather than adb_read() for stdin.
439 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
440 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
441 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700442 if (r <= 0) break;
David Pursell606835a2015-09-08 17:17:02 -0700443 for (int n = 0; n < r; n++){
444 switch(buffer_ptr[n]) {
Mike Lockwood67d53582010-05-25 13:40:15 -0400445 case '\n':
446 state = 1;
447 break;
448 case '\r':
449 state = 1;
450 break;
451 case '~':
452 if(state == 1) state++;
453 break;
454 case '.':
455 if(state == 2) {
456 fprintf(stderr,"\n* disconnect *\n");
David Pursell606835a2015-09-08 17:17:02 -0700457 stdin_raw_restore(args->stdin_fd);
Mike Lockwood67d53582010-05-25 13:40:15 -0400458 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800459 }
Mike Lockwood67d53582010-05-25 13:40:15 -0400460 default:
461 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800462 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800463 }
David Pursell606835a2015-09-08 17:17:02 -0700464 if (args->protocol) {
465 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
466 break;
467 }
468 } else {
469 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
470 break;
471 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800472 }
473 }
David Pursell606835a2015-09-08 17:17:02 -0700474
475 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800476}
477
David Pursell606835a2015-09-08 17:17:02 -0700478static int interactive_shell(bool use_shell_protocol) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700479 std::string error;
480 int fd = adb_connect("shell:", &error);
481 if (fd < 0) {
482 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800483 return 1;
484 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800485
David Pursell606835a2015-09-08 17:17:02 -0700486 StdinReadArgs* args = new StdinReadArgs;
487 if (!args) {
488 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700489 return 1;
490 }
David Pursell606835a2015-09-08 17:17:02 -0700491 args->stdin_fd = 0;
492 args->write_fd = fd;
493 if (use_shell_protocol) {
494 args->protocol.reset(new ShellProtocol(args->write_fd));
495 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700496
David Pursell606835a2015-09-08 17:17:02 -0700497 stdin_raw_init(args->stdin_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800498
David Pursell606835a2015-09-08 17:17:02 -0700499 int exit_code = 0;
500 if (!adb_thread_create(stdin_read_thread, args)) {
501 PLOG(ERROR) << "error starting stdin read thread";
502 exit_code = 1;
503 delete args;
504 } else {
505 exit_code = read_and_dump(fd, use_shell_protocol);
506 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700507
David Pursell606835a2015-09-08 17:17:02 -0700508 stdin_raw_restore(args->stdin_fd);
509 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800510}
511
512
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700513static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800514 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700515 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800516 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700517
518 const char* prefix = "host";
519 if (type == kTransportUsb) {
520 prefix = "host-usb";
521 } else if (type == kTransportLocal) {
522 prefix = "host-local";
523 }
524 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800525}
526
David Pursell71c83122015-09-14 15:33:50 -0700527// Checks whether the device indicated by |transport_type| and |serial| supports
528// |feature|. Returns the response string, which will be empty if the device
529// could not be found or the feature is not supported.
530static std::string CheckFeature(const std::string& feature,
531 TransportType transport_type,
532 const char* serial) {
533 std::string result, error, command("check-feature:" + feature);
534 if (!adb_query(format_host_command(command.c_str(), transport_type, serial),
535 &result, &error)) {
536 return "";
537 }
538 return result;
539}
540
Elliott Hughes6452a892015-04-29 12:28:13 -0700541static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700542 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800543{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700544 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700545 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700546 if (fd < 0) {
547 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800548 return -1;
549 }
550
551 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800552 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800553
Elliott Hughes6452a892015-04-29 12:28:13 -0700554 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800555 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800556
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700557 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700558 const char* x = strrchr(service, ':');
559 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800560 }
561
Elliott Hughes6452a892015-04-29 12:28:13 -0700562 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800563 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700564 if (!WriteFdExactly(fd, ptr, xfer)) {
565 std::string error;
566 adb_status(fd, &error);
567 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800568 return -1;
569 }
570 sz -= xfer;
571 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700572 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100573 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800574 fflush(stdout);
575 }
576 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700577 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800578 printf("\n");
579 }
580
Elliott Hughese67f1f82015-04-30 17:32:03 -0700581 if (!adb_status(fd, &error)) {
582 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800583 return -1;
584 }
585
586 adb_close(fd);
587 return 0;
588}
589
Doug Zongker71fe5842014-06-26 15:35:36 -0700590#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
591
592/*
593 * The sideload-host protocol serves the data in a file (given on the
594 * command line) to the client, using a simple protocol:
595 *
596 * - The connect message includes the total number of bytes in the
597 * file and a block size chosen by us.
598 *
599 * - The other side sends the desired block number as eight decimal
600 * digits (eg "00000023" for block 23). Blocks are numbered from
601 * zero.
602 *
603 * - We send back the data of the requested block. The last block is
604 * likely to be partial; when the last block is requested we only
605 * send the part of the block that exists, it's not padded up to the
606 * block size.
607 *
608 * - When the other side sends "DONEDONE" instead of a block number,
609 * we hang up.
610 */
Elliott Hughes58305772015-04-17 13:57:15 -0700611static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700612 unsigned sz;
613 size_t xfer = 0;
614 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800615 int last_percent = -1;
616 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700617
618 printf("loading: '%s'", fn);
619 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800620 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700621 if (data == 0) {
622 printf("\n");
623 fprintf(stderr, "* cannot read '%s' *\n", fn);
624 return -1;
625 }
626
Elliott Hughes6452a892015-04-29 12:28:13 -0700627 std::string service =
628 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700629 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700630 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700631 if (fd < 0) {
632 // Try falling back to the older sideload method. Maybe this
633 // is an older device that doesn't support sideload-host.
634 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700635 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700636 goto done;
637 }
638
Spencer Lowf055c192015-01-25 14:40:16 -0800639 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700640
Elliott Hughesa7090b92015-04-17 17:03:59 -0700641 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700642 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800643 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700644 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700645 status = -1;
646 goto done;
647 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700648 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700649
Elliott Hughes6452a892015-04-29 12:28:13 -0700650 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700651 status = 0;
652 break;
653 }
654
Doug Zongker71fe5842014-06-26 15:35:36 -0700655 int block = strtol(buf, NULL, 10);
656
657 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
658 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700659 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700660 status = -1;
661 goto done;
662 }
663 uint8_t* start = data + offset;
664 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
665 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
666 if (offset_end > sz) {
667 to_write = sz - offset;
668 }
669
Dan Albertcc731cc2015-02-24 21:26:58 -0800670 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700671 adb_status(fd, &error);
672 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700673 status = -1;
674 goto done;
675 }
676 xfer += to_write;
677
678 // For normal OTA packages, we expect to transfer every byte
679 // twice, plus a bit of overhead (one read during
680 // verification, one read of each byte for installation, plus
681 // extra access to things like the zip central directory).
682 // This estimate of the completion becomes 100% when we've
683 // transferred ~2.13 (=100/47) times the package size.
684 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
685 if (percent != last_percent) {
686 printf("\rserving: '%s' (~%d%%) ", fn, percent);
687 fflush(stdout);
688 last_percent = percent;
689 }
690 }
691
Colin Cross6d6a8982014-07-07 14:12:41 -0700692 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700693
694 done:
695 if (fd >= 0) adb_close(fd);
696 free(data);
697 return status;
698}
699
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800700/**
701 * Run ppp in "notty" mode against a resource listed as the first parameter
702 * eg:
703 *
704 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
705 *
706 */
Elliott Hughes58305772015-04-17 13:57:15 -0700707static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800708#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800709 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
710 return -1;
711#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800712 if (argc < 2) {
713 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
714 argv[0]);
715
716 return 1;
717 }
718
Dan Albertbac34742015-02-25 17:51:28 -0800719 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700720 std::string error;
721 int fd = adb_connect(adb_service_name, &error);
722 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800723 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700724 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800725 return 1;
726 }
727
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700728 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800729
730 if (pid < 0) {
731 perror("from fork()");
732 return 1;
733 } else if (pid == 0) {
734 int err;
735 int i;
736 const char **ppp_args;
737
738 // copy args
739 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
740 ppp_args[0] = "pppd";
741 for (i = 2 ; i < argc ; i++) {
742 //argv[2] and beyond become ppp_args[1] and beyond
743 ppp_args[i - 1] = argv[i];
744 }
745 ppp_args[i-1] = NULL;
746
747 // child side
748
749 dup2(fd, STDIN_FILENO);
750 dup2(fd, STDOUT_FILENO);
751 adb_close(STDERR_FILENO);
752 adb_close(fd);
753
754 err = execvp("pppd", (char * const *)ppp_args);
755
756 if (err < 0) {
757 perror("execing pppd");
758 }
759 exit(-1);
760 } else {
761 // parent side
762
763 adb_close(fd);
764 return 0;
765 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800766#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800767}
768
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700769static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700770 // Was the caller vague about what they'd like us to wait for?
771 // If so, check they weren't more specific in their choice of transport type.
772 if (strcmp(service, "wait-for-device") == 0) {
773 if (t == kTransportUsb) {
774 service = "wait-for-usb";
775 } else if (t == kTransportLocal) {
776 service = "wait-for-local";
777 } else {
778 service = "wait-for-any";
779 }
780 }
781
782 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700783 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700784}
785
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700786static int send_shell_command(TransportType transport_type, const char* serial,
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700787 const std::string& command) {
788 int fd;
789 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700790 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700791 fd = adb_connect(command, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700792 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800793 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700794 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800795 fprintf(stderr,"- waiting for device -\n");
796 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700797 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800798 }
799
David Pursell71c83122015-09-14 15:33:50 -0700800 bool use_shell_protocol = !CheckFeature(kFeatureShell2, transport_type,
801 serial).empty();
802 int exit_code = read_and_dump(fd, use_shell_protocol);
803
804 if (adb_close(fd) < 0) {
805 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700806 }
David Pursell71c83122015-09-14 15:33:50 -0700807
808 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800809}
810
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700811static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700812 char* log_tags = getenv("ANDROID_LOG_TAGS");
813 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800814
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700815 std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800816
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700817 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700818 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800819 }
820
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700821 --argc;
822 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700823 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700824 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800825 }
826
Elliott Hughes15551472015-04-21 17:58:55 -0700827 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800828}
829
Dan Albertbac34742015-02-25 17:51:28 -0800830static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700831 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700832
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700833 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700834 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700835 if (!strcmp("-f", argv[i])) {
836 if (i == argc-1) {
837 fprintf(stderr, "adb: -f passed with no filename\n");
838 return usage();
839 }
840 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700841 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700842 argv[i++] = argv[j++];
843 }
844 argc -= 2;
845 argv[argc] = NULL;
846 }
Christopher Tated2f54152011-04-21 12:53:28 -0700847 }
848
Christopher Tatebb86bc52011-08-22 17:12:08 -0700849 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
850 if (argc < 2) return usage();
851
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800852 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700853 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700854 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700855 if (outFd < 0) {
856 fprintf(stderr, "adb: unable to open file %s\n", filename);
857 return -1;
858 }
859
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700860 std::string cmd = "backup:";
861 --argc;
862 ++argv;
863 while (argc-- > 0) {
864 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700865 }
866
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700867 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700868 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700869 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700870 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700871 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700872 adb_close(outFd);
873 return -1;
874 }
875
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800876 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700877 copy_to_file(fd, outFd);
878
879 adb_close(fd);
880 adb_close(outFd);
881 return 0;
882}
883
Dan Albertbac34742015-02-25 17:51:28 -0800884static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700885 if (argc != 2) return usage();
886
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700887 const char* filename = argv[1];
888 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700889 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700890 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700891 return -1;
892 }
893
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700894 std::string error;
895 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700896 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700897 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700898 adb_close(tarFd);
899 return -1;
900 }
901
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800902 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700903 copy_to_file(tarFd, fd);
904
905 adb_close(fd);
906 adb_close(tarFd);
907 return 0;
908}
909
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800910/* <hint> may be:
911 * - A simple product name
912 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800913 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
914 * e.g., "out/target/product/sooner"
915 * - An absolute path to the PRODUCT_OUT dir
916 * e.g., "/src/device/out/target/product/sooner"
917 *
918 * Given <hint>, try to construct an absolute path to the
919 * ANDROID_PRODUCT_OUT dir.
920 */
Elliott Hughes5c742702015-07-30 17:42:01 -0700921static std::string find_product_out_path(const std::string& hint) {
922 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -0700923 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800924 }
925
Elliott Hughes58305772015-04-17 13:57:15 -0700926 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -0700927 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -0700928 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800929 }
930
Elliott Hughes58305772015-04-17 13:57:15 -0700931 // If there are any slashes in it, assume it's a relative path;
932 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -0700933 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700934 std::string cwd;
935 if (!getcwd(&cwd)) {
936 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -0700937 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800938 }
Elliott Hughes5c742702015-07-30 17:42:01 -0700939 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 -0800940 }
941
Elliott Hughes58305772015-04-17 13:57:15 -0700942 // It's a string without any slashes. Try to do something with it.
943 //
944 // Try to find the root of the build tree, and build a PRODUCT_OUT
945 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -0700946 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -0700947 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700948 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -0700949 return "";
950 }
Elliott Hughesa7090b92015-04-17 17:03:59 -0700951
952 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -0700953 path += OS_PATH_SEPARATOR_STR;
954 path += "out";
955 path += OS_PATH_SEPARATOR_STR;
956 path += "target";
957 path += OS_PATH_SEPARATOR_STR;
958 path += "product";
959 path += OS_PATH_SEPARATOR_STR;
960 path += hint;
961 if (!directory_exists(path)) {
962 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -0700963 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -0700964 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800965 }
Elliott Hughes58305772015-04-17 13:57:15 -0700966 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800967}
968
Dan Albertbac34742015-02-25 17:51:28 -0800969static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -0700970 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -0800971 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700972 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700973 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -0700974
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700975 while (narg > 0) {
976 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700977 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700978 } else if (!strcmp(*arg, "-a")) {
979 *copy_attrs = 1;
980 } else {
981 break;
982 }
Mark Lindner76f2a932014-03-11 17:55:59 -0700983 ++arg;
984 --narg;
985 }
986
987 if (narg > 0) {
988 *path1 = *arg;
989 ++arg;
990 --narg;
991 }
992
993 if (narg > 0) {
994 *path2 = *arg;
995 }
996}
997
Elliott Hughes6452a892015-04-29 12:28:13 -0700998static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700999 std::string error;
1000 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001001 if (fd < 0) {
1002 fprintf(stderr, "error: %s\n", error.c_str());
1003 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001004 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001005 read_and_dump(fd);
1006 adb_close(fd);
1007 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001008}
1009
Elliott Hughes6452a892015-04-29 12:28:13 -07001010static int adb_query_command(const std::string& command) {
1011 std::string result;
1012 std::string error;
1013 if (!adb_query(command, &result, &error)) {
1014 fprintf(stderr, "error: %s\n", error.c_str());
1015 return 1;
1016 }
1017 printf("%s\n", result.c_str());
1018 return 0;
1019}
1020
Spencer Lowa13df302015-09-07 16:20:13 -07001021// Disallow stdin, stdout, and stderr.
1022static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1023#ifdef _WIN32
1024 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1025 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1026 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1027 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1028#else
1029 return ack_reply_fd > 2;
1030#endif
1031}
1032
Elliott Hughesab52c182015-05-01 17:04:38 -07001033int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001034 int no_daemon = 0;
1035 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001036 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001037 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001038 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001039 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001040
Elliott Hughes58305772015-04-17 13:57:15 -07001041 // If defined, this should be an absolute path to
1042 // the directory containing all of the various system images
1043 // for a particular product. If not defined, and the adb
1044 // command requires this information, then the user must
1045 // specify the path using "-p".
1046 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1047 if (ANDROID_PRODUCT_OUT != nullptr) {
1048 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001049 }
1050 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1051
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001052 const char* serial = getenv("ANDROID_SERIAL");
Nick Pellydb449262009-05-07 12:48:03 -07001053
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001054 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001055 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001056 int server_port = DEFAULT_ADB_PORT;
1057 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001058 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001059 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001060 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001061 "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65536. Got \"%s\"\n",
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001062 server_port_str);
1063 return usage();
1064 }
1065 }
1066
1067 /* modifiers and flags */
Riley Andrews98f58e82014-12-05 17:37:24 -08001068 while (argc > 0) {
1069 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001070 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001071 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001072 no_daemon = 1;
1073 } else if (!strcmp(argv[0], "fork-server")) {
1074 /* this is a special flag used only when the ADB client launches the ADB Server */
1075 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001076 } else if (!strcmp(argv[0], "--reply-fd")) {
1077 if (argc < 2) return usage();
1078 const char* reply_fd_str = argv[1];
1079 argc--;
1080 argv++;
1081 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001082 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001083 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1084 return usage();
1085 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001086 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001087 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001088 if (argv[0][2] == '\0') {
1089 if (argc < 2) return usage();
1090 product = argv[1];
1091 argc--;
1092 argv++;
1093 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001094 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001095 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001096 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001097 if (gProductOutPath.empty()) {
1098 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001099 return usage();
1100 }
1101 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1102 if (isdigit(argv[0][2])) {
1103 serial = argv[0] + 2;
1104 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001105 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001106 serial = argv[1];
1107 argc--;
1108 argv++;
1109 }
1110 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001111 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001112 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001113 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001114 } else if (!strcmp(argv[0],"-a")) {
1115 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001116 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001117 const char *hostname = NULL;
1118 if (argv[0][2] == '\0') {
1119 if (argc < 2) return usage();
1120 hostname = argv[1];
1121 argc--;
1122 argv++;
1123 } else {
1124 hostname = argv[0] + 2;
1125 }
1126 adb_set_tcp_name(hostname);
1127
Riley Andrews98f58e82014-12-05 17:37:24 -08001128 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001129 if (argv[0][2] == '\0') {
1130 if (argc < 2) return usage();
1131 server_port_str = argv[1];
1132 argc--;
1133 argv++;
1134 } else {
1135 server_port_str = argv[0] + 2;
1136 }
1137 if (strlen(server_port_str) > 0) {
1138 server_port = (int) strtol(server_port_str, NULL, 0);
1139 if (server_port <= 0 || server_port > 65535) {
1140 fprintf(stderr,
1141 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1142 server_port_str);
1143 return usage();
1144 }
1145 } else {
1146 fprintf(stderr,
1147 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1148 return usage();
1149 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001150 } else {
1151 /* out of recognized modifiers and flags */
1152 break;
1153 }
1154 argc--;
1155 argv++;
1156 }
1157
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001158 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001159 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001160
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001161 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001162 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001163 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001164 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1165 return usage();
1166 }
1167 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001168 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001169 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001170 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001171 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001172 fprintf(stderr,"* could not start server *\n");
1173 }
1174 return r;
1175 }
1176
Riley Andrews98f58e82014-12-05 17:37:24 -08001177 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001178 return usage();
1179 }
1180
Riley Andrewsc8514c82014-12-05 17:32:46 -08001181 /* handle wait-for-* prefix */
1182 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001183 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001184
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001185 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001186 return 1;
1187 }
1188
Elliott Hughes2b101112015-05-04 19:29:32 -07001189 // Allow a command to be run after wait-for-device,
1190 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001191 if (argc == 1) {
1192 return 0;
1193 }
1194
1195 /* Fall through */
1196 argc--;
1197 argv++;
1198 }
1199
1200 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001201 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001202 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001203 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001204 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001205 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001206 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001207 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001208 fprintf(stderr, "Usage: adb devices [-l]\n");
1209 return 1;
1210 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001211
1212 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1213 printf("List of devices attached\n");
1214 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001215 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001216 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001217 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001218 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001219 return 1;
1220 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001221
1222 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1223 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001224 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001225 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001226 if (argc > 2) {
1227 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1228 return 1;
1229 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001230
1231 std::string query = android::base::StringPrintf("host:disconnect:%s",
1232 (argc == 2) ? argv[1] : "");
1233 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001234 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001235 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001236 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001237 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001238 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001239 char h = (argv[0][0] == 'h');
1240
1241 if (h) {
1242 printf("\x1b[41;33m");
1243 fflush(stdout);
1244 }
1245
David Pursell606835a2015-09-08 17:17:02 -07001246 bool use_shell_protocol;
1247 if (CheckFeature(kFeatureShell2, transport_type, serial).empty()) {
1248 D("shell protocol not supported, using raw data transfer");
1249 use_shell_protocol = false;
1250 } else {
1251 D("using shell protocol");
1252 use_shell_protocol = true;
1253 }
1254
1255
Riley Andrews98f58e82014-12-05 17:37:24 -08001256 if (argc < 2) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001257 D("starting interactive shell");
David Pursell606835a2015-09-08 17:17:02 -07001258 r = interactive_shell(use_shell_protocol);
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001259 if (h) {
1260 printf("\x1b[0m");
1261 fflush(stdout);
1262 }
1263 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001264 }
1265
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001266 std::string cmd = "shell:";
Elliott Hughes2b101112015-05-04 19:29:32 -07001267 --argc;
1268 ++argv;
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001269 while (argc-- > 0) {
Elliott Hughes2b101112015-05-04 19:29:32 -07001270 // We don't escape here, just like ssh(1). http://b/20564385.
1271 cmd += *argv++;
1272 if (*argv) cmd += " ";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001273 }
1274
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001275 while (true) {
David Pursell606835a2015-09-08 17:17:02 -07001276 D("non-interactive shell loop. cmd=%s", cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001277 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001278 int fd = adb_connect(cmd, &error);
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001279 int r;
Riley Andrews98f58e82014-12-05 17:37:24 -08001280 if (fd >= 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001281 D("about to read_and_dump(fd=%d)", fd);
David Pursell606835a2015-09-08 17:17:02 -07001282 r = read_and_dump(fd, use_shell_protocol);
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001283 D("read_and_dump() done.");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001284 adb_close(fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001285 } else {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001286 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001287 r = -1;
1288 }
1289
Elliott Hughes32687be2015-05-05 12:50:26 -07001290 if (h) {
1291 printf("\x1b[0m");
1292 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001293 }
David Pursell606835a2015-09-08 17:17:02 -07001294 D("non-interactive shell loop. return r=%d", r);
Elliott Hughes32687be2015-05-05 12:50:26 -07001295 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001296 }
1297 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001298 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001299 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001300
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001301 std::string cmd = "exec:";
1302 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001303 argc -= 2;
1304 argv += 2;
1305 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001306 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001307 }
1308
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001309 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001310 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001311 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001312 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001313 return -1;
1314 }
1315
1316 if (exec_in) {
1317 copy_to_file(STDIN_FILENO, fd);
1318 } else {
1319 copy_to_file(fd, STDOUT_FILENO);
1320 }
1321
1322 adb_close(fd);
1323 return 0;
1324 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001325 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001326 std::string error;
1327 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001328 if (fd == -2) {
1329 // Failed to make network connection to server. Don't output the
1330 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001331 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001332 // Successful exit code because the server is already "killed".
1333 return 0;
1334 } else if (fd == -1) {
1335 // Some other error.
1336 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001337 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001338 } else {
1339 // Successfully connected, kill command sent, okay status came back.
1340 // Server should exit() in a moment, if not already.
1341 adb_close(fd);
1342 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001343 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001344 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001345 else if (!strcmp(argv[0], "sideload")) {
1346 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001347 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001348 return 1;
1349 } else {
1350 return 0;
1351 }
1352 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001353 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1354 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1355 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001356 else if (!strcmp(argv[0], "remount") ||
1357 !strcmp(argv[0], "reboot") ||
1358 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001359 !strcmp(argv[0], "usb") ||
1360 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001361 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001362 !strcmp(argv[0], "disable-verity") ||
1363 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001364 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001365 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001366 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001367 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001368 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001369 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001370 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001371 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001372 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001373 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001374 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001375 if (argc != 1) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001376 return send_shell_command(transport_type, serial, "shell:bugreport");
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001377 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001378 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001379 bool reverse = !strcmp(argv[0], "reverse");
1380 ++argv;
1381 --argc;
1382 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001383
1384 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001385 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001386 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001387 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001388 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001389 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001390 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001391 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001392 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001393 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001394 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001395 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001396 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001397 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001398 }
1399
Elliott Hughes424af022015-05-29 17:55:19 -07001400 std::string cmd;
1401 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001402 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001403 return adb_query_command(host_prefix + ":list-forward");
1404 } else if (strcmp(argv[0], "--remove-all") == 0) {
1405 if (argc != 1) return usage();
1406 cmd = host_prefix + ":killforward-all";
1407 } else if (strcmp(argv[0], "--remove") == 0) {
1408 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001409 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001410 cmd = host_prefix + ":killforward:" + argv[1];
1411 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1412 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001413 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001414 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1415 } else {
1416 // forward <local> <remote>
1417 if (argc != 2) return usage();
1418 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001419 }
1420
Elliott Hughes424af022015-05-29 17:55:19 -07001421 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001422 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001423 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001424 else if (!strcmp(argv[0], "ls")) {
1425 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001426 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001427 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001428 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001429 bool show_progress = false;
1430 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001431 const char* lpath = NULL, *rpath = NULL;
1432
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001433 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001434 if (!lpath || !rpath || copy_attrs != 0) return usage();
1435 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001436 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001437 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001438 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001439 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001440 const char* rpath = NULL, *lpath = ".";
1441
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001442 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001443 if (!rpath) return usage();
1444 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001445 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001446 else if (!strcmp(argv[0], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001447 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001448 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001449 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001450 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001451 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001452 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001453 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001454 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001455 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001456 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001457 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001458 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001459 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001460 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001461 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001462 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001463 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001464 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001465 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001466 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001467 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001468 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001469 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001470 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001471 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001472 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001473 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001474 } else {
1475 return usage();
1476 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001477
Elliott Hughesd236d072015-04-21 10:17:07 -07001478 if (src != "" &&
1479 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001480 return usage();
1481 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001482
Elliott Hughes58305772015-04-17 13:57:15 -07001483 std::string system_src_path = product_file("system");
1484 std::string data_src_path = product_file("data");
1485 std::string vendor_src_path = product_file("vendor");
1486 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001487
Elliott Hughesaa245492015-08-03 10:38:08 -07001488 bool okay = true;
1489 if (okay && (src.empty() || src == "system")) {
1490 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001491 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001492 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1493 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001494 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001495 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1496 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001497 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001498 if (okay && (src.empty() || src == "data")) {
1499 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001500 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001501 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001502 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001503 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001504 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001505 !strcmp(argv[0],"get-serialno") ||
1506 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001507 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001508 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001509 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001510 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001511 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001512 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001513 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001514 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001515 return ppp(argc, argv);
1516 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001517 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001518 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001519 const int result = adb_connect("host:start-server", &error);
1520 if (result < 0) {
1521 fprintf(stderr, "error: %s\n", error.c_str());
1522 }
1523 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001524 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001525 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001526 return backup(argc, argv);
1527 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001528 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001529 return restore(argc, argv);
1530 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001531 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001532 if (argc < 2) return usage();
1533 return adb_auth_keygen(argv[1]);
1534 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001535 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001536 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001537 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001538 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001539 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001540 help();
1541 return 0;
1542 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001543 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001544 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001545 return 0;
1546 }
Dan Albert90d4b732015-05-20 18:58:41 -07001547 else if (!strcmp(argv[0], "features")) {
David Pursell880be432015-09-04 16:40:30 -07001548 return adb_query_command(format_host_command("features", transport_type, serial));
Dan Albert90d4b732015-05-20 18:58:41 -07001549 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001550
1551 usage();
1552 return 1;
1553}
1554
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001555static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001556 std::string cmd = "shell:pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001557
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001558 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001559 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001560 }
1561
Elliott Hughes15551472015-04-21 17:58:55 -07001562 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001563}
1564
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001565static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001566 /* if the user choose the -k option, we refuse to do it until devices are
1567 out with the option to uninstall the remaining data somehow (adb/ui) */
1568 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1569 {
1570 printf(
1571 "The -k option uninstalls the application while retaining the data/cache.\n"
1572 "At the moment, there is no way to remove the remaining data.\n"
1573 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1574 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1575 return -1;
1576 }
1577
1578 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1579 return pm_command(transport, serial, argc, argv);
1580}
1581
Elliott Hughes5c742702015-07-30 17:42:01 -07001582static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001583 std::string cmd = "shell:rm -f " + escape_arg(filename);
Elliott Hughes15551472015-04-21 17:58:55 -07001584 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001585}
1586
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001587static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001588 static const char *const DATA_DEST = "/data/local/tmp/%s";
1589 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001590 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001591 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001592 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001593
1594 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001595 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001596 where = SD_DEST;
1597 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001598 }
1599
Jeff Sharkey960df972014-06-09 17:30:57 -07001600 // Find last APK argument.
1601 // All other arguments passed through verbatim.
1602 int last_apk = -1;
1603 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001604 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001605 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001606 if (dot && !strcasecmp(dot, ".apk")) {
1607 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1608 fprintf(stderr, "Invalid APK file: %s\n", file);
1609 return -1;
1610 }
1611
1612 last_apk = i;
1613 break;
1614 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001615 }
1616
Jeff Sharkey960df972014-06-09 17:30:57 -07001617 if (last_apk == -1) {
1618 fprintf(stderr, "Missing APK file\n");
1619 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001620 }
1621
Elliott Hughesaa245492015-08-03 10:38:08 -07001622 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001623 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001624 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001625 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1626 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1627 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001628
Kenny Root60733e92012-03-26 16:14:02 -07001629cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001630 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001631 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001632}
1633
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001634static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001635 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001636{
Jeff Sharkey960df972014-06-09 17:30:57 -07001637 int i;
1638 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001639 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001640
1641 // Find all APK arguments starting at end.
1642 // All other arguments passed through verbatim.
1643 int first_apk = -1;
1644 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001645 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001646 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001647 if (dot && !strcasecmp(dot, ".apk")) {
1648 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1649 fprintf(stderr, "Invalid APK file: %s\n", file);
1650 return -1;
1651 }
1652
1653 total_size += sb.st_size;
1654 first_apk = i;
1655 } else {
1656 break;
1657 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001658 }
1659
Jeff Sharkey960df972014-06-09 17:30:57 -07001660 if (first_apk == -1) {
1661 fprintf(stderr, "Missing APK file\n");
1662 return 1;
1663 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001664
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001665 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001666 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001667 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001668 }
1669
1670 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001671 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001672 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001673 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001674 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001675 return -1;
1676 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001677 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001678 read_status_line(fd, buf, sizeof(buf));
1679 adb_close(fd);
1680
1681 int session_id = -1;
1682 if (!strncmp("Success", buf, 7)) {
1683 char* start = strrchr(buf, '[');
1684 char* end = strrchr(buf, ']');
1685 if (start && end) {
1686 *end = '\0';
1687 session_id = strtol(start + 1, NULL, 10);
1688 }
1689 }
1690 if (session_id < 0) {
1691 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001692 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001693 return -1;
1694 }
1695
1696 // Valid session, now stream the APKs
1697 int success = 1;
1698 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001699 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001700 if (stat(file, &sb) == -1) {
1701 fprintf(stderr, "Failed to stat %s\n", file);
1702 success = 0;
1703 goto finalize_session;
1704 }
1705
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001706 std::string cmd = android::base::StringPrintf(
1707 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001708 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001709
1710 int localFd = adb_open(file, O_RDONLY);
1711 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001712 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001713 success = 0;
1714 goto finalize_session;
1715 }
1716
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001717 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001718 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001719 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001720 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001721 adb_close(localFd);
1722 success = 0;
1723 goto finalize_session;
1724 }
1725
1726 copy_to_file(localFd, remoteFd);
1727 read_status_line(remoteFd, buf, sizeof(buf));
1728
1729 adb_close(localFd);
1730 adb_close(remoteFd);
1731
1732 if (strncmp("Success", buf, 7)) {
1733 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001734 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001735 success = 0;
1736 goto finalize_session;
1737 }
1738 }
1739
1740finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001741 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001742 std::string service =
1743 android::base::StringPrintf("exec:pm install-%s %d",
1744 success ? "commit" : "abandon", session_id);
1745 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001746 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001747 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001748 return -1;
1749 }
1750 read_status_line(fd, buf, sizeof(buf));
1751 adb_close(fd);
1752
1753 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001754 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001755 return 0;
1756 } else {
1757 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001758 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001759 return -1;
1760 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001761}