blob: 985b2bb1e071ba058abff19bb6a4f1e7de228c8e [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG ADB
Dan Albert33134262015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Dan Albert76649012015-02-24 15:51:19 -080021#include <assert.h>
22#include <ctype.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <errno.h>
Elliott Hughes2940ccf2015-04-17 14:07:52 -070024#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <limits.h>
26#include <stdarg.h>
Dan Albert76649012015-02-24 15:51:19 -080027#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031#include <sys/stat.h>
Dan Albert76649012015-02-24 15:51:19 -080032#include <sys/types.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
David Pursell606835a2015-09-08 17:17:02 -070034#include <memory>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070035#include <string>
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"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900147 " adb install [-lrtsdg] <file>\n"
Svetoslav23d84072015-06-01 16:02:50 -0700148 " - push this package file to the device and install it\n"
149 " (-l: forward lock application)\n"
150 " (-r: replace existing application)\n"
151 " (-t: allow test packages)\n"
152 " (-s: install application on sdcard)\n"
153 " (-d: allow version code downgrade)\n"
154 " (-g: grant all runtime permissions)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900155 " adb install-multiple [-lrtsdpg] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700156 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700157 " (-l: forward lock application)\n"
158 " (-r: replace existing application)\n"
159 " (-t: allow test packages)\n"
160 " (-s: install application on sdcard)\n"
161 " (-d: allow version code downgrade)\n"
162 " (-p: partial application install)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900163 " (-g: grant all runtime permissions)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800164 " adb uninstall [-k] <package> - remove this app package from the device\n"
165 " ('-k' means keep the data and cache directories)\n"
166 " adb bugreport - return all information from the device\n"
167 " that should be included in a bug report.\n"
168 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800169 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700170 " - write an archive of the device's data to <file>.\n"
171 " If no -f option is supplied then the data is written\n"
172 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700173 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700174 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800175 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
176 " (aka .obb) files associated with each application; the default\n"
177 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700178 " (-shared|-noshared enable/disable backup of the device's\n"
179 " shared storage / SD card contents; the default is noshared.)\n"
180 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700181 " (-system|-nosystem toggles whether -all automatically includes\n"
182 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700183 " (<packages...> is the list of applications to be backed up. If\n"
184 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700185 " list is optional. Applications explicitly given on the\n"
186 " command line will be included even if -nosystem would\n"
187 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700188 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700189 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700190 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800191 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
192 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800193 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
194 " and the public key is stored in <file>.pub. Any existing files\n"
195 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800196 " adb help - show this help message\n"
197 " adb version - show version num\n"
198 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800199 "scripting:\n"
200 " adb wait-for-device - block until device is online\n"
201 " adb start-server - ensure that there is a server running\n"
202 " adb kill-server - kill the server if it is running\n"
203 " adb get-state - prints: offline | bootloader | device\n"
204 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700205 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000206 " 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 -0700207 " adb reboot [bootloader|recovery]\n"
208 " - reboots the device, optionally into the bootloader or recovery program.\n"
209 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
210 " adb reboot sideload-auto-reboot\n"
211 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700212 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700213 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500214 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800215 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000216 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700217 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800218 "networking:\n"
219 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500220 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800221 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
222 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
223 "\n"
224 "adb sync notes: adb sync [ <directory> ]\n"
225 " <localdir> can be interpreted in several ways:\n"
226 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000227 " - 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 -0800228 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000229 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800230 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000231 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700232 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000233 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
234 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
235 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
236 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800237 );
238}
239
Elliott Hughes58305772015-04-17 13:57:15 -0700240static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800241 help();
242 return 1;
243}
244
Yabin Cuid325e862014-11-17 14:48:25 -0800245#if defined(_WIN32)
246
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700247// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800248void stdin_raw_init(int fd);
249void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800250
251#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100252static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800253
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100254static void stdin_raw_init(int fd) {
255 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100257 termios tio;
258 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800259
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100260 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800261
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100262 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800263 tio.c_cc[VTIME] = 0;
264 tio.c_cc[VMIN] = 1;
265
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100266 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800267}
268
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100269static void stdin_raw_restore(int fd) {
270 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800271}
272#endif
273
David Pursell606835a2015-09-08 17:17:02 -0700274// Reads from |fd| and prints received data. If |use_shell_protocol| is true
275// this expects that incoming data will use the shell protocol, in which case
276// stdout/stderr are routed independently and the remote exit code will be
277// returned.
278static int read_and_dump(int fd, bool use_shell_protocol=false) {
279 int exit_code = 0;
280 std::unique_ptr<ShellProtocol> protocol;
281 int length = 0;
282 FILE* outfile = stdout;
283
284 char raw_buffer[BUFSIZ];
285 char* buffer_ptr = raw_buffer;
286 if (use_shell_protocol) {
287 protocol.reset(new ShellProtocol(fd));
288 if (!protocol) {
289 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
290 return 1;
291 }
292 buffer_ptr = protocol->data();
293 }
294
Elliott Hughes5677c232015-05-07 23:37:40 -0700295 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700296 if (use_shell_protocol) {
297 if (!protocol->Read()) {
298 break;
299 }
300 switch (protocol->id()) {
301 case ShellProtocol::kIdStdout:
302 outfile = stdout;
303 break;
304 case ShellProtocol::kIdStderr:
305 outfile = stderr;
306 break;
307 case ShellProtocol::kIdExit:
308 exit_code = protocol->data()[0];
309 continue;
310 default:
311 continue;
312 }
313 length = protocol->data_length();
314 } else {
315 D("read_and_dump(): pre adb_read(fd=%d)", fd);
316 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
317 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
318 if (length <= 0) {
319 break;
320 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800321 }
322
David Pursell606835a2015-09-08 17:17:02 -0700323 fwrite(buffer_ptr, 1, length, outfile);
324 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800325 }
David Pursell606835a2015-09-08 17:17:02 -0700326
327 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800328}
329
Jeff Sharkey960df972014-06-09 17:30:57 -0700330static void read_status_line(int fd, char* buf, size_t count)
331{
332 count--;
333 while (count > 0) {
334 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700335 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700336 break;
337 }
338
339 buf += len;
340 count -= len;
341 }
342 *buf = '\0';
343}
344
Christopher Tated2f54152011-04-21 12:53:28 -0700345static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700346 const size_t BUFSIZE = 32 * 1024;
347 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700348 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700349 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700350 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700351#ifdef _WIN32
352 int old_stdin_mode = -1;
353 int old_stdout_mode = -1;
354#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700355
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700356 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800357
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700358 if (inFd == STDIN_FILENO) {
359 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700360#ifdef _WIN32
361 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
362 if (old_stdin_mode == -1) {
363 fatal_errno("could not set stdin to binary");
364 }
365#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700366 }
Yabin Cuid325e862014-11-17 14:48:25 -0800367
Spencer Lowb7dfb792015-05-22 16:48:31 -0700368#ifdef _WIN32
369 if (outFd == STDOUT_FILENO) {
370 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
371 if (old_stdout_mode == -1) {
372 fatal_errno("could not set stdout to binary");
373 }
374 }
375#endif
376
Elliott Hughesa7090b92015-04-17 17:03:59 -0700377 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700378 if (inFd == STDIN_FILENO) {
379 len = unix_read(inFd, buf, BUFSIZE);
380 } else {
381 len = adb_read(inFd, buf, BUFSIZE);
382 }
Christopher Tated2f54152011-04-21 12:53:28 -0700383 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700384 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700385 break;
386 }
387 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700388 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700389 break;
390 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700391 if (outFd == STDOUT_FILENO) {
392 fwrite(buf, 1, len, stdout);
393 fflush(stdout);
394 } else {
395 adb_write(outFd, buf, len);
396 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700397 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700398 }
Yabin Cuid325e862014-11-17 14:48:25 -0800399
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700400 if (inFd == STDIN_FILENO) {
401 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700402#ifdef _WIN32
403 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
404 fatal_errno("could not restore stdin mode");
405 }
406#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700407 }
Yabin Cuid325e862014-11-17 14:48:25 -0800408
Spencer Lowb7dfb792015-05-22 16:48:31 -0700409#ifdef _WIN32
410 if (outFd == STDOUT_FILENO) {
411 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
412 fatal_errno("could not restore stdout mode");
413 }
414 }
415#endif
416
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700417 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700418 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700419}
420
David Pursell606835a2015-09-08 17:17:02 -0700421namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800422
David Pursell606835a2015-09-08 17:17:02 -0700423// Used to pass multiple values to the stdin read thread.
424struct StdinReadArgs {
425 int stdin_fd, write_fd;
426 std::unique_ptr<ShellProtocol> protocol;
427};
428
429} // namespace
430
431// Loops to read from stdin and push the data to the given FD.
432// The argument should be a pointer to a StdinReadArgs object. This function
433// will take ownership of the object and delete it when finished.
434static void* stdin_read_thread(void* x) {
435 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
436 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800437
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700438 adb_thread_setname("stdin reader");
439
David Pursell606835a2015-09-08 17:17:02 -0700440 char raw_buffer[1024];
441 char* buffer_ptr = raw_buffer;
442 size_t buffer_size = sizeof(raw_buffer);
443 if (args->protocol) {
444 buffer_ptr = args->protocol->data();
445 buffer_size = args->protocol->data_capacity();
446 }
447
Elliott Hughesaa245492015-08-03 10:38:08 -0700448 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700449 // Use unix_read() rather than adb_read() for stdin.
450 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
451 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
452 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700453 if (r <= 0) break;
David Pursell606835a2015-09-08 17:17:02 -0700454 for (int n = 0; n < r; n++){
455 switch(buffer_ptr[n]) {
Mike Lockwood67d53582010-05-25 13:40:15 -0400456 case '\n':
457 state = 1;
458 break;
459 case '\r':
460 state = 1;
461 break;
462 case '~':
463 if(state == 1) state++;
464 break;
465 case '.':
466 if(state == 2) {
467 fprintf(stderr,"\n* disconnect *\n");
David Pursell606835a2015-09-08 17:17:02 -0700468 stdin_raw_restore(args->stdin_fd);
Mike Lockwood67d53582010-05-25 13:40:15 -0400469 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800470 }
Mike Lockwood67d53582010-05-25 13:40:15 -0400471 default:
472 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800473 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800474 }
David Pursell606835a2015-09-08 17:17:02 -0700475 if (args->protocol) {
476 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
477 break;
478 }
479 } else {
480 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
481 break;
482 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800483 }
484 }
David Pursell606835a2015-09-08 17:17:02 -0700485
486 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800487}
488
David Pursell4e2fd362015-09-22 10:43:08 -0700489static int interactive_shell(const std::string& service_string,
490 bool use_shell_protocol) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700491 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700492 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700493 if (fd < 0) {
494 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800495 return 1;
496 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800497
David Pursell606835a2015-09-08 17:17:02 -0700498 StdinReadArgs* args = new StdinReadArgs;
499 if (!args) {
500 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700501 return 1;
502 }
David Pursell606835a2015-09-08 17:17:02 -0700503 args->stdin_fd = 0;
504 args->write_fd = fd;
505 if (use_shell_protocol) {
506 args->protocol.reset(new ShellProtocol(args->write_fd));
507 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700508
David Pursell606835a2015-09-08 17:17:02 -0700509 stdin_raw_init(args->stdin_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800510
David Pursell606835a2015-09-08 17:17:02 -0700511 int exit_code = 0;
512 if (!adb_thread_create(stdin_read_thread, args)) {
513 PLOG(ERROR) << "error starting stdin read thread";
514 exit_code = 1;
515 delete args;
516 } else {
517 exit_code = read_and_dump(fd, use_shell_protocol);
518 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700519
David Pursell606835a2015-09-08 17:17:02 -0700520 stdin_raw_restore(args->stdin_fd);
521 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800522}
523
524
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700525static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800526 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700527 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800528 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700529
530 const char* prefix = "host";
531 if (type == kTransportUsb) {
532 prefix = "host-usb";
533 } else if (type == kTransportLocal) {
534 prefix = "host-local";
535 }
536 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800537}
538
David Pursell4e2fd362015-09-22 10:43:08 -0700539// Returns the FeatureSet for the indicated transport.
540static FeatureSet GetFeatureSet(TransportType transport_type,
David Pursell71c83122015-09-14 15:33:50 -0700541 const char* serial) {
David Pursell4e2fd362015-09-22 10:43:08 -0700542 std::string result, error;
543
544 if (adb_query(format_host_command("features", transport_type, serial),
545 &result, &error)) {
546 return StringToFeatureSet(result);
David Pursell71c83122015-09-14 15:33:50 -0700547 }
David Pursell4e2fd362015-09-22 10:43:08 -0700548 return FeatureSet();
David Pursell71c83122015-09-14 15:33:50 -0700549}
550
Elliott Hughes6452a892015-04-29 12:28:13 -0700551static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700552 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800553{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700554 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700555 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700556 if (fd < 0) {
557 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800558 return -1;
559 }
560
561 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800562 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800563
Elliott Hughes6452a892015-04-29 12:28:13 -0700564 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800565 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800566
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700567 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700568 const char* x = strrchr(service, ':');
569 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800570 }
571
Elliott Hughes6452a892015-04-29 12:28:13 -0700572 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800573 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700574 if (!WriteFdExactly(fd, ptr, xfer)) {
575 std::string error;
576 adb_status(fd, &error);
577 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800578 return -1;
579 }
580 sz -= xfer;
581 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700582 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100583 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800584 fflush(stdout);
585 }
586 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700587 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800588 printf("\n");
589 }
590
Elliott Hughese67f1f82015-04-30 17:32:03 -0700591 if (!adb_status(fd, &error)) {
592 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800593 return -1;
594 }
595
596 adb_close(fd);
597 return 0;
598}
599
Doug Zongker71fe5842014-06-26 15:35:36 -0700600#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
601
602/*
603 * The sideload-host protocol serves the data in a file (given on the
604 * command line) to the client, using a simple protocol:
605 *
606 * - The connect message includes the total number of bytes in the
607 * file and a block size chosen by us.
608 *
609 * - The other side sends the desired block number as eight decimal
610 * digits (eg "00000023" for block 23). Blocks are numbered from
611 * zero.
612 *
613 * - We send back the data of the requested block. The last block is
614 * likely to be partial; when the last block is requested we only
615 * send the part of the block that exists, it's not padded up to the
616 * block size.
617 *
618 * - When the other side sends "DONEDONE" instead of a block number,
619 * we hang up.
620 */
Elliott Hughes58305772015-04-17 13:57:15 -0700621static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700622 unsigned sz;
623 size_t xfer = 0;
624 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800625 int last_percent = -1;
626 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700627
628 printf("loading: '%s'", fn);
629 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800630 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700631 if (data == 0) {
632 printf("\n");
633 fprintf(stderr, "* cannot read '%s' *\n", fn);
634 return -1;
635 }
636
Elliott Hughes6452a892015-04-29 12:28:13 -0700637 std::string service =
638 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700639 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700640 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700641 if (fd < 0) {
642 // Try falling back to the older sideload method. Maybe this
643 // is an older device that doesn't support sideload-host.
644 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700645 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700646 goto done;
647 }
648
Spencer Lowf055c192015-01-25 14:40:16 -0800649 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700650
Elliott Hughesa7090b92015-04-17 17:03:59 -0700651 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700652 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800653 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700654 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700655 status = -1;
656 goto done;
657 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700658 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700659
Elliott Hughes6452a892015-04-29 12:28:13 -0700660 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700661 status = 0;
662 break;
663 }
664
Doug Zongker71fe5842014-06-26 15:35:36 -0700665 int block = strtol(buf, NULL, 10);
666
667 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
668 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700669 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700670 status = -1;
671 goto done;
672 }
673 uint8_t* start = data + offset;
674 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
675 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
676 if (offset_end > sz) {
677 to_write = sz - offset;
678 }
679
Dan Albertcc731cc2015-02-24 21:26:58 -0800680 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700681 adb_status(fd, &error);
682 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700683 status = -1;
684 goto done;
685 }
686 xfer += to_write;
687
688 // For normal OTA packages, we expect to transfer every byte
689 // twice, plus a bit of overhead (one read during
690 // verification, one read of each byte for installation, plus
691 // extra access to things like the zip central directory).
692 // This estimate of the completion becomes 100% when we've
693 // transferred ~2.13 (=100/47) times the package size.
694 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
695 if (percent != last_percent) {
696 printf("\rserving: '%s' (~%d%%) ", fn, percent);
697 fflush(stdout);
698 last_percent = percent;
699 }
700 }
701
Colin Cross6d6a8982014-07-07 14:12:41 -0700702 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700703
704 done:
705 if (fd >= 0) adb_close(fd);
706 free(data);
707 return status;
708}
709
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800710/**
711 * Run ppp in "notty" mode against a resource listed as the first parameter
712 * eg:
713 *
714 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
715 *
716 */
Elliott Hughes58305772015-04-17 13:57:15 -0700717static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800718#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800719 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
720 return -1;
721#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800722 if (argc < 2) {
723 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
724 argv[0]);
725
726 return 1;
727 }
728
Dan Albertbac34742015-02-25 17:51:28 -0800729 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700730 std::string error;
731 int fd = adb_connect(adb_service_name, &error);
732 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800733 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700734 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800735 return 1;
736 }
737
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700738 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800739
740 if (pid < 0) {
741 perror("from fork()");
742 return 1;
743 } else if (pid == 0) {
744 int err;
745 int i;
746 const char **ppp_args;
747
748 // copy args
749 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
750 ppp_args[0] = "pppd";
751 for (i = 2 ; i < argc ; i++) {
752 //argv[2] and beyond become ppp_args[1] and beyond
753 ppp_args[i - 1] = argv[i];
754 }
755 ppp_args[i-1] = NULL;
756
757 // child side
758
759 dup2(fd, STDIN_FILENO);
760 dup2(fd, STDOUT_FILENO);
761 adb_close(STDERR_FILENO);
762 adb_close(fd);
763
764 err = execvp("pppd", (char * const *)ppp_args);
765
766 if (err < 0) {
767 perror("execing pppd");
768 }
769 exit(-1);
770 } else {
771 // parent side
772
773 adb_close(fd);
774 return 0;
775 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800776#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800777}
778
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700779static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700780 // Was the caller vague about what they'd like us to wait for?
781 // If so, check they weren't more specific in their choice of transport type.
782 if (strcmp(service, "wait-for-device") == 0) {
783 if (t == kTransportUsb) {
784 service = "wait-for-usb";
785 } else if (t == kTransportLocal) {
786 service = "wait-for-local";
787 } else {
788 service = "wait-for-any";
789 }
790 }
791
792 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700793 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700794}
795
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700796static int send_shell_command(TransportType transport_type, const char* serial,
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700797 const std::string& command) {
798 int fd;
799 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700800 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700801 fd = adb_connect(command, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700802 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800803 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700804 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800805 fprintf(stderr,"- waiting for device -\n");
806 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700807 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800808 }
809
David Pursell4e2fd362015-09-22 10:43:08 -0700810 FeatureSet features = GetFeatureSet(transport_type, serial);
811 int exit_code = read_and_dump(fd, features.count(kFeatureShell2) > 0);
David Pursell71c83122015-09-14 15:33:50 -0700812
813 if (adb_close(fd) < 0) {
814 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700815 }
David Pursell71c83122015-09-14 15:33:50 -0700816
817 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800818}
819
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700820static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700821 char* log_tags = getenv("ANDROID_LOG_TAGS");
822 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800823
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700824 std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800825
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700826 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700827 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800828 }
829
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700830 --argc;
831 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700832 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700833 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800834 }
835
Elliott Hughes15551472015-04-21 17:58:55 -0700836 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800837}
838
Dan Albertbac34742015-02-25 17:51:28 -0800839static int backup(int argc, const char** argv) {
Elliott Hughes24f165f2015-08-21 20:31:31 -0700840 const char* filename = "backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700841
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700842 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700843 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700844 if (!strcmp("-f", argv[i])) {
845 if (i == argc-1) {
846 fprintf(stderr, "adb: -f passed with no filename\n");
847 return usage();
848 }
849 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700850 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700851 argv[i++] = argv[j++];
852 }
853 argc -= 2;
854 argv[argc] = NULL;
855 }
Christopher Tated2f54152011-04-21 12:53:28 -0700856 }
857
Christopher Tatebb86bc52011-08-22 17:12:08 -0700858 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
859 if (argc < 2) return usage();
860
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800861 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700862 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700863 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700864 if (outFd < 0) {
865 fprintf(stderr, "adb: unable to open file %s\n", filename);
866 return -1;
867 }
868
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700869 std::string cmd = "backup:";
870 --argc;
871 ++argv;
872 while (argc-- > 0) {
873 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700874 }
875
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700876 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700877 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700878 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700879 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700880 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700881 adb_close(outFd);
882 return -1;
883 }
884
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800885 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700886 copy_to_file(fd, outFd);
887
888 adb_close(fd);
889 adb_close(outFd);
890 return 0;
891}
892
Dan Albertbac34742015-02-25 17:51:28 -0800893static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700894 if (argc != 2) return usage();
895
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700896 const char* filename = argv[1];
897 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700898 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700899 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700900 return -1;
901 }
902
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700903 std::string error;
904 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700905 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700906 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700907 adb_close(tarFd);
908 return -1;
909 }
910
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800911 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700912 copy_to_file(tarFd, fd);
913
914 adb_close(fd);
915 adb_close(tarFd);
916 return 0;
917}
918
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800919/* <hint> may be:
920 * - A simple product name
921 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800922 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
923 * e.g., "out/target/product/sooner"
924 * - An absolute path to the PRODUCT_OUT dir
925 * e.g., "/src/device/out/target/product/sooner"
926 *
927 * Given <hint>, try to construct an absolute path to the
928 * ANDROID_PRODUCT_OUT dir.
929 */
Elliott Hughes5c742702015-07-30 17:42:01 -0700930static std::string find_product_out_path(const std::string& hint) {
931 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -0700932 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800933 }
934
Elliott Hughes58305772015-04-17 13:57:15 -0700935 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -0700936 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -0700937 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800938 }
939
Elliott Hughes58305772015-04-17 13:57:15 -0700940 // If there are any slashes in it, assume it's a relative path;
941 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -0700942 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700943 std::string cwd;
944 if (!getcwd(&cwd)) {
945 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -0700946 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800947 }
Elliott Hughes5c742702015-07-30 17:42:01 -0700948 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 -0800949 }
950
Elliott Hughes58305772015-04-17 13:57:15 -0700951 // It's a string without any slashes. Try to do something with it.
952 //
953 // Try to find the root of the build tree, and build a PRODUCT_OUT
954 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -0700955 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -0700956 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700957 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -0700958 return "";
959 }
Elliott Hughesa7090b92015-04-17 17:03:59 -0700960
961 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -0700962 path += OS_PATH_SEPARATOR_STR;
963 path += "out";
964 path += OS_PATH_SEPARATOR_STR;
965 path += "target";
966 path += OS_PATH_SEPARATOR_STR;
967 path += "product";
968 path += OS_PATH_SEPARATOR_STR;
969 path += hint;
970 if (!directory_exists(path)) {
971 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -0700972 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -0700973 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800974 }
Elliott Hughes58305772015-04-17 13:57:15 -0700975 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800976}
977
Dan Albertbac34742015-02-25 17:51:28 -0800978static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -0700979 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -0800980 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700981 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700982 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -0700983
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700984 while (narg > 0) {
985 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700986 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700987 } else if (!strcmp(*arg, "-a")) {
988 *copy_attrs = 1;
989 } else {
990 break;
991 }
Mark Lindner76f2a932014-03-11 17:55:59 -0700992 ++arg;
993 --narg;
994 }
995
996 if (narg > 0) {
997 *path1 = *arg;
998 ++arg;
999 --narg;
1000 }
1001
1002 if (narg > 0) {
1003 *path2 = *arg;
1004 }
1005}
1006
Elliott Hughes6452a892015-04-29 12:28:13 -07001007static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001008 std::string error;
1009 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001010 if (fd < 0) {
1011 fprintf(stderr, "error: %s\n", error.c_str());
1012 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001013 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001014 read_and_dump(fd);
1015 adb_close(fd);
1016 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001017}
1018
Elliott Hughes6452a892015-04-29 12:28:13 -07001019static int adb_query_command(const std::string& command) {
1020 std::string result;
1021 std::string error;
1022 if (!adb_query(command, &result, &error)) {
1023 fprintf(stderr, "error: %s\n", error.c_str());
1024 return 1;
1025 }
1026 printf("%s\n", result.c_str());
1027 return 0;
1028}
1029
Spencer Lowa13df302015-09-07 16:20:13 -07001030// Disallow stdin, stdout, and stderr.
1031static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1032#ifdef _WIN32
1033 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1034 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1035 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1036 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1037#else
1038 return ack_reply_fd > 2;
1039#endif
1040}
1041
Elliott Hughesab52c182015-05-01 17:04:38 -07001042int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001043 int no_daemon = 0;
1044 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001045 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001046 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001047 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001048 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001049
Elliott Hughes58305772015-04-17 13:57:15 -07001050 // If defined, this should be an absolute path to
1051 // the directory containing all of the various system images
1052 // for a particular product. If not defined, and the adb
1053 // command requires this information, then the user must
1054 // specify the path using "-p".
1055 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1056 if (ANDROID_PRODUCT_OUT != nullptr) {
1057 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001058 }
1059 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1060
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001061 const char* serial = getenv("ANDROID_SERIAL");
Nick Pellydb449262009-05-07 12:48:03 -07001062
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001063 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001064 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001065 int server_port = DEFAULT_ADB_PORT;
1066 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001067 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001068 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001069 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001070 "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 +01001071 server_port_str);
1072 return usage();
1073 }
1074 }
1075
1076 /* modifiers and flags */
Riley Andrews98f58e82014-12-05 17:37:24 -08001077 while (argc > 0) {
1078 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001079 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001080 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001081 no_daemon = 1;
1082 } else if (!strcmp(argv[0], "fork-server")) {
1083 /* this is a special flag used only when the ADB client launches the ADB Server */
1084 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001085 } else if (!strcmp(argv[0], "--reply-fd")) {
1086 if (argc < 2) return usage();
1087 const char* reply_fd_str = argv[1];
1088 argc--;
1089 argv++;
1090 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001091 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001092 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1093 return usage();
1094 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001095 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001096 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001097 if (argv[0][2] == '\0') {
1098 if (argc < 2) return usage();
1099 product = argv[1];
1100 argc--;
1101 argv++;
1102 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001103 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001104 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001105 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001106 if (gProductOutPath.empty()) {
1107 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001108 return usage();
1109 }
1110 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1111 if (isdigit(argv[0][2])) {
1112 serial = argv[0] + 2;
1113 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001114 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001115 serial = argv[1];
1116 argc--;
1117 argv++;
1118 }
1119 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001120 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001121 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001122 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001123 } else if (!strcmp(argv[0],"-a")) {
1124 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001125 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001126 const char *hostname = NULL;
1127 if (argv[0][2] == '\0') {
1128 if (argc < 2) return usage();
1129 hostname = argv[1];
1130 argc--;
1131 argv++;
1132 } else {
1133 hostname = argv[0] + 2;
1134 }
1135 adb_set_tcp_name(hostname);
1136
Riley Andrews98f58e82014-12-05 17:37:24 -08001137 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001138 if (argv[0][2] == '\0') {
1139 if (argc < 2) return usage();
1140 server_port_str = argv[1];
1141 argc--;
1142 argv++;
1143 } else {
1144 server_port_str = argv[0] + 2;
1145 }
1146 if (strlen(server_port_str) > 0) {
1147 server_port = (int) strtol(server_port_str, NULL, 0);
1148 if (server_port <= 0 || server_port > 65535) {
1149 fprintf(stderr,
1150 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1151 server_port_str);
1152 return usage();
1153 }
1154 } else {
1155 fprintf(stderr,
1156 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1157 return usage();
1158 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001159 } else {
1160 /* out of recognized modifiers and flags */
1161 break;
1162 }
1163 argc--;
1164 argv++;
1165 }
1166
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001167 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001168 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001169
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001170 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001171 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001172 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001173 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1174 return usage();
1175 }
1176 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001177 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001178 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001179 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001180 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001181 fprintf(stderr,"* could not start server *\n");
1182 }
1183 return r;
1184 }
1185
Riley Andrews98f58e82014-12-05 17:37:24 -08001186 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001187 return usage();
1188 }
1189
Riley Andrewsc8514c82014-12-05 17:32:46 -08001190 /* handle wait-for-* prefix */
1191 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001192 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001193
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001194 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001195 return 1;
1196 }
1197
Elliott Hughes2b101112015-05-04 19:29:32 -07001198 // Allow a command to be run after wait-for-device,
1199 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001200 if (argc == 1) {
1201 return 0;
1202 }
1203
1204 /* Fall through */
1205 argc--;
1206 argv++;
1207 }
1208
1209 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001210 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001211 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001212 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001213 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001214 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001215 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001216 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001217 fprintf(stderr, "Usage: adb devices [-l]\n");
1218 return 1;
1219 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001220
1221 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1222 printf("List of devices attached\n");
1223 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001224 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001225 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001226 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001227 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001228 return 1;
1229 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001230
1231 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1232 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001233 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001234 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001235 if (argc > 2) {
1236 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1237 return 1;
1238 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001239
1240 std::string query = android::base::StringPrintf("host:disconnect:%s",
1241 (argc == 2) ? argv[1] : "");
1242 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001243 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001244 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001245 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001246 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001247 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001248 char h = (argv[0][0] == 'h');
1249
David Pursell4e2fd362015-09-22 10:43:08 -07001250 FeatureSet features = GetFeatureSet(transport_type, serial);
1251
1252 bool use_shell_protocol = (features.count(kFeatureShell2) > 0);
1253 if (!use_shell_protocol) {
1254 D("shell protocol not supported, using raw data transfer");
1255 } else {
1256 D("using shell protocol");
1257 }
1258
1259 // Parse shell-specific command-line options.
1260 // argv[0] is always "shell".
1261 --argc;
1262 ++argv;
1263 std::string shell_type_arg;
1264 while (argc) {
1265 if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
1266 if (features.count(kFeatureShell2) == 0) {
1267 fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
1268 return 1;
1269 }
1270 shell_type_arg = argv[0];
1271 --argc;
1272 ++argv;
1273 } else {
1274 break;
1275 }
1276 }
1277 std::string service_string = android::base::StringPrintf(
1278 "shell%s:", shell_type_arg.c_str());
1279
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001280 if (h) {
1281 printf("\x1b[41;33m");
1282 fflush(stdout);
1283 }
1284
David Pursell4e2fd362015-09-22 10:43:08 -07001285 if (!argc) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001286 D("starting interactive shell");
David Pursell4e2fd362015-09-22 10:43:08 -07001287 r = interactive_shell(service_string, use_shell_protocol);
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001288 if (h) {
1289 printf("\x1b[0m");
1290 fflush(stdout);
1291 }
1292 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001293 }
1294
David Pursell4e2fd362015-09-22 10:43:08 -07001295 // We don't escape here, just like ssh(1). http://b/20564385.
1296 service_string += android::base::Join(
1297 std::vector<const char*>(argv, argv + argc), ' ');
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001298
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001299 while (true) {
David Pursell4e2fd362015-09-22 10:43:08 -07001300 D("non-interactive shell loop. cmd=%s", service_string.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001301 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -07001302 int fd = adb_connect(service_string, &error);
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001303 int r;
Riley Andrews98f58e82014-12-05 17:37:24 -08001304 if (fd >= 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001305 D("about to read_and_dump(fd=%d)", fd);
David Pursell606835a2015-09-08 17:17:02 -07001306 r = read_and_dump(fd, use_shell_protocol);
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001307 D("read_and_dump() done.");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001308 adb_close(fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001309 } else {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001310 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001311 r = -1;
1312 }
1313
Elliott Hughes32687be2015-05-05 12:50:26 -07001314 if (h) {
1315 printf("\x1b[0m");
1316 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001317 }
David Pursell606835a2015-09-08 17:17:02 -07001318 D("non-interactive shell loop. return r=%d", r);
Elliott Hughes32687be2015-05-05 12:50:26 -07001319 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001320 }
1321 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001322 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001323 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001324
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001325 std::string cmd = "exec:";
1326 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001327 argc -= 2;
1328 argv += 2;
1329 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001330 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001331 }
1332
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001333 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001334 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001335 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001336 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001337 return -1;
1338 }
1339
1340 if (exec_in) {
1341 copy_to_file(STDIN_FILENO, fd);
1342 } else {
1343 copy_to_file(fd, STDOUT_FILENO);
1344 }
1345
1346 adb_close(fd);
1347 return 0;
1348 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001349 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001350 std::string error;
1351 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001352 if (fd == -2) {
1353 // Failed to make network connection to server. Don't output the
1354 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001355 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001356 // Successful exit code because the server is already "killed".
1357 return 0;
1358 } else if (fd == -1) {
1359 // Some other error.
1360 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001361 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001362 } else {
1363 // Successfully connected, kill command sent, okay status came back.
1364 // Server should exit() in a moment, if not already.
1365 adb_close(fd);
1366 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001367 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001368 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001369 else if (!strcmp(argv[0], "sideload")) {
1370 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001371 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001372 return 1;
1373 } else {
1374 return 0;
1375 }
1376 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001377 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1378 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1379 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001380 else if (!strcmp(argv[0], "remount") ||
1381 !strcmp(argv[0], "reboot") ||
1382 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001383 !strcmp(argv[0], "usb") ||
1384 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001385 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001386 !strcmp(argv[0], "disable-verity") ||
1387 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001388 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001389 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001390 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001391 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001392 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001393 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001394 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001395 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001396 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001397 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001398 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001399 if (argc != 1) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001400 return send_shell_command(transport_type, serial, "shell:bugreport");
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001401 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001402 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001403 bool reverse = !strcmp(argv[0], "reverse");
1404 ++argv;
1405 --argc;
1406 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001407
1408 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001409 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001410 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001411 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001412 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001413 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001414 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001415 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001416 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001417 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001418 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001419 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001420 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001421 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001422 }
1423
Elliott Hughes424af022015-05-29 17:55:19 -07001424 std::string cmd;
1425 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001426 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001427 return adb_query_command(host_prefix + ":list-forward");
1428 } else if (strcmp(argv[0], "--remove-all") == 0) {
1429 if (argc != 1) return usage();
1430 cmd = host_prefix + ":killforward-all";
1431 } else if (strcmp(argv[0], "--remove") == 0) {
1432 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001433 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001434 cmd = host_prefix + ":killforward:" + argv[1];
1435 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1436 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001437 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001438 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1439 } else {
1440 // forward <local> <remote>
1441 if (argc != 2) return usage();
1442 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001443 }
1444
Elliott Hughes424af022015-05-29 17:55:19 -07001445 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001446 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001447 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001448 else if (!strcmp(argv[0], "ls")) {
1449 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001450 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001451 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001452 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001453 bool show_progress = false;
1454 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001455 const char* lpath = NULL, *rpath = NULL;
1456
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001457 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001458 if (!lpath || !rpath || copy_attrs != 0) return usage();
1459 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001460 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001461 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001462 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001463 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001464 const char* rpath = NULL, *lpath = ".";
1465
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001466 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001467 if (!rpath) return usage();
1468 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001469 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001470 else if (!strcmp(argv[0], "install")) {
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 install_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], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001475 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001476 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001477 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001478 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001479 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001480 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001481 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001482 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001483 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001484 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001485 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001486 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001487 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001488 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001489 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001490 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001491 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001492 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001493 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001494 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001495 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001496 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001497 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001498 } else {
1499 return usage();
1500 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001501
Elliott Hughesd236d072015-04-21 10:17:07 -07001502 if (src != "" &&
1503 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001504 return usage();
1505 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001506
Elliott Hughes58305772015-04-17 13:57:15 -07001507 std::string system_src_path = product_file("system");
1508 std::string data_src_path = product_file("data");
1509 std::string vendor_src_path = product_file("vendor");
1510 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001511
Elliott Hughesaa245492015-08-03 10:38:08 -07001512 bool okay = true;
1513 if (okay && (src.empty() || src == "system")) {
1514 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001515 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001516 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1517 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001518 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001519 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1520 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001521 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001522 if (okay && (src.empty() || src == "data")) {
1523 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001524 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001525 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001526 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001527 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001528 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001529 !strcmp(argv[0],"get-serialno") ||
1530 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001531 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001532 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001533 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001534 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001535 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001536 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001537 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001538 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001539 return ppp(argc, argv);
1540 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001541 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001542 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001543 const int result = adb_connect("host:start-server", &error);
1544 if (result < 0) {
1545 fprintf(stderr, "error: %s\n", error.c_str());
1546 }
1547 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001548 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001549 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001550 return backup(argc, argv);
1551 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001552 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001553 return restore(argc, argv);
1554 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001555 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001556 if (argc < 2) return usage();
Yabin Cuiaed3c612015-09-22 15:52:57 -07001557 // Always print key generation information for keygen command.
1558 adb_trace_enable(AUTH);
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001559 return adb_auth_keygen(argv[1]);
1560 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001561 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001562 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001563 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001564 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001565 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001566 help();
1567 return 0;
1568 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001569 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001570 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001571 return 0;
1572 }
Dan Albert90d4b732015-05-20 18:58:41 -07001573 else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001574 // Only list the features common to both the adb client and the device.
1575 FeatureSet features = GetFeatureSet(transport_type, serial);
1576 for (const std::string& name : features) {
1577 if (supported_features().count(name) > 0) {
1578 printf("%s\n", name.c_str());
1579 }
1580 }
1581 return 0;
Dan Albert90d4b732015-05-20 18:58:41 -07001582 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001583
1584 usage();
1585 return 1;
1586}
1587
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001588static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001589 std::string cmd = "shell:pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001590
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001591 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001592 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001593 }
1594
Elliott Hughes15551472015-04-21 17:58:55 -07001595 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001596}
1597
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001598static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001599 /* if the user choose the -k option, we refuse to do it until devices are
1600 out with the option to uninstall the remaining data somehow (adb/ui) */
1601 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1602 {
1603 printf(
1604 "The -k option uninstalls the application while retaining the data/cache.\n"
1605 "At the moment, there is no way to remove the remaining data.\n"
1606 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1607 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1608 return -1;
1609 }
1610
1611 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1612 return pm_command(transport, serial, argc, argv);
1613}
1614
Elliott Hughes5c742702015-07-30 17:42:01 -07001615static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001616 std::string cmd = "shell:rm -f " + escape_arg(filename);
Elliott Hughes15551472015-04-21 17:58:55 -07001617 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001618}
1619
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001620static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001621 static const char *const DATA_DEST = "/data/local/tmp/%s";
1622 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001623 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001624 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001625 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001626
1627 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001628 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001629 where = SD_DEST;
1630 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001631 }
1632
Jeff Sharkey960df972014-06-09 17:30:57 -07001633 // Find last APK argument.
1634 // All other arguments passed through verbatim.
1635 int last_apk = -1;
1636 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001637 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001638 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001639 if (dot && !strcasecmp(dot, ".apk")) {
1640 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1641 fprintf(stderr, "Invalid APK file: %s\n", file);
1642 return -1;
1643 }
1644
1645 last_apk = i;
1646 break;
1647 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001648 }
1649
Jeff Sharkey960df972014-06-09 17:30:57 -07001650 if (last_apk == -1) {
1651 fprintf(stderr, "Missing APK file\n");
1652 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001653 }
1654
Elliott Hughesaa245492015-08-03 10:38:08 -07001655 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001656 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001657 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001658 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1659 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1660 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001661
Kenny Root60733e92012-03-26 16:14:02 -07001662cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001663 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001664 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001665}
1666
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001667static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001668 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001669{
Jeff Sharkey960df972014-06-09 17:30:57 -07001670 int i;
1671 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001672 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001673
1674 // Find all APK arguments starting at end.
1675 // All other arguments passed through verbatim.
1676 int first_apk = -1;
1677 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001678 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001679 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001680 if (dot && !strcasecmp(dot, ".apk")) {
1681 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1682 fprintf(stderr, "Invalid APK file: %s\n", file);
1683 return -1;
1684 }
1685
1686 total_size += sb.st_size;
1687 first_apk = i;
1688 } else {
1689 break;
1690 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001691 }
1692
Jeff Sharkey960df972014-06-09 17:30:57 -07001693 if (first_apk == -1) {
1694 fprintf(stderr, "Missing APK file\n");
1695 return 1;
1696 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001697
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001698 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001699 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001700 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001701 }
1702
1703 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001704 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001705 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001706 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001707 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001708 return -1;
1709 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001710 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001711 read_status_line(fd, buf, sizeof(buf));
1712 adb_close(fd);
1713
1714 int session_id = -1;
1715 if (!strncmp("Success", buf, 7)) {
1716 char* start = strrchr(buf, '[');
1717 char* end = strrchr(buf, ']');
1718 if (start && end) {
1719 *end = '\0';
1720 session_id = strtol(start + 1, NULL, 10);
1721 }
1722 }
1723 if (session_id < 0) {
1724 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001725 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001726 return -1;
1727 }
1728
1729 // Valid session, now stream the APKs
1730 int success = 1;
1731 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001732 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001733 if (stat(file, &sb) == -1) {
1734 fprintf(stderr, "Failed to stat %s\n", file);
1735 success = 0;
1736 goto finalize_session;
1737 }
1738
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001739 std::string cmd = android::base::StringPrintf(
1740 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001741 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001742
1743 int localFd = adb_open(file, O_RDONLY);
1744 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001745 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001746 success = 0;
1747 goto finalize_session;
1748 }
1749
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001750 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001751 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001752 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001753 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001754 adb_close(localFd);
1755 success = 0;
1756 goto finalize_session;
1757 }
1758
1759 copy_to_file(localFd, remoteFd);
1760 read_status_line(remoteFd, buf, sizeof(buf));
1761
1762 adb_close(localFd);
1763 adb_close(remoteFd);
1764
1765 if (strncmp("Success", buf, 7)) {
1766 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001767 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001768 success = 0;
1769 goto finalize_session;
1770 }
1771 }
1772
1773finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001774 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001775 std::string service =
1776 android::base::StringPrintf("exec:pm install-%s %d",
1777 success ? "commit" : "abandon", session_id);
1778 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001779 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001780 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001781 return -1;
1782 }
1783 read_status_line(fd, buf, sizeof(buf));
1784 adb_close(fd);
1785
1786 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001787 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001788 return 0;
1789 } else {
1790 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001791 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001792 return -1;
1793 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001794}