blob: 4e93deea212ba5d98dab316cb8d47ab82abfebd7 [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>
David Pursell4e2fd362015-09-22 10:43:08 -070039#include <base/strings.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070040
Yabin Cuid325e862014-11-17 14:48:25 -080041#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080042#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080043#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080044#endif
45
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080047#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080048#include "adb_client.h"
49#include "adb_io.h"
Elliott Hughes58305772015-04-17 13:57:15 -070050#include "adb_utils.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051#include "file_sync_service.h"
David Pursell606835a2015-09-08 17:17:02 -070052#include "shell_service.h"
53#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080054
Elliott Hughes3bd73c12015-05-05 13:10:43 -070055static int install_app(TransportType t, const char* serial, int argc, const char** argv);
56static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
57static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058
Elliott Hughes58305772015-04-17 13:57:15 -070059static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080060extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080061
Elliott Hughes58305772015-04-17 13:57:15 -070062static std::string product_file(const char *extra) {
63 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080064 fprintf(stderr, "adb: Product directory not specified; "
65 "use -p or define ANDROID_PRODUCT_OUT\n");
66 exit(1);
67 }
68
Elliott Hughes58305772015-04-17 13:57:15 -070069 return android::base::StringPrintf("%s%s%s",
70 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080071}
72
Elliott Hughes58305772015-04-17 13:57:15 -070073static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070074 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080075 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080076 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080077 " -d - directs command to the only connected USB device\n"
78 " returns an error if more than one USB device is present.\n"
79 " -e - directs command to the only running emulator.\n"
80 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070081 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070082 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070083 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080084 " -p <product name or path> - simple product name like 'sooner', or\n"
85 " a relative/absolute path to a product\n"
86 " out directory like 'out/target/product/sooner'.\n"
87 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
88 " environment variable is used, which must\n"
89 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080090 " -H - Name of adb server host (default: localhost)\n"
91 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070092 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070093 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040094 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
95 " Port 5555 is used by default if no port number is specified.\n"
96 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
97 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +020098 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040099 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800100 "\n"
101 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700102 " adb push [-p] <local> <remote>\n"
103 " - copy file/dir to device\n"
104 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700105 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700106 " - copy file/dir from device\n"
107 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700108 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800109 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600110 " (-l means list but don't copy)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800111 " adb shell - run remote shell interactively\n"
David Pursell4e2fd362015-09-22 10:43:08 -0700112 " adb shell [-Tt] <command> - run remote shell command\n"
113 " (-T disables PTY allocation)\n"
114 " (-t forces PTY allocation)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800115 " adb emu <command> - run emulator console command\n"
116 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100117 " adb forward --list - list all forward socket connections.\n"
118 " the format is a list of lines with the following format:\n"
119 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800120 " adb forward <local> <remote> - forward socket connections\n"
121 " forward specs are one of: \n"
122 " tcp:<port>\n"
123 " localabstract:<unix domain socket name>\n"
124 " localreserved:<unix domain socket name>\n"
125 " localfilesystem:<unix domain socket name>\n"
126 " dev:<character device name>\n"
127 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100128 " adb forward --no-rebind <local> <remote>\n"
129 " - same as 'adb forward <local> <remote>' but fails\n"
130 " if <local> is already forwarded\n"
131 " adb forward --remove <local> - remove a specific forward socket connection\n"
132 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100133 " adb reverse --list - list all reverse socket connections from device\n"
134 " adb reverse <remote> <local> - reverse socket connections\n"
135 " reverse specs are one of:\n"
136 " tcp:<port>\n"
137 " localabstract:<unix domain socket name>\n"
138 " localreserved:<unix domain socket name>\n"
139 " localfilesystem:<unix domain socket name>\n"
140 " adb reverse --norebind <remote> <local>\n"
141 " - same as 'adb reverse <remote> <local>' but fails\n"
142 " if <remote> is already reversed.\n"
143 " adb reverse --remove <remote>\n"
144 " - remove a specific reversed socket connection\n"
145 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800146 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700147 " adb install [-lrtsd] <file>\n"
148 " adb install-multiple [-lrtsdp] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700149 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700150 " (-l: forward lock application)\n"
151 " (-r: replace existing application)\n"
152 " (-t: allow test packages)\n"
153 " (-s: install application on sdcard)\n"
154 " (-d: allow version code downgrade)\n"
155 " (-p: partial application install)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800156 " adb uninstall [-k] <package> - remove this app package from the device\n"
157 " ('-k' means keep the data and cache directories)\n"
158 " adb bugreport - return all information from the device\n"
159 " that should be included in a bug report.\n"
160 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800161 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700162 " - write an archive of the device's data to <file>.\n"
163 " If no -f option is supplied then the data is written\n"
164 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700165 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700166 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800167 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
168 " (aka .obb) files associated with each application; the default\n"
169 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700170 " (-shared|-noshared enable/disable backup of the device's\n"
171 " shared storage / SD card contents; the default is noshared.)\n"
172 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700173 " (-system|-nosystem toggles whether -all automatically includes\n"
174 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700175 " (<packages...> is the list of applications to be backed up. If\n"
176 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700177 " list is optional. Applications explicitly given on the\n"
178 " command line will be included even if -nosystem would\n"
179 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700180 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700181 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700182 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800183 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
184 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800185 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
186 " and the public key is stored in <file>.pub. Any existing files\n"
187 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800188 " adb help - show this help message\n"
189 " adb version - show version num\n"
190 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800191 "scripting:\n"
192 " adb wait-for-device - block until device is online\n"
193 " adb start-server - ensure that there is a server running\n"
194 " adb kill-server - kill the server if it is running\n"
195 " adb get-state - prints: offline | bootloader | device\n"
196 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700197 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000198 " 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 -0700199 " adb reboot [bootloader|recovery]\n"
200 " - reboots the device, optionally into the bootloader or recovery program.\n"
201 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
202 " adb reboot sideload-auto-reboot\n"
203 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700204 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700205 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500206 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800207 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000208 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700209 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800210 "networking:\n"
211 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500212 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800213 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
214 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
215 "\n"
216 "adb sync notes: adb sync [ <directory> ]\n"
217 " <localdir> can be interpreted in several ways:\n"
218 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000219 " - 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 -0800220 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000221 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800222 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000223 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700224 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000225 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
226 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
227 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
228 " 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 -0800229 );
230}
231
Elliott Hughes58305772015-04-17 13:57:15 -0700232static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800233 help();
234 return 1;
235}
236
Yabin Cuid325e862014-11-17 14:48:25 -0800237#if defined(_WIN32)
238
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700239// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800240void stdin_raw_init(int fd);
241void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800242
243#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100244static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800245
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100246static void stdin_raw_init(int fd) {
247 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800248
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100249 termios tio;
250 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800251
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100252 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800253
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100254 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800255 tio.c_cc[VTIME] = 0;
256 tio.c_cc[VMIN] = 1;
257
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100258 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800259}
260
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100261static void stdin_raw_restore(int fd) {
262 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800263}
264#endif
265
David Pursell606835a2015-09-08 17:17:02 -0700266// Reads from |fd| and prints received data. If |use_shell_protocol| is true
267// this expects that incoming data will use the shell protocol, in which case
268// stdout/stderr are routed independently and the remote exit code will be
269// returned.
270static int read_and_dump(int fd, bool use_shell_protocol=false) {
271 int exit_code = 0;
272 std::unique_ptr<ShellProtocol> protocol;
273 int length = 0;
274 FILE* outfile = stdout;
275
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
Elliott Hughes5677c232015-05-07 23:37:40 -0700287 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700288 if (use_shell_protocol) {
289 if (!protocol->Read()) {
290 break;
291 }
292 switch (protocol->id()) {
293 case ShellProtocol::kIdStdout:
294 outfile = stdout;
295 break;
296 case ShellProtocol::kIdStderr:
297 outfile = stderr;
298 break;
299 case ShellProtocol::kIdExit:
300 exit_code = protocol->data()[0];
301 continue;
302 default:
303 continue;
304 }
305 length = protocol->data_length();
306 } else {
307 D("read_and_dump(): pre adb_read(fd=%d)", fd);
308 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
309 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
310 if (length <= 0) {
311 break;
312 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800313 }
314
David Pursell606835a2015-09-08 17:17:02 -0700315 fwrite(buffer_ptr, 1, length, outfile);
316 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800317 }
David Pursell606835a2015-09-08 17:17:02 -0700318
319 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800320}
321
Jeff Sharkey960df972014-06-09 17:30:57 -0700322static void read_status_line(int fd, char* buf, size_t count)
323{
324 count--;
325 while (count > 0) {
326 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700327 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700328 break;
329 }
330
331 buf += len;
332 count -= len;
333 }
334 *buf = '\0';
335}
336
Christopher Tated2f54152011-04-21 12:53:28 -0700337static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700338 const size_t BUFSIZE = 32 * 1024;
339 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700340 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700341 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700342 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700343#ifdef _WIN32
344 int old_stdin_mode = -1;
345 int old_stdout_mode = -1;
346#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700347
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700348 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800349
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700350 if (inFd == STDIN_FILENO) {
351 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700352#ifdef _WIN32
353 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
354 if (old_stdin_mode == -1) {
355 fatal_errno("could not set stdin to binary");
356 }
357#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700358 }
Yabin Cuid325e862014-11-17 14:48:25 -0800359
Spencer Lowb7dfb792015-05-22 16:48:31 -0700360#ifdef _WIN32
361 if (outFd == STDOUT_FILENO) {
362 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
363 if (old_stdout_mode == -1) {
364 fatal_errno("could not set stdout to binary");
365 }
366 }
367#endif
368
Elliott Hughesa7090b92015-04-17 17:03:59 -0700369 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700370 if (inFd == STDIN_FILENO) {
371 len = unix_read(inFd, buf, BUFSIZE);
372 } else {
373 len = adb_read(inFd, buf, BUFSIZE);
374 }
Christopher Tated2f54152011-04-21 12:53:28 -0700375 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700376 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700377 break;
378 }
379 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700380 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700381 break;
382 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700383 if (outFd == STDOUT_FILENO) {
384 fwrite(buf, 1, len, stdout);
385 fflush(stdout);
386 } else {
387 adb_write(outFd, buf, len);
388 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700389 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700390 }
Yabin Cuid325e862014-11-17 14:48:25 -0800391
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700392 if (inFd == STDIN_FILENO) {
393 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700394#ifdef _WIN32
395 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
396 fatal_errno("could not restore stdin mode");
397 }
398#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700399 }
Yabin Cuid325e862014-11-17 14:48:25 -0800400
Spencer Lowb7dfb792015-05-22 16:48:31 -0700401#ifdef _WIN32
402 if (outFd == STDOUT_FILENO) {
403 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
404 fatal_errno("could not restore stdout mode");
405 }
406 }
407#endif
408
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700409 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700410 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700411}
412
David Pursell606835a2015-09-08 17:17:02 -0700413namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800414
David Pursell606835a2015-09-08 17:17:02 -0700415// Used to pass multiple values to the stdin read thread.
416struct StdinReadArgs {
417 int stdin_fd, write_fd;
418 std::unique_ptr<ShellProtocol> protocol;
419};
420
421} // namespace
422
423// Loops to read from stdin and push the data to the given FD.
424// The argument should be a pointer to a StdinReadArgs object. This function
425// will take ownership of the object and delete it when finished.
426static void* stdin_read_thread(void* x) {
427 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
428 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800429
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700430 adb_thread_setname("stdin reader");
431
David Pursell606835a2015-09-08 17:17:02 -0700432 char raw_buffer[1024];
433 char* buffer_ptr = raw_buffer;
434 size_t buffer_size = sizeof(raw_buffer);
435 if (args->protocol) {
436 buffer_ptr = args->protocol->data();
437 buffer_size = args->protocol->data_capacity();
438 }
439
Elliott Hughesaa245492015-08-03 10:38:08 -0700440 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700441 // Use unix_read() rather than adb_read() for stdin.
442 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
443 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
444 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700445 if (r <= 0) break;
David Pursell606835a2015-09-08 17:17:02 -0700446 for (int n = 0; n < r; n++){
447 switch(buffer_ptr[n]) {
Mike Lockwood67d53582010-05-25 13:40:15 -0400448 case '\n':
449 state = 1;
450 break;
451 case '\r':
452 state = 1;
453 break;
454 case '~':
455 if(state == 1) state++;
456 break;
457 case '.':
458 if(state == 2) {
459 fprintf(stderr,"\n* disconnect *\n");
David Pursell606835a2015-09-08 17:17:02 -0700460 stdin_raw_restore(args->stdin_fd);
Mike Lockwood67d53582010-05-25 13:40:15 -0400461 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800462 }
Mike Lockwood67d53582010-05-25 13:40:15 -0400463 default:
464 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800465 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800466 }
David Pursell606835a2015-09-08 17:17:02 -0700467 if (args->protocol) {
468 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
469 break;
470 }
471 } else {
472 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
473 break;
474 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800475 }
476 }
David Pursell606835a2015-09-08 17:17:02 -0700477
478 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800479}
480
David Pursell4e2fd362015-09-22 10:43:08 -0700481static int interactive_shell(const std::string& service_string,
482 bool use_shell_protocol) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700483 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700484 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700485 if (fd < 0) {
486 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800487 return 1;
488 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800489
David Pursell606835a2015-09-08 17:17:02 -0700490 StdinReadArgs* args = new StdinReadArgs;
491 if (!args) {
492 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700493 return 1;
494 }
David Pursell606835a2015-09-08 17:17:02 -0700495 args->stdin_fd = 0;
496 args->write_fd = fd;
497 if (use_shell_protocol) {
498 args->protocol.reset(new ShellProtocol(args->write_fd));
499 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700500
David Pursell606835a2015-09-08 17:17:02 -0700501 stdin_raw_init(args->stdin_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800502
David Pursell606835a2015-09-08 17:17:02 -0700503 int exit_code = 0;
504 if (!adb_thread_create(stdin_read_thread, args)) {
505 PLOG(ERROR) << "error starting stdin read thread";
506 exit_code = 1;
507 delete args;
508 } else {
509 exit_code = read_and_dump(fd, use_shell_protocol);
510 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700511
David Pursell606835a2015-09-08 17:17:02 -0700512 stdin_raw_restore(args->stdin_fd);
513 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800514}
515
516
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700517static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800518 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700519 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800520 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700521
522 const char* prefix = "host";
523 if (type == kTransportUsb) {
524 prefix = "host-usb";
525 } else if (type == kTransportLocal) {
526 prefix = "host-local";
527 }
528 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800529}
530
David Pursell4e2fd362015-09-22 10:43:08 -0700531// Returns the FeatureSet for the indicated transport.
532static FeatureSet GetFeatureSet(TransportType transport_type,
David Pursell71c83122015-09-14 15:33:50 -0700533 const char* serial) {
David Pursell4e2fd362015-09-22 10:43:08 -0700534 std::string result, error;
535
536 if (adb_query(format_host_command("features", transport_type, serial),
537 &result, &error)) {
538 return StringToFeatureSet(result);
David Pursell71c83122015-09-14 15:33:50 -0700539 }
David Pursell4e2fd362015-09-22 10:43:08 -0700540 return FeatureSet();
David Pursell71c83122015-09-14 15:33:50 -0700541}
542
Elliott Hughes6452a892015-04-29 12:28:13 -0700543static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700544 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800545{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700546 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700547 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700548 if (fd < 0) {
549 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800550 return -1;
551 }
552
553 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800554 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800555
Elliott Hughes6452a892015-04-29 12:28:13 -0700556 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800557 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800558
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700559 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700560 const char* x = strrchr(service, ':');
561 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800562 }
563
Elliott Hughes6452a892015-04-29 12:28:13 -0700564 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800565 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700566 if (!WriteFdExactly(fd, ptr, xfer)) {
567 std::string error;
568 adb_status(fd, &error);
569 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800570 return -1;
571 }
572 sz -= xfer;
573 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700574 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100575 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800576 fflush(stdout);
577 }
578 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700579 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800580 printf("\n");
581 }
582
Elliott Hughese67f1f82015-04-30 17:32:03 -0700583 if (!adb_status(fd, &error)) {
584 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800585 return -1;
586 }
587
588 adb_close(fd);
589 return 0;
590}
591
Doug Zongker71fe5842014-06-26 15:35:36 -0700592#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
593
594/*
595 * The sideload-host protocol serves the data in a file (given on the
596 * command line) to the client, using a simple protocol:
597 *
598 * - The connect message includes the total number of bytes in the
599 * file and a block size chosen by us.
600 *
601 * - The other side sends the desired block number as eight decimal
602 * digits (eg "00000023" for block 23). Blocks are numbered from
603 * zero.
604 *
605 * - We send back the data of the requested block. The last block is
606 * likely to be partial; when the last block is requested we only
607 * send the part of the block that exists, it's not padded up to the
608 * block size.
609 *
610 * - When the other side sends "DONEDONE" instead of a block number,
611 * we hang up.
612 */
Elliott Hughes58305772015-04-17 13:57:15 -0700613static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700614 unsigned sz;
615 size_t xfer = 0;
616 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800617 int last_percent = -1;
618 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700619
620 printf("loading: '%s'", fn);
621 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800622 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700623 if (data == 0) {
624 printf("\n");
625 fprintf(stderr, "* cannot read '%s' *\n", fn);
626 return -1;
627 }
628
Elliott Hughes6452a892015-04-29 12:28:13 -0700629 std::string service =
630 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700631 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700632 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700633 if (fd < 0) {
634 // Try falling back to the older sideload method. Maybe this
635 // is an older device that doesn't support sideload-host.
636 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700637 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700638 goto done;
639 }
640
Spencer Lowf055c192015-01-25 14:40:16 -0800641 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700642
Elliott Hughesa7090b92015-04-17 17:03:59 -0700643 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700644 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800645 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700646 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700647 status = -1;
648 goto done;
649 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700650 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700651
Elliott Hughes6452a892015-04-29 12:28:13 -0700652 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700653 status = 0;
654 break;
655 }
656
Doug Zongker71fe5842014-06-26 15:35:36 -0700657 int block = strtol(buf, NULL, 10);
658
659 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
660 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700661 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700662 status = -1;
663 goto done;
664 }
665 uint8_t* start = data + offset;
666 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
667 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
668 if (offset_end > sz) {
669 to_write = sz - offset;
670 }
671
Dan Albertcc731cc2015-02-24 21:26:58 -0800672 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700673 adb_status(fd, &error);
674 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700675 status = -1;
676 goto done;
677 }
678 xfer += to_write;
679
680 // For normal OTA packages, we expect to transfer every byte
681 // twice, plus a bit of overhead (one read during
682 // verification, one read of each byte for installation, plus
683 // extra access to things like the zip central directory).
684 // This estimate of the completion becomes 100% when we've
685 // transferred ~2.13 (=100/47) times the package size.
686 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
687 if (percent != last_percent) {
688 printf("\rserving: '%s' (~%d%%) ", fn, percent);
689 fflush(stdout);
690 last_percent = percent;
691 }
692 }
693
Colin Cross6d6a8982014-07-07 14:12:41 -0700694 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700695
696 done:
697 if (fd >= 0) adb_close(fd);
698 free(data);
699 return status;
700}
701
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800702/**
703 * Run ppp in "notty" mode against a resource listed as the first parameter
704 * eg:
705 *
706 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
707 *
708 */
Elliott Hughes58305772015-04-17 13:57:15 -0700709static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800710#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800711 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
712 return -1;
713#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800714 if (argc < 2) {
715 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
716 argv[0]);
717
718 return 1;
719 }
720
Dan Albertbac34742015-02-25 17:51:28 -0800721 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700722 std::string error;
723 int fd = adb_connect(adb_service_name, &error);
724 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800725 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700726 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800727 return 1;
728 }
729
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700730 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800731
732 if (pid < 0) {
733 perror("from fork()");
734 return 1;
735 } else if (pid == 0) {
736 int err;
737 int i;
738 const char **ppp_args;
739
740 // copy args
741 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
742 ppp_args[0] = "pppd";
743 for (i = 2 ; i < argc ; i++) {
744 //argv[2] and beyond become ppp_args[1] and beyond
745 ppp_args[i - 1] = argv[i];
746 }
747 ppp_args[i-1] = NULL;
748
749 // child side
750
751 dup2(fd, STDIN_FILENO);
752 dup2(fd, STDOUT_FILENO);
753 adb_close(STDERR_FILENO);
754 adb_close(fd);
755
756 err = execvp("pppd", (char * const *)ppp_args);
757
758 if (err < 0) {
759 perror("execing pppd");
760 }
761 exit(-1);
762 } else {
763 // parent side
764
765 adb_close(fd);
766 return 0;
767 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800768#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800769}
770
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700771static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700772 // Was the caller vague about what they'd like us to wait for?
773 // If so, check they weren't more specific in their choice of transport type.
774 if (strcmp(service, "wait-for-device") == 0) {
775 if (t == kTransportUsb) {
776 service = "wait-for-usb";
777 } else if (t == kTransportLocal) {
778 service = "wait-for-local";
779 } else {
780 service = "wait-for-any";
781 }
782 }
783
784 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700785 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700786}
787
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700788static int send_shell_command(TransportType transport_type, const char* serial,
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700789 const std::string& command) {
790 int fd;
791 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700792 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700793 fd = adb_connect(command, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700794 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800795 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700796 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800797 fprintf(stderr,"- waiting for device -\n");
798 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700799 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800800 }
801
David Pursell4e2fd362015-09-22 10:43:08 -0700802 FeatureSet features = GetFeatureSet(transport_type, serial);
803 int exit_code = read_and_dump(fd, features.count(kFeatureShell2) > 0);
David Pursell71c83122015-09-14 15:33:50 -0700804
805 if (adb_close(fd) < 0) {
806 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700807 }
David Pursell71c83122015-09-14 15:33:50 -0700808
809 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800810}
811
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700812static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700813 char* log_tags = getenv("ANDROID_LOG_TAGS");
814 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800815
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700816 std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800817
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700818 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700819 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800820 }
821
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700822 --argc;
823 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700824 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700825 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800826 }
827
Elliott Hughes15551472015-04-21 17:58:55 -0700828 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800829}
830
Dan Albertbac34742015-02-25 17:51:28 -0800831static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700832 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700833
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700834 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700835 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700836 if (!strcmp("-f", argv[i])) {
837 if (i == argc-1) {
838 fprintf(stderr, "adb: -f passed with no filename\n");
839 return usage();
840 }
841 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700842 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700843 argv[i++] = argv[j++];
844 }
845 argc -= 2;
846 argv[argc] = NULL;
847 }
Christopher Tated2f54152011-04-21 12:53:28 -0700848 }
849
Christopher Tatebb86bc52011-08-22 17:12:08 -0700850 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
851 if (argc < 2) return usage();
852
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800853 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700854 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700855 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700856 if (outFd < 0) {
857 fprintf(stderr, "adb: unable to open file %s\n", filename);
858 return -1;
859 }
860
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700861 std::string cmd = "backup:";
862 --argc;
863 ++argv;
864 while (argc-- > 0) {
865 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700866 }
867
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700868 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700869 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700870 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700871 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700872 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700873 adb_close(outFd);
874 return -1;
875 }
876
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800877 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700878 copy_to_file(fd, outFd);
879
880 adb_close(fd);
881 adb_close(outFd);
882 return 0;
883}
884
Dan Albertbac34742015-02-25 17:51:28 -0800885static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700886 if (argc != 2) return usage();
887
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700888 const char* filename = argv[1];
889 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700890 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700891 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700892 return -1;
893 }
894
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700895 std::string error;
896 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700897 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700898 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700899 adb_close(tarFd);
900 return -1;
901 }
902
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800903 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700904 copy_to_file(tarFd, fd);
905
906 adb_close(fd);
907 adb_close(tarFd);
908 return 0;
909}
910
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800911/* <hint> may be:
912 * - A simple product name
913 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800914 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
915 * e.g., "out/target/product/sooner"
916 * - An absolute path to the PRODUCT_OUT dir
917 * e.g., "/src/device/out/target/product/sooner"
918 *
919 * Given <hint>, try to construct an absolute path to the
920 * ANDROID_PRODUCT_OUT dir.
921 */
Elliott Hughes5c742702015-07-30 17:42:01 -0700922static std::string find_product_out_path(const std::string& hint) {
923 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -0700924 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800925 }
926
Elliott Hughes58305772015-04-17 13:57:15 -0700927 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -0700928 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -0700929 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800930 }
931
Elliott Hughes58305772015-04-17 13:57:15 -0700932 // If there are any slashes in it, assume it's a relative path;
933 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -0700934 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700935 std::string cwd;
936 if (!getcwd(&cwd)) {
937 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -0700938 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800939 }
Elliott Hughes5c742702015-07-30 17:42:01 -0700940 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 -0800941 }
942
Elliott Hughes58305772015-04-17 13:57:15 -0700943 // It's a string without any slashes. Try to do something with it.
944 //
945 // Try to find the root of the build tree, and build a PRODUCT_OUT
946 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -0700947 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -0700948 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700949 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -0700950 return "";
951 }
Elliott Hughesa7090b92015-04-17 17:03:59 -0700952
953 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -0700954 path += OS_PATH_SEPARATOR_STR;
955 path += "out";
956 path += OS_PATH_SEPARATOR_STR;
957 path += "target";
958 path += OS_PATH_SEPARATOR_STR;
959 path += "product";
960 path += OS_PATH_SEPARATOR_STR;
961 path += hint;
962 if (!directory_exists(path)) {
963 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -0700964 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -0700965 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800966 }
Elliott Hughes58305772015-04-17 13:57:15 -0700967 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800968}
969
Dan Albertbac34742015-02-25 17:51:28 -0800970static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -0700971 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -0800972 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700973 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700974 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -0700975
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700976 while (narg > 0) {
977 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700978 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700979 } else if (!strcmp(*arg, "-a")) {
980 *copy_attrs = 1;
981 } else {
982 break;
983 }
Mark Lindner76f2a932014-03-11 17:55:59 -0700984 ++arg;
985 --narg;
986 }
987
988 if (narg > 0) {
989 *path1 = *arg;
990 ++arg;
991 --narg;
992 }
993
994 if (narg > 0) {
995 *path2 = *arg;
996 }
997}
998
Elliott Hughes6452a892015-04-29 12:28:13 -0700999static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001000 std::string error;
1001 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001002 if (fd < 0) {
1003 fprintf(stderr, "error: %s\n", error.c_str());
1004 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001005 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001006 read_and_dump(fd);
1007 adb_close(fd);
1008 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001009}
1010
Elliott Hughes6452a892015-04-29 12:28:13 -07001011static int adb_query_command(const std::string& command) {
1012 std::string result;
1013 std::string error;
1014 if (!adb_query(command, &result, &error)) {
1015 fprintf(stderr, "error: %s\n", error.c_str());
1016 return 1;
1017 }
1018 printf("%s\n", result.c_str());
1019 return 0;
1020}
1021
Spencer Lowa13df302015-09-07 16:20:13 -07001022// Disallow stdin, stdout, and stderr.
1023static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1024#ifdef _WIN32
1025 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1026 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1027 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1028 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1029#else
1030 return ack_reply_fd > 2;
1031#endif
1032}
1033
Elliott Hughesab52c182015-05-01 17:04:38 -07001034int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001035 int no_daemon = 0;
1036 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001037 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001038 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001039 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001040 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001041
Elliott Hughes58305772015-04-17 13:57:15 -07001042 // If defined, this should be an absolute path to
1043 // the directory containing all of the various system images
1044 // for a particular product. If not defined, and the adb
1045 // command requires this information, then the user must
1046 // specify the path using "-p".
1047 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1048 if (ANDROID_PRODUCT_OUT != nullptr) {
1049 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001050 }
1051 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1052
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001053 const char* serial = getenv("ANDROID_SERIAL");
Nick Pellydb449262009-05-07 12:48:03 -07001054
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001055 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001056 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001057 int server_port = DEFAULT_ADB_PORT;
1058 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001059 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001060 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001061 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001062 "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 +01001063 server_port_str);
1064 return usage();
1065 }
1066 }
1067
1068 /* modifiers and flags */
Riley Andrews98f58e82014-12-05 17:37:24 -08001069 while (argc > 0) {
1070 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001071 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001072 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001073 no_daemon = 1;
1074 } else if (!strcmp(argv[0], "fork-server")) {
1075 /* this is a special flag used only when the ADB client launches the ADB Server */
1076 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001077 } else if (!strcmp(argv[0], "--reply-fd")) {
1078 if (argc < 2) return usage();
1079 const char* reply_fd_str = argv[1];
1080 argc--;
1081 argv++;
1082 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001083 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001084 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1085 return usage();
1086 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001087 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001088 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001089 if (argv[0][2] == '\0') {
1090 if (argc < 2) return usage();
1091 product = argv[1];
1092 argc--;
1093 argv++;
1094 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001095 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001096 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001097 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001098 if (gProductOutPath.empty()) {
1099 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001100 return usage();
1101 }
1102 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1103 if (isdigit(argv[0][2])) {
1104 serial = argv[0] + 2;
1105 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001106 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001107 serial = argv[1];
1108 argc--;
1109 argv++;
1110 }
1111 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001112 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001113 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001114 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001115 } else if (!strcmp(argv[0],"-a")) {
1116 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001117 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001118 const char *hostname = NULL;
1119 if (argv[0][2] == '\0') {
1120 if (argc < 2) return usage();
1121 hostname = argv[1];
1122 argc--;
1123 argv++;
1124 } else {
1125 hostname = argv[0] + 2;
1126 }
1127 adb_set_tcp_name(hostname);
1128
Riley Andrews98f58e82014-12-05 17:37:24 -08001129 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001130 if (argv[0][2] == '\0') {
1131 if (argc < 2) return usage();
1132 server_port_str = argv[1];
1133 argc--;
1134 argv++;
1135 } else {
1136 server_port_str = argv[0] + 2;
1137 }
1138 if (strlen(server_port_str) > 0) {
1139 server_port = (int) strtol(server_port_str, NULL, 0);
1140 if (server_port <= 0 || server_port > 65535) {
1141 fprintf(stderr,
1142 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1143 server_port_str);
1144 return usage();
1145 }
1146 } else {
1147 fprintf(stderr,
1148 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1149 return usage();
1150 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001151 } else {
1152 /* out of recognized modifiers and flags */
1153 break;
1154 }
1155 argc--;
1156 argv++;
1157 }
1158
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001159 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001160 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001161
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001162 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001163 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001164 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001165 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1166 return usage();
1167 }
1168 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001169 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001170 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001171 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001172 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001173 fprintf(stderr,"* could not start server *\n");
1174 }
1175 return r;
1176 }
1177
Riley Andrews98f58e82014-12-05 17:37:24 -08001178 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001179 return usage();
1180 }
1181
Riley Andrewsc8514c82014-12-05 17:32:46 -08001182 /* handle wait-for-* prefix */
1183 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001184 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001185
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001186 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001187 return 1;
1188 }
1189
Elliott Hughes2b101112015-05-04 19:29:32 -07001190 // Allow a command to be run after wait-for-device,
1191 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001192 if (argc == 1) {
1193 return 0;
1194 }
1195
1196 /* Fall through */
1197 argc--;
1198 argv++;
1199 }
1200
1201 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001202 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001203 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001204 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001205 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001206 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001207 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001208 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001209 fprintf(stderr, "Usage: adb devices [-l]\n");
1210 return 1;
1211 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001212
1213 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1214 printf("List of devices attached\n");
1215 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001216 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001217 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001218 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001219 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001220 return 1;
1221 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001222
1223 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1224 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001225 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001226 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001227 if (argc > 2) {
1228 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1229 return 1;
1230 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001231
1232 std::string query = android::base::StringPrintf("host:disconnect:%s",
1233 (argc == 2) ? argv[1] : "");
1234 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001235 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001236 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001237 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001238 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001239 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001240 char h = (argv[0][0] == 'h');
1241
David Pursell4e2fd362015-09-22 10:43:08 -07001242 FeatureSet features = GetFeatureSet(transport_type, serial);
1243
1244 bool use_shell_protocol = (features.count(kFeatureShell2) > 0);
1245 if (!use_shell_protocol) {
1246 D("shell protocol not supported, using raw data transfer");
1247 } else {
1248 D("using shell protocol");
1249 }
1250
1251 // Parse shell-specific command-line options.
1252 // argv[0] is always "shell".
1253 --argc;
1254 ++argv;
1255 std::string shell_type_arg;
1256 while (argc) {
1257 if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
1258 if (features.count(kFeatureShell2) == 0) {
1259 fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
1260 return 1;
1261 }
1262 shell_type_arg = argv[0];
1263 --argc;
1264 ++argv;
1265 } else {
1266 break;
1267 }
1268 }
1269 std::string service_string = android::base::StringPrintf(
1270 "shell%s:", shell_type_arg.c_str());
1271
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001272 if (h) {
1273 printf("\x1b[41;33m");
1274 fflush(stdout);
1275 }
1276
David Pursell4e2fd362015-09-22 10:43:08 -07001277 if (!argc) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001278 D("starting interactive shell");
David Pursell4e2fd362015-09-22 10:43:08 -07001279 r = interactive_shell(service_string, use_shell_protocol);
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001280 if (h) {
1281 printf("\x1b[0m");
1282 fflush(stdout);
1283 }
1284 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001285 }
1286
David Pursell4e2fd362015-09-22 10:43:08 -07001287 // We don't escape here, just like ssh(1). http://b/20564385.
1288 service_string += android::base::Join(
1289 std::vector<const char*>(argv, argv + argc), ' ');
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001290
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001291 while (true) {
David Pursell4e2fd362015-09-22 10:43:08 -07001292 D("non-interactive shell loop. cmd=%s", service_string.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001293 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -07001294 int fd = adb_connect(service_string, &error);
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001295 int r;
Riley Andrews98f58e82014-12-05 17:37:24 -08001296 if (fd >= 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001297 D("about to read_and_dump(fd=%d)", fd);
David Pursell606835a2015-09-08 17:17:02 -07001298 r = read_and_dump(fd, use_shell_protocol);
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001299 D("read_and_dump() done.");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001300 adb_close(fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001301 } else {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001302 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001303 r = -1;
1304 }
1305
Elliott Hughes32687be2015-05-05 12:50:26 -07001306 if (h) {
1307 printf("\x1b[0m");
1308 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001309 }
David Pursell606835a2015-09-08 17:17:02 -07001310 D("non-interactive shell loop. return r=%d", r);
Elliott Hughes32687be2015-05-05 12:50:26 -07001311 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001312 }
1313 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001314 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001315 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001316
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001317 std::string cmd = "exec:";
1318 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001319 argc -= 2;
1320 argv += 2;
1321 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001322 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001323 }
1324
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001325 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001326 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001327 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001328 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001329 return -1;
1330 }
1331
1332 if (exec_in) {
1333 copy_to_file(STDIN_FILENO, fd);
1334 } else {
1335 copy_to_file(fd, STDOUT_FILENO);
1336 }
1337
1338 adb_close(fd);
1339 return 0;
1340 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001341 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001342 std::string error;
1343 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001344 if (fd == -2) {
1345 // Failed to make network connection to server. Don't output the
1346 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001347 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001348 // Successful exit code because the server is already "killed".
1349 return 0;
1350 } else if (fd == -1) {
1351 // Some other error.
1352 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001353 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001354 } else {
1355 // Successfully connected, kill command sent, okay status came back.
1356 // Server should exit() in a moment, if not already.
1357 adb_close(fd);
1358 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001359 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001360 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001361 else if (!strcmp(argv[0], "sideload")) {
1362 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001363 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001364 return 1;
1365 } else {
1366 return 0;
1367 }
1368 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001369 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1370 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1371 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001372 else if (!strcmp(argv[0], "remount") ||
1373 !strcmp(argv[0], "reboot") ||
1374 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001375 !strcmp(argv[0], "usb") ||
1376 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001377 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001378 !strcmp(argv[0], "disable-verity") ||
1379 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001380 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001381 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001382 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001383 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001384 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001385 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001386 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001387 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001388 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001389 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001390 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001391 if (argc != 1) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001392 return send_shell_command(transport_type, serial, "shell:bugreport");
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001393 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001394 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001395 bool reverse = !strcmp(argv[0], "reverse");
1396 ++argv;
1397 --argc;
1398 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001399
1400 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001401 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001402 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001403 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001404 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001405 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001406 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001407 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001408 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001409 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001410 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001411 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001412 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001413 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001414 }
1415
Elliott Hughes424af022015-05-29 17:55:19 -07001416 std::string cmd;
1417 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001418 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001419 return adb_query_command(host_prefix + ":list-forward");
1420 } else if (strcmp(argv[0], "--remove-all") == 0) {
1421 if (argc != 1) return usage();
1422 cmd = host_prefix + ":killforward-all";
1423 } else if (strcmp(argv[0], "--remove") == 0) {
1424 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001425 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001426 cmd = host_prefix + ":killforward:" + argv[1];
1427 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1428 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001429 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001430 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1431 } else {
1432 // forward <local> <remote>
1433 if (argc != 2) return usage();
1434 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001435 }
1436
Elliott Hughes424af022015-05-29 17:55:19 -07001437 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001438 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001439 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001440 else if (!strcmp(argv[0], "ls")) {
1441 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001442 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001443 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001444 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001445 bool show_progress = false;
1446 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001447 const char* lpath = NULL, *rpath = NULL;
1448
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001449 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001450 if (!lpath || !rpath || copy_attrs != 0) return usage();
1451 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001452 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001453 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001454 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001455 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001456 const char* rpath = NULL, *lpath = ".";
1457
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001458 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001459 if (!rpath) return usage();
1460 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001461 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001462 else if (!strcmp(argv[0], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001463 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001464 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001465 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001466 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001467 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001468 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001469 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001470 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001471 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001472 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001473 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001474 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001475 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001476 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001477 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001478 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001479 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001480 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001481 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001482 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001483 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001484 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001485 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001486 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001487 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001488 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001489 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001490 } else {
1491 return usage();
1492 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001493
Elliott Hughesd236d072015-04-21 10:17:07 -07001494 if (src != "" &&
1495 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001496 return usage();
1497 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001498
Elliott Hughes58305772015-04-17 13:57:15 -07001499 std::string system_src_path = product_file("system");
1500 std::string data_src_path = product_file("data");
1501 std::string vendor_src_path = product_file("vendor");
1502 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001503
Elliott Hughesaa245492015-08-03 10:38:08 -07001504 bool okay = true;
1505 if (okay && (src.empty() || src == "system")) {
1506 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001507 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001508 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1509 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001510 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001511 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1512 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001513 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001514 if (okay && (src.empty() || src == "data")) {
1515 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001516 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001517 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001518 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001519 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001520 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001521 !strcmp(argv[0],"get-serialno") ||
1522 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001523 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001524 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001525 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001526 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001527 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001528 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001529 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001530 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001531 return ppp(argc, argv);
1532 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001533 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001534 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001535 const int result = adb_connect("host:start-server", &error);
1536 if (result < 0) {
1537 fprintf(stderr, "error: %s\n", error.c_str());
1538 }
1539 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001540 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001541 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001542 return backup(argc, argv);
1543 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001544 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001545 return restore(argc, argv);
1546 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001547 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001548 if (argc < 2) return usage();
1549 return adb_auth_keygen(argv[1]);
1550 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001551 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001552 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001553 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001554 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001555 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001556 help();
1557 return 0;
1558 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001559 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001560 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001561 return 0;
1562 }
Dan Albert90d4b732015-05-20 18:58:41 -07001563 else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001564 // Only list the features common to both the adb client and the device.
1565 FeatureSet features = GetFeatureSet(transport_type, serial);
1566 for (const std::string& name : features) {
1567 if (supported_features().count(name) > 0) {
1568 printf("%s\n", name.c_str());
1569 }
1570 }
1571 return 0;
Dan Albert90d4b732015-05-20 18:58:41 -07001572 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001573
1574 usage();
1575 return 1;
1576}
1577
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001578static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001579 std::string cmd = "shell:pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001580
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001581 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001582 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001583 }
1584
Elliott Hughes15551472015-04-21 17:58:55 -07001585 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001586}
1587
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001588static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001589 /* if the user choose the -k option, we refuse to do it until devices are
1590 out with the option to uninstall the remaining data somehow (adb/ui) */
1591 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1592 {
1593 printf(
1594 "The -k option uninstalls the application while retaining the data/cache.\n"
1595 "At the moment, there is no way to remove the remaining data.\n"
1596 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1597 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1598 return -1;
1599 }
1600
1601 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1602 return pm_command(transport, serial, argc, argv);
1603}
1604
Elliott Hughes5c742702015-07-30 17:42:01 -07001605static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001606 std::string cmd = "shell:rm -f " + escape_arg(filename);
Elliott Hughes15551472015-04-21 17:58:55 -07001607 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001608}
1609
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001610static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001611 static const char *const DATA_DEST = "/data/local/tmp/%s";
1612 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001613 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001614 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001615 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001616
1617 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001618 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001619 where = SD_DEST;
1620 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001621 }
1622
Jeff Sharkey960df972014-06-09 17:30:57 -07001623 // Find last APK argument.
1624 // All other arguments passed through verbatim.
1625 int last_apk = -1;
1626 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001627 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001628 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001629 if (dot && !strcasecmp(dot, ".apk")) {
1630 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1631 fprintf(stderr, "Invalid APK file: %s\n", file);
1632 return -1;
1633 }
1634
1635 last_apk = i;
1636 break;
1637 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001638 }
1639
Jeff Sharkey960df972014-06-09 17:30:57 -07001640 if (last_apk == -1) {
1641 fprintf(stderr, "Missing APK file\n");
1642 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001643 }
1644
Elliott Hughesaa245492015-08-03 10:38:08 -07001645 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001646 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001647 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001648 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1649 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1650 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001651
Kenny Root60733e92012-03-26 16:14:02 -07001652cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001653 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001654 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001655}
1656
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001657static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001658 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001659{
Jeff Sharkey960df972014-06-09 17:30:57 -07001660 int i;
1661 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001662 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001663
1664 // Find all APK arguments starting at end.
1665 // All other arguments passed through verbatim.
1666 int first_apk = -1;
1667 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001668 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001669 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001670 if (dot && !strcasecmp(dot, ".apk")) {
1671 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1672 fprintf(stderr, "Invalid APK file: %s\n", file);
1673 return -1;
1674 }
1675
1676 total_size += sb.st_size;
1677 first_apk = i;
1678 } else {
1679 break;
1680 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001681 }
1682
Jeff Sharkey960df972014-06-09 17:30:57 -07001683 if (first_apk == -1) {
1684 fprintf(stderr, "Missing APK file\n");
1685 return 1;
1686 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001687
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001688 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001689 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001690 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001691 }
1692
1693 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001694 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001695 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001696 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001697 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001698 return -1;
1699 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001700 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001701 read_status_line(fd, buf, sizeof(buf));
1702 adb_close(fd);
1703
1704 int session_id = -1;
1705 if (!strncmp("Success", buf, 7)) {
1706 char* start = strrchr(buf, '[');
1707 char* end = strrchr(buf, ']');
1708 if (start && end) {
1709 *end = '\0';
1710 session_id = strtol(start + 1, NULL, 10);
1711 }
1712 }
1713 if (session_id < 0) {
1714 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001715 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001716 return -1;
1717 }
1718
1719 // Valid session, now stream the APKs
1720 int success = 1;
1721 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001722 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001723 if (stat(file, &sb) == -1) {
1724 fprintf(stderr, "Failed to stat %s\n", file);
1725 success = 0;
1726 goto finalize_session;
1727 }
1728
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001729 std::string cmd = android::base::StringPrintf(
1730 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001731 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001732
1733 int localFd = adb_open(file, O_RDONLY);
1734 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001735 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001736 success = 0;
1737 goto finalize_session;
1738 }
1739
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001740 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001741 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001742 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001743 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001744 adb_close(localFd);
1745 success = 0;
1746 goto finalize_session;
1747 }
1748
1749 copy_to_file(localFd, remoteFd);
1750 read_status_line(remoteFd, buf, sizeof(buf));
1751
1752 adb_close(localFd);
1753 adb_close(remoteFd);
1754
1755 if (strncmp("Success", buf, 7)) {
1756 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001757 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001758 success = 0;
1759 goto finalize_session;
1760 }
1761 }
1762
1763finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001764 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001765 std::string service =
1766 android::base::StringPrintf("exec:pm install-%s %d",
1767 success ? "commit" : "abandon", session_id);
1768 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001769 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001770 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001771 return -1;
1772 }
1773 read_status_line(fd, buf, sizeof(buf));
1774 adb_close(fd);
1775
1776 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001777 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001778 return 0;
1779 } else {
1780 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001781 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001782 return -1;
1783 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001784}