blob: c508b3285b154284db40114217fb3abe798a8df9 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Albert33134262015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20
Dan Albert76649012015-02-24 15:51:19 -080021#include <assert.h>
22#include <ctype.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <errno.h>
Elliott Hughes2940ccf2015-04-17 14:07:52 -070024#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <limits.h>
26#include <stdarg.h>
Dan Albert76649012015-02-24 15:51:19 -080027#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031#include <sys/stat.h>
Dan Albert76649012015-02-24 15:51:19 -080032#include <sys/types.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
David Pursell606835a2015-09-08 17:17:02 -070034#include <memory>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070035#include <string>
36
David Pursell606835a2015-09-08 17:17:02 -070037#include <base/logging.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070038#include <base/stringprintf.h>
39
Yabin Cuid325e862014-11-17 14:48:25 -080040#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080042#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043#endif
44
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080045#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080046#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080047#include "adb_client.h"
48#include "adb_io.h"
Elliott Hughes58305772015-04-17 13:57:15 -070049#include "adb_utils.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050#include "file_sync_service.h"
David Pursell606835a2015-09-08 17:17:02 -070051#include "shell_service.h"
52#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053
Elliott Hughes3bd73c12015-05-05 13:10:43 -070054static int install_app(TransportType t, const char* serial, int argc, const char** argv);
55static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
56static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080057
Elliott Hughes58305772015-04-17 13:57:15 -070058static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080059extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060
Elliott Hughes58305772015-04-17 13:57:15 -070061static std::string product_file(const char *extra) {
62 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063 fprintf(stderr, "adb: Product directory not specified; "
64 "use -p or define ANDROID_PRODUCT_OUT\n");
65 exit(1);
66 }
67
Elliott Hughes58305772015-04-17 13:57:15 -070068 return android::base::StringPrintf("%s%s%s",
69 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080070}
71
Elliott Hughes58305772015-04-17 13:57:15 -070072static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070073 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080074 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080075 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080076 " -d - directs command to the only connected USB device\n"
77 " returns an error if more than one USB device is present.\n"
78 " -e - directs command to the only running emulator.\n"
79 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070080 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070081 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070082 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080083 " -p <product name or path> - simple product name like 'sooner', or\n"
84 " a relative/absolute path to a product\n"
85 " out directory like 'out/target/product/sooner'.\n"
86 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
87 " environment variable is used, which must\n"
88 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080089 " -H - Name of adb server host (default: localhost)\n"
90 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070091 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070092 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040093 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
94 " Port 5555 is used by default if no port number is specified.\n"
95 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
96 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +020097 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040098 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080099 "\n"
100 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700101 " adb push [-p] <local> <remote>\n"
102 " - copy file/dir to device\n"
103 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700104 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700105 " - copy file/dir from device\n"
106 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700107 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800108 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600109 " (-l means list but don't copy)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800110 " adb shell - run remote shell interactively\n"
111 " adb shell <command> - run remote shell command\n"
112 " adb emu <command> - run emulator console command\n"
113 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100114 " adb forward --list - list all forward socket connections.\n"
115 " the format is a list of lines with the following format:\n"
116 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800117 " adb forward <local> <remote> - forward socket connections\n"
118 " forward specs are one of: \n"
119 " tcp:<port>\n"
120 " localabstract:<unix domain socket name>\n"
121 " localreserved:<unix domain socket name>\n"
122 " localfilesystem:<unix domain socket name>\n"
123 " dev:<character device name>\n"
124 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100125 " adb forward --no-rebind <local> <remote>\n"
126 " - same as 'adb forward <local> <remote>' but fails\n"
127 " if <local> is already forwarded\n"
128 " adb forward --remove <local> - remove a specific forward socket connection\n"
129 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100130 " adb reverse --list - list all reverse socket connections from device\n"
131 " adb reverse <remote> <local> - reverse socket connections\n"
132 " reverse specs are one of:\n"
133 " tcp:<port>\n"
134 " localabstract:<unix domain socket name>\n"
135 " localreserved:<unix domain socket name>\n"
136 " localfilesystem:<unix domain socket name>\n"
137 " adb reverse --norebind <remote> <local>\n"
138 " - same as 'adb reverse <remote> <local>' but fails\n"
139 " if <remote> is already reversed.\n"
140 " adb reverse --remove <remote>\n"
141 " - remove a specific reversed socket connection\n"
142 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700144 " adb install [-lrtsd] <file>\n"
145 " adb install-multiple [-lrtsdp] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700146 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700147 " (-l: forward lock application)\n"
148 " (-r: replace existing application)\n"
149 " (-t: allow test packages)\n"
150 " (-s: install application on sdcard)\n"
151 " (-d: allow version code downgrade)\n"
152 " (-p: partial application install)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800153 " adb uninstall [-k] <package> - remove this app package from the device\n"
154 " ('-k' means keep the data and cache directories)\n"
155 " adb bugreport - return all information from the device\n"
156 " that should be included in a bug report.\n"
157 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800158 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700159 " - write an archive of the device's data to <file>.\n"
160 " If no -f option is supplied then the data is written\n"
161 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700162 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700163 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800164 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
165 " (aka .obb) files associated with each application; the default\n"
166 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700167 " (-shared|-noshared enable/disable backup of the device's\n"
168 " shared storage / SD card contents; the default is noshared.)\n"
169 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700170 " (-system|-nosystem toggles whether -all automatically includes\n"
171 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700172 " (<packages...> is the list of applications to be backed up. If\n"
173 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700174 " list is optional. Applications explicitly given on the\n"
175 " command line will be included even if -nosystem would\n"
176 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700177 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700178 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700179 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800180 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
181 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800182 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
183 " and the public key is stored in <file>.pub. Any existing files\n"
184 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800185 " adb help - show this help message\n"
186 " adb version - show version num\n"
187 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800188 "scripting:\n"
189 " adb wait-for-device - block until device is online\n"
190 " adb start-server - ensure that there is a server running\n"
191 " adb kill-server - kill the server if it is running\n"
192 " adb get-state - prints: offline | bootloader | device\n"
193 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700194 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000195 " adb remount - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
Tao Bao175b7bb2015-03-29 11:22:34 -0700196 " adb reboot [bootloader|recovery]\n"
197 " - reboots the device, optionally into the bootloader or recovery program.\n"
198 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
199 " adb reboot sideload-auto-reboot\n"
200 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700201 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700202 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500203 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800204 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000205 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700206 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800207 "networking:\n"
208 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500209 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800210 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
211 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
212 "\n"
213 "adb sync notes: adb sync [ <directory> ]\n"
214 " <localdir> can be interpreted in several ways:\n"
215 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000216 " - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800217 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000218 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800219 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000220 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700221 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000222 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
223 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
224 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
225 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800226 );
227}
228
Elliott Hughes58305772015-04-17 13:57:15 -0700229static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800230 help();
231 return 1;
232}
233
Yabin Cuid325e862014-11-17 14:48:25 -0800234#if defined(_WIN32)
235
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700236// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800237void stdin_raw_init(int fd);
238void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800239
240#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100241static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800242
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100243static void stdin_raw_init(int fd) {
244 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800245
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100246 termios tio;
247 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800248
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100249 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800250
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100251 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800252 tio.c_cc[VTIME] = 0;
253 tio.c_cc[VMIN] = 1;
254
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100255 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256}
257
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100258static void stdin_raw_restore(int fd) {
259 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260}
261#endif
262
David Pursell606835a2015-09-08 17:17:02 -0700263// Reads from |fd| and prints received data. If |use_shell_protocol| is true
264// this expects that incoming data will use the shell protocol, in which case
265// stdout/stderr are routed independently and the remote exit code will be
266// returned.
267static int read_and_dump(int fd, bool use_shell_protocol=false) {
268 int exit_code = 0;
269 std::unique_ptr<ShellProtocol> protocol;
270 int length = 0;
271 FILE* outfile = stdout;
272
273 char raw_buffer[BUFSIZ];
274 char* buffer_ptr = raw_buffer;
275 if (use_shell_protocol) {
276 protocol.reset(new ShellProtocol(fd));
277 if (!protocol) {
278 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
279 return 1;
280 }
281 buffer_ptr = protocol->data();
282 }
283
Elliott Hughes5677c232015-05-07 23:37:40 -0700284 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700285 if (use_shell_protocol) {
286 if (!protocol->Read()) {
287 break;
288 }
289 switch (protocol->id()) {
290 case ShellProtocol::kIdStdout:
291 outfile = stdout;
292 break;
293 case ShellProtocol::kIdStderr:
294 outfile = stderr;
295 break;
296 case ShellProtocol::kIdExit:
297 exit_code = protocol->data()[0];
298 continue;
299 default:
300 continue;
301 }
302 length = protocol->data_length();
303 } else {
304 D("read_and_dump(): pre adb_read(fd=%d)", fd);
305 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
306 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
307 if (length <= 0) {
308 break;
309 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800310 }
311
David Pursell606835a2015-09-08 17:17:02 -0700312 fwrite(buffer_ptr, 1, length, outfile);
313 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800314 }
David Pursell606835a2015-09-08 17:17:02 -0700315
316 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800317}
318
Jeff Sharkey960df972014-06-09 17:30:57 -0700319static void read_status_line(int fd, char* buf, size_t count)
320{
321 count--;
322 while (count > 0) {
323 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700324 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700325 break;
326 }
327
328 buf += len;
329 count -= len;
330 }
331 *buf = '\0';
332}
333
Christopher Tated2f54152011-04-21 12:53:28 -0700334static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700335 const size_t BUFSIZE = 32 * 1024;
336 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700337 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700338 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700339 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700340#ifdef _WIN32
341 int old_stdin_mode = -1;
342 int old_stdout_mode = -1;
343#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700344
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700345 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800346
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700347 if (inFd == STDIN_FILENO) {
348 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700349#ifdef _WIN32
350 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
351 if (old_stdin_mode == -1) {
352 fatal_errno("could not set stdin to binary");
353 }
354#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700355 }
Yabin Cuid325e862014-11-17 14:48:25 -0800356
Spencer Lowb7dfb792015-05-22 16:48:31 -0700357#ifdef _WIN32
358 if (outFd == STDOUT_FILENO) {
359 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
360 if (old_stdout_mode == -1) {
361 fatal_errno("could not set stdout to binary");
362 }
363 }
364#endif
365
Elliott Hughesa7090b92015-04-17 17:03:59 -0700366 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700367 if (inFd == STDIN_FILENO) {
368 len = unix_read(inFd, buf, BUFSIZE);
369 } else {
370 len = adb_read(inFd, buf, BUFSIZE);
371 }
Christopher Tated2f54152011-04-21 12:53:28 -0700372 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700373 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700374 break;
375 }
376 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700377 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700378 break;
379 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700380 if (outFd == STDOUT_FILENO) {
381 fwrite(buf, 1, len, stdout);
382 fflush(stdout);
383 } else {
384 adb_write(outFd, buf, len);
385 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700386 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700387 }
Yabin Cuid325e862014-11-17 14:48:25 -0800388
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700389 if (inFd == STDIN_FILENO) {
390 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700391#ifdef _WIN32
392 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
393 fatal_errno("could not restore stdin mode");
394 }
395#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700396 }
Yabin Cuid325e862014-11-17 14:48:25 -0800397
Spencer Lowb7dfb792015-05-22 16:48:31 -0700398#ifdef _WIN32
399 if (outFd == STDOUT_FILENO) {
400 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
401 fatal_errno("could not restore stdout mode");
402 }
403 }
404#endif
405
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700406 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700407 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700408}
409
David Pursell606835a2015-09-08 17:17:02 -0700410namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800411
David Pursell606835a2015-09-08 17:17:02 -0700412// Used to pass multiple values to the stdin read thread.
413struct StdinReadArgs {
414 int stdin_fd, write_fd;
415 std::unique_ptr<ShellProtocol> protocol;
416};
417
418} // namespace
419
420// Loops to read from stdin and push the data to the given FD.
421// The argument should be a pointer to a StdinReadArgs object. This function
422// will take ownership of the object and delete it when finished.
423static void* stdin_read_thread(void* x) {
424 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
425 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800426
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700427 adb_thread_setname("stdin reader");
428
David Pursell606835a2015-09-08 17:17:02 -0700429 char raw_buffer[1024];
430 char* buffer_ptr = raw_buffer;
431 size_t buffer_size = sizeof(raw_buffer);
432 if (args->protocol) {
433 buffer_ptr = args->protocol->data();
434 buffer_size = args->protocol->data_capacity();
435 }
436
Elliott Hughesaa245492015-08-03 10:38:08 -0700437 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700438 // Use unix_read() rather than adb_read() for stdin.
439 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
440 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
441 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700442 if (r <= 0) break;
David Pursell606835a2015-09-08 17:17:02 -0700443 for (int n = 0; n < r; n++){
444 switch(buffer_ptr[n]) {
Mike Lockwood67d53582010-05-25 13:40:15 -0400445 case '\n':
446 state = 1;
447 break;
448 case '\r':
449 state = 1;
450 break;
451 case '~':
452 if(state == 1) state++;
453 break;
454 case '.':
455 if(state == 2) {
456 fprintf(stderr,"\n* disconnect *\n");
David Pursell606835a2015-09-08 17:17:02 -0700457 stdin_raw_restore(args->stdin_fd);
Mike Lockwood67d53582010-05-25 13:40:15 -0400458 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800459 }
Mike Lockwood67d53582010-05-25 13:40:15 -0400460 default:
461 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800462 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800463 }
David Pursell606835a2015-09-08 17:17:02 -0700464 if (args->protocol) {
465 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
466 break;
467 }
468 } else {
469 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
470 break;
471 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800472 }
473 }
David Pursell606835a2015-09-08 17:17:02 -0700474
475 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800476}
477
David Pursell606835a2015-09-08 17:17:02 -0700478static int interactive_shell(bool use_shell_protocol) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700479 std::string error;
480 int fd = adb_connect("shell:", &error);
481 if (fd < 0) {
482 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800483 return 1;
484 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800485
David Pursell606835a2015-09-08 17:17:02 -0700486 StdinReadArgs* args = new StdinReadArgs;
487 if (!args) {
488 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700489 return 1;
490 }
David Pursell606835a2015-09-08 17:17:02 -0700491 args->stdin_fd = 0;
492 args->write_fd = fd;
493 if (use_shell_protocol) {
494 args->protocol.reset(new ShellProtocol(args->write_fd));
495 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700496
David Pursell606835a2015-09-08 17:17:02 -0700497 stdin_raw_init(args->stdin_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800498
David Pursell606835a2015-09-08 17:17:02 -0700499 int exit_code = 0;
500 if (!adb_thread_create(stdin_read_thread, args)) {
501 PLOG(ERROR) << "error starting stdin read thread";
502 exit_code = 1;
503 delete args;
504 } else {
505 exit_code = read_and_dump(fd, use_shell_protocol);
506 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700507
David Pursell606835a2015-09-08 17:17:02 -0700508 stdin_raw_restore(args->stdin_fd);
509 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800510}
511
512
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700513static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800514 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700515 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800516 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700517
518 const char* prefix = "host";
519 if (type == kTransportUsb) {
520 prefix = "host-usb";
521 } else if (type == kTransportLocal) {
522 prefix = "host-local";
523 }
524 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800525}
526
Elliott Hughes6452a892015-04-29 12:28:13 -0700527static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700528 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800529{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700530 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700531 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700532 if (fd < 0) {
533 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800534 return -1;
535 }
536
537 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800538 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800539
Elliott Hughes6452a892015-04-29 12:28:13 -0700540 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800541 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800542
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700543 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700544 const char* x = strrchr(service, ':');
545 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800546 }
547
Elliott Hughes6452a892015-04-29 12:28:13 -0700548 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800549 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700550 if (!WriteFdExactly(fd, ptr, xfer)) {
551 std::string error;
552 adb_status(fd, &error);
553 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800554 return -1;
555 }
556 sz -= xfer;
557 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700558 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100559 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800560 fflush(stdout);
561 }
562 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700563 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800564 printf("\n");
565 }
566
Elliott Hughese67f1f82015-04-30 17:32:03 -0700567 if (!adb_status(fd, &error)) {
568 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800569 return -1;
570 }
571
572 adb_close(fd);
573 return 0;
574}
575
Doug Zongker71fe5842014-06-26 15:35:36 -0700576#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
577
578/*
579 * The sideload-host protocol serves the data in a file (given on the
580 * command line) to the client, using a simple protocol:
581 *
582 * - The connect message includes the total number of bytes in the
583 * file and a block size chosen by us.
584 *
585 * - The other side sends the desired block number as eight decimal
586 * digits (eg "00000023" for block 23). Blocks are numbered from
587 * zero.
588 *
589 * - We send back the data of the requested block. The last block is
590 * likely to be partial; when the last block is requested we only
591 * send the part of the block that exists, it's not padded up to the
592 * block size.
593 *
594 * - When the other side sends "DONEDONE" instead of a block number,
595 * we hang up.
596 */
Elliott Hughes58305772015-04-17 13:57:15 -0700597static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700598 unsigned sz;
599 size_t xfer = 0;
600 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800601 int last_percent = -1;
602 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700603
604 printf("loading: '%s'", fn);
605 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800606 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700607 if (data == 0) {
608 printf("\n");
609 fprintf(stderr, "* cannot read '%s' *\n", fn);
610 return -1;
611 }
612
Elliott Hughes6452a892015-04-29 12:28:13 -0700613 std::string service =
614 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700615 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700616 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700617 if (fd < 0) {
618 // Try falling back to the older sideload method. Maybe this
619 // is an older device that doesn't support sideload-host.
620 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700621 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700622 goto done;
623 }
624
Spencer Lowf055c192015-01-25 14:40:16 -0800625 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700626
Elliott Hughesa7090b92015-04-17 17:03:59 -0700627 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700628 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800629 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700630 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700631 status = -1;
632 goto done;
633 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700634 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700635
Elliott Hughes6452a892015-04-29 12:28:13 -0700636 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700637 status = 0;
638 break;
639 }
640
Doug Zongker71fe5842014-06-26 15:35:36 -0700641 int block = strtol(buf, NULL, 10);
642
643 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
644 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700645 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700646 status = -1;
647 goto done;
648 }
649 uint8_t* start = data + offset;
650 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
651 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
652 if (offset_end > sz) {
653 to_write = sz - offset;
654 }
655
Dan Albertcc731cc2015-02-24 21:26:58 -0800656 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700657 adb_status(fd, &error);
658 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700659 status = -1;
660 goto done;
661 }
662 xfer += to_write;
663
664 // For normal OTA packages, we expect to transfer every byte
665 // twice, plus a bit of overhead (one read during
666 // verification, one read of each byte for installation, plus
667 // extra access to things like the zip central directory).
668 // This estimate of the completion becomes 100% when we've
669 // transferred ~2.13 (=100/47) times the package size.
670 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
671 if (percent != last_percent) {
672 printf("\rserving: '%s' (~%d%%) ", fn, percent);
673 fflush(stdout);
674 last_percent = percent;
675 }
676 }
677
Colin Cross6d6a8982014-07-07 14:12:41 -0700678 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700679
680 done:
681 if (fd >= 0) adb_close(fd);
682 free(data);
683 return status;
684}
685
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800686/**
687 * Run ppp in "notty" mode against a resource listed as the first parameter
688 * eg:
689 *
690 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
691 *
692 */
Elliott Hughes58305772015-04-17 13:57:15 -0700693static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800694#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800695 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
696 return -1;
697#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800698 if (argc < 2) {
699 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
700 argv[0]);
701
702 return 1;
703 }
704
Dan Albertbac34742015-02-25 17:51:28 -0800705 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700706 std::string error;
707 int fd = adb_connect(adb_service_name, &error);
708 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800709 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700710 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800711 return 1;
712 }
713
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700714 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800715
716 if (pid < 0) {
717 perror("from fork()");
718 return 1;
719 } else if (pid == 0) {
720 int err;
721 int i;
722 const char **ppp_args;
723
724 // copy args
725 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
726 ppp_args[0] = "pppd";
727 for (i = 2 ; i < argc ; i++) {
728 //argv[2] and beyond become ppp_args[1] and beyond
729 ppp_args[i - 1] = argv[i];
730 }
731 ppp_args[i-1] = NULL;
732
733 // child side
734
735 dup2(fd, STDIN_FILENO);
736 dup2(fd, STDOUT_FILENO);
737 adb_close(STDERR_FILENO);
738 adb_close(fd);
739
740 err = execvp("pppd", (char * const *)ppp_args);
741
742 if (err < 0) {
743 perror("execing pppd");
744 }
745 exit(-1);
746 } else {
747 // parent side
748
749 adb_close(fd);
750 return 0;
751 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800752#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800753}
754
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700755static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700756 // Was the caller vague about what they'd like us to wait for?
757 // If so, check they weren't more specific in their choice of transport type.
758 if (strcmp(service, "wait-for-device") == 0) {
759 if (t == kTransportUsb) {
760 service = "wait-for-usb";
761 } else if (t == kTransportLocal) {
762 service = "wait-for-local";
763 } else {
764 service = "wait-for-any";
765 }
766 }
767
768 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700769 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700770}
771
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700772static int send_shell_command(TransportType transport_type, const char* serial,
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700773 const std::string& command) {
774 int fd;
775 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700776 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700777 fd = adb_connect(command, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700778 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800779 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700780 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800781 fprintf(stderr,"- waiting for device -\n");
782 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700783 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800784 }
785
786 read_and_dump(fd);
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700787 int rc = adb_close(fd);
788 if (rc) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800789 perror("close");
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700790 }
791 return rc;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800792}
793
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700794static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700795 char* log_tags = getenv("ANDROID_LOG_TAGS");
796 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800797
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700798 std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800799
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700800 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700801 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800802 }
803
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700804 --argc;
805 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700806 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700807 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800808 }
809
Elliott Hughes15551472015-04-21 17:58:55 -0700810 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800811}
812
Dan Albertbac34742015-02-25 17:51:28 -0800813static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700814 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700815
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700816 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700817 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700818 if (!strcmp("-f", argv[i])) {
819 if (i == argc-1) {
820 fprintf(stderr, "adb: -f passed with no filename\n");
821 return usage();
822 }
823 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700824 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700825 argv[i++] = argv[j++];
826 }
827 argc -= 2;
828 argv[argc] = NULL;
829 }
Christopher Tated2f54152011-04-21 12:53:28 -0700830 }
831
Christopher Tatebb86bc52011-08-22 17:12:08 -0700832 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
833 if (argc < 2) return usage();
834
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800835 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700836 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700837 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700838 if (outFd < 0) {
839 fprintf(stderr, "adb: unable to open file %s\n", filename);
840 return -1;
841 }
842
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700843 std::string cmd = "backup:";
844 --argc;
845 ++argv;
846 while (argc-- > 0) {
847 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700848 }
849
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700850 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700851 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700852 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700853 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700854 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700855 adb_close(outFd);
856 return -1;
857 }
858
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800859 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700860 copy_to_file(fd, outFd);
861
862 adb_close(fd);
863 adb_close(outFd);
864 return 0;
865}
866
Dan Albertbac34742015-02-25 17:51:28 -0800867static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700868 if (argc != 2) return usage();
869
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700870 const char* filename = argv[1];
871 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700872 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700873 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700874 return -1;
875 }
876
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700877 std::string error;
878 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700879 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700880 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700881 adb_close(tarFd);
882 return -1;
883 }
884
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800885 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700886 copy_to_file(tarFd, fd);
887
888 adb_close(fd);
889 adb_close(tarFd);
890 return 0;
891}
892
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800893/* <hint> may be:
894 * - A simple product name
895 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800896 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
897 * e.g., "out/target/product/sooner"
898 * - An absolute path to the PRODUCT_OUT dir
899 * e.g., "/src/device/out/target/product/sooner"
900 *
901 * Given <hint>, try to construct an absolute path to the
902 * ANDROID_PRODUCT_OUT dir.
903 */
Elliott Hughes5c742702015-07-30 17:42:01 -0700904static std::string find_product_out_path(const std::string& hint) {
905 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -0700906 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800907 }
908
Elliott Hughes58305772015-04-17 13:57:15 -0700909 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -0700910 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -0700911 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800912 }
913
Elliott Hughes58305772015-04-17 13:57:15 -0700914 // If there are any slashes in it, assume it's a relative path;
915 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -0700916 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700917 std::string cwd;
918 if (!getcwd(&cwd)) {
919 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -0700920 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800921 }
Elliott Hughes5c742702015-07-30 17:42:01 -0700922 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 -0800923 }
924
Elliott Hughes58305772015-04-17 13:57:15 -0700925 // It's a string without any slashes. Try to do something with it.
926 //
927 // Try to find the root of the build tree, and build a PRODUCT_OUT
928 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -0700929 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -0700930 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700931 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -0700932 return "";
933 }
Elliott Hughesa7090b92015-04-17 17:03:59 -0700934
935 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -0700936 path += OS_PATH_SEPARATOR_STR;
937 path += "out";
938 path += OS_PATH_SEPARATOR_STR;
939 path += "target";
940 path += OS_PATH_SEPARATOR_STR;
941 path += "product";
942 path += OS_PATH_SEPARATOR_STR;
943 path += hint;
944 if (!directory_exists(path)) {
945 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -0700946 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -0700947 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800948 }
Elliott Hughes58305772015-04-17 13:57:15 -0700949 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800950}
951
Dan Albertbac34742015-02-25 17:51:28 -0800952static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -0700953 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -0800954 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700955 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700956 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -0700957
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700958 while (narg > 0) {
959 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -0700960 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700961 } else if (!strcmp(*arg, "-a")) {
962 *copy_attrs = 1;
963 } else {
964 break;
965 }
Mark Lindner76f2a932014-03-11 17:55:59 -0700966 ++arg;
967 --narg;
968 }
969
970 if (narg > 0) {
971 *path1 = *arg;
972 ++arg;
973 --narg;
974 }
975
976 if (narg > 0) {
977 *path2 = *arg;
978 }
979}
980
Elliott Hughes6452a892015-04-29 12:28:13 -0700981static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700982 std::string error;
983 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -0700984 if (fd < 0) {
985 fprintf(stderr, "error: %s\n", error.c_str());
986 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -0700987 }
Elliott Hughes5677c232015-05-07 23:37:40 -0700988 read_and_dump(fd);
989 adb_close(fd);
990 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -0700991}
992
Elliott Hughes6452a892015-04-29 12:28:13 -0700993static int adb_query_command(const std::string& command) {
994 std::string result;
995 std::string error;
996 if (!adb_query(command, &result, &error)) {
997 fprintf(stderr, "error: %s\n", error.c_str());
998 return 1;
999 }
1000 printf("%s\n", result.c_str());
1001 return 0;
1002}
1003
Spencer Lowa13df302015-09-07 16:20:13 -07001004// Disallow stdin, stdout, and stderr.
1005static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1006#ifdef _WIN32
1007 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1008 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1009 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1010 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1011#else
1012 return ack_reply_fd > 2;
1013#endif
1014}
1015
David Pursell606835a2015-09-08 17:17:02 -07001016// Checks whether the device indicated by |transport_type| and |serial| supports
1017// |feature|. Returns the response string, which will be empty if the device
1018// could not be found or the feature is not supported.
1019static std::string CheckFeature(const std::string& feature,
1020 TransportType transport_type,
1021 const char* serial) {
1022 std::string result, error, command("check-feature:" + feature);
1023 if (!adb_query(format_host_command(command.c_str(), transport_type, serial),
1024 &result, &error)) {
1025 return "";
1026 }
1027 return result;
1028}
1029
Elliott Hughesab52c182015-05-01 17:04:38 -07001030int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001031 int no_daemon = 0;
1032 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001033 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001034 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001035 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001036 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001037
Elliott Hughes58305772015-04-17 13:57:15 -07001038 // If defined, this should be an absolute path to
1039 // the directory containing all of the various system images
1040 // for a particular product. If not defined, and the adb
1041 // command requires this information, then the user must
1042 // specify the path using "-p".
1043 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1044 if (ANDROID_PRODUCT_OUT != nullptr) {
1045 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001046 }
1047 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1048
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001049 const char* serial = getenv("ANDROID_SERIAL");
Nick Pellydb449262009-05-07 12:48:03 -07001050
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001051 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001052 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001053 int server_port = DEFAULT_ADB_PORT;
1054 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001055 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001056 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001057 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001058 "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 +01001059 server_port_str);
1060 return usage();
1061 }
1062 }
1063
1064 /* modifiers and flags */
Riley Andrews98f58e82014-12-05 17:37:24 -08001065 while (argc > 0) {
1066 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001067 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001068 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001069 no_daemon = 1;
1070 } else if (!strcmp(argv[0], "fork-server")) {
1071 /* this is a special flag used only when the ADB client launches the ADB Server */
1072 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001073 } else if (!strcmp(argv[0], "--reply-fd")) {
1074 if (argc < 2) return usage();
1075 const char* reply_fd_str = argv[1];
1076 argc--;
1077 argv++;
1078 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001079 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001080 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1081 return usage();
1082 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001083 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001084 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001085 if (argv[0][2] == '\0') {
1086 if (argc < 2) return usage();
1087 product = argv[1];
1088 argc--;
1089 argv++;
1090 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001091 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001092 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001093 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001094 if (gProductOutPath.empty()) {
1095 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001096 return usage();
1097 }
1098 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1099 if (isdigit(argv[0][2])) {
1100 serial = argv[0] + 2;
1101 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001102 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001103 serial = argv[1];
1104 argc--;
1105 argv++;
1106 }
1107 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001108 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001109 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001110 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001111 } else if (!strcmp(argv[0],"-a")) {
1112 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001113 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001114 const char *hostname = NULL;
1115 if (argv[0][2] == '\0') {
1116 if (argc < 2) return usage();
1117 hostname = argv[1];
1118 argc--;
1119 argv++;
1120 } else {
1121 hostname = argv[0] + 2;
1122 }
1123 adb_set_tcp_name(hostname);
1124
Riley Andrews98f58e82014-12-05 17:37:24 -08001125 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001126 if (argv[0][2] == '\0') {
1127 if (argc < 2) return usage();
1128 server_port_str = argv[1];
1129 argc--;
1130 argv++;
1131 } else {
1132 server_port_str = argv[0] + 2;
1133 }
1134 if (strlen(server_port_str) > 0) {
1135 server_port = (int) strtol(server_port_str, NULL, 0);
1136 if (server_port <= 0 || server_port > 65535) {
1137 fprintf(stderr,
1138 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1139 server_port_str);
1140 return usage();
1141 }
1142 } else {
1143 fprintf(stderr,
1144 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1145 return usage();
1146 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001147 } else {
1148 /* out of recognized modifiers and flags */
1149 break;
1150 }
1151 argc--;
1152 argv++;
1153 }
1154
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001155 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001156 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001157
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001158 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001159 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001160 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001161 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1162 return usage();
1163 }
1164 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001165 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001166 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001167 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001168 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001169 fprintf(stderr,"* could not start server *\n");
1170 }
1171 return r;
1172 }
1173
Riley Andrews98f58e82014-12-05 17:37:24 -08001174 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001175 return usage();
1176 }
1177
Riley Andrewsc8514c82014-12-05 17:32:46 -08001178 /* handle wait-for-* prefix */
1179 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001180 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001181
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001182 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001183 return 1;
1184 }
1185
Elliott Hughes2b101112015-05-04 19:29:32 -07001186 // Allow a command to be run after wait-for-device,
1187 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001188 if (argc == 1) {
1189 return 0;
1190 }
1191
1192 /* Fall through */
1193 argc--;
1194 argv++;
1195 }
1196
1197 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001198 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001199 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001200 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001201 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001202 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001203 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001204 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001205 fprintf(stderr, "Usage: adb devices [-l]\n");
1206 return 1;
1207 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001208
1209 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1210 printf("List of devices attached\n");
1211 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001212 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001213 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001214 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001215 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001216 return 1;
1217 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001218
1219 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1220 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001221 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001222 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001223 if (argc > 2) {
1224 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1225 return 1;
1226 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001227
1228 std::string query = android::base::StringPrintf("host:disconnect:%s",
1229 (argc == 2) ? argv[1] : "");
1230 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001231 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001232 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001233 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001234 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001235 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001236 char h = (argv[0][0] == 'h');
1237
1238 if (h) {
1239 printf("\x1b[41;33m");
1240 fflush(stdout);
1241 }
1242
David Pursell606835a2015-09-08 17:17:02 -07001243 bool use_shell_protocol;
1244 if (CheckFeature(kFeatureShell2, transport_type, serial).empty()) {
1245 D("shell protocol not supported, using raw data transfer");
1246 use_shell_protocol = false;
1247 } else {
1248 D("using shell protocol");
1249 use_shell_protocol = true;
1250 }
1251
1252
Riley Andrews98f58e82014-12-05 17:37:24 -08001253 if (argc < 2) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001254 D("starting interactive shell");
David Pursell606835a2015-09-08 17:17:02 -07001255 r = interactive_shell(use_shell_protocol);
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001256 if (h) {
1257 printf("\x1b[0m");
1258 fflush(stdout);
1259 }
1260 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001261 }
1262
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001263 std::string cmd = "shell:";
Elliott Hughes2b101112015-05-04 19:29:32 -07001264 --argc;
1265 ++argv;
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001266 while (argc-- > 0) {
Elliott Hughes2b101112015-05-04 19:29:32 -07001267 // We don't escape here, just like ssh(1). http://b/20564385.
1268 cmd += *argv++;
1269 if (*argv) cmd += " ";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001270 }
1271
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001272 while (true) {
David Pursell606835a2015-09-08 17:17:02 -07001273 D("non-interactive shell loop. cmd=%s", cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001274 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001275 int fd = adb_connect(cmd, &error);
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001276 int r;
Riley Andrews98f58e82014-12-05 17:37:24 -08001277 if (fd >= 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001278 D("about to read_and_dump(fd=%d)", fd);
David Pursell606835a2015-09-08 17:17:02 -07001279 r = read_and_dump(fd, use_shell_protocol);
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001280 D("read_and_dump() done.");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001281 adb_close(fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001282 } else {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001283 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001284 r = -1;
1285 }
1286
Elliott Hughes32687be2015-05-05 12:50:26 -07001287 if (h) {
1288 printf("\x1b[0m");
1289 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001290 }
David Pursell606835a2015-09-08 17:17:02 -07001291 D("non-interactive shell loop. return r=%d", r);
Elliott Hughes32687be2015-05-05 12:50:26 -07001292 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001293 }
1294 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001295 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001296 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001297
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001298 std::string cmd = "exec:";
1299 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001300 argc -= 2;
1301 argv += 2;
1302 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001303 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001304 }
1305
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001306 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001307 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001308 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001309 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001310 return -1;
1311 }
1312
1313 if (exec_in) {
1314 copy_to_file(STDIN_FILENO, fd);
1315 } else {
1316 copy_to_file(fd, STDOUT_FILENO);
1317 }
1318
1319 adb_close(fd);
1320 return 0;
1321 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001322 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001323 std::string error;
1324 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001325 if (fd == -2) {
1326 // Failed to make network connection to server. Don't output the
1327 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001328 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001329 // Successful exit code because the server is already "killed".
1330 return 0;
1331 } else if (fd == -1) {
1332 // Some other error.
1333 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001334 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001335 } else {
1336 // Successfully connected, kill command sent, okay status came back.
1337 // Server should exit() in a moment, if not already.
1338 adb_close(fd);
1339 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001340 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001341 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001342 else if (!strcmp(argv[0], "sideload")) {
1343 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001344 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001345 return 1;
1346 } else {
1347 return 0;
1348 }
1349 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001350 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1351 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1352 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001353 else if (!strcmp(argv[0], "remount") ||
1354 !strcmp(argv[0], "reboot") ||
1355 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001356 !strcmp(argv[0], "usb") ||
1357 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001358 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001359 !strcmp(argv[0], "disable-verity") ||
1360 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001361 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001362 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001363 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001364 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001365 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001366 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001367 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001368 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001369 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001370 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001371 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001372 if (argc != 1) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001373 return send_shell_command(transport_type, serial, "shell:bugreport");
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001374 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001375 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001376 bool reverse = !strcmp(argv[0], "reverse");
1377 ++argv;
1378 --argc;
1379 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001380
1381 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001382 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001383 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001384 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001385 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001386 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001387 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001388 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001389 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001390 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001391 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001392 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001393 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001394 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001395 }
1396
Elliott Hughes424af022015-05-29 17:55:19 -07001397 std::string cmd;
1398 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001399 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001400 return adb_query_command(host_prefix + ":list-forward");
1401 } else if (strcmp(argv[0], "--remove-all") == 0) {
1402 if (argc != 1) return usage();
1403 cmd = host_prefix + ":killforward-all";
1404 } else if (strcmp(argv[0], "--remove") == 0) {
1405 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001406 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001407 cmd = host_prefix + ":killforward:" + argv[1];
1408 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1409 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001410 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001411 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1412 } else {
1413 // forward <local> <remote>
1414 if (argc != 2) return usage();
1415 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001416 }
1417
Elliott Hughes424af022015-05-29 17:55:19 -07001418 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001419 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001420 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001421 else if (!strcmp(argv[0], "ls")) {
1422 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001423 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001424 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001425 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001426 bool show_progress = false;
1427 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001428 const char* lpath = NULL, *rpath = NULL;
1429
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001430 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001431 if (!lpath || !rpath || copy_attrs != 0) return usage();
1432 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001433 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001434 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001435 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001436 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001437 const char* rpath = NULL, *lpath = ".";
1438
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001439 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001440 if (!rpath) return usage();
1441 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001442 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001443 else if (!strcmp(argv[0], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001444 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001445 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001446 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001447 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001448 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001449 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001450 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001451 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001452 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001453 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001454 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001455 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001456 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001457 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001458 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001459 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001460 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001461 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001462 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001463 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001464 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001465 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001466 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001467 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001468 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001469 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001470 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001471 } else {
1472 return usage();
1473 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001474
Elliott Hughesd236d072015-04-21 10:17:07 -07001475 if (src != "" &&
1476 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001477 return usage();
1478 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001479
Elliott Hughes58305772015-04-17 13:57:15 -07001480 std::string system_src_path = product_file("system");
1481 std::string data_src_path = product_file("data");
1482 std::string vendor_src_path = product_file("vendor");
1483 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001484
Elliott Hughesaa245492015-08-03 10:38:08 -07001485 bool okay = true;
1486 if (okay && (src.empty() || src == "system")) {
1487 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001488 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001489 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1490 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001491 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001492 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1493 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001494 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001495 if (okay && (src.empty() || src == "data")) {
1496 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001497 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001498 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001499 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001500 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001501 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001502 !strcmp(argv[0],"get-serialno") ||
1503 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001504 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001505 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001506 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001507 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001508 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001509 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001510 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001511 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001512 return ppp(argc, argv);
1513 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001514 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001515 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001516 const int result = adb_connect("host:start-server", &error);
1517 if (result < 0) {
1518 fprintf(stderr, "error: %s\n", error.c_str());
1519 }
1520 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001521 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001522 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001523 return backup(argc, argv);
1524 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001525 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001526 return restore(argc, argv);
1527 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001528 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001529 if (argc < 2) return usage();
1530 return adb_auth_keygen(argv[1]);
1531 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001532 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001533 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001534 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001535 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001536 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001537 help();
1538 return 0;
1539 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001540 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001541 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001542 return 0;
1543 }
Dan Albert90d4b732015-05-20 18:58:41 -07001544 else if (!strcmp(argv[0], "features")) {
David Pursell880be432015-09-04 16:40:30 -07001545 return adb_query_command(format_host_command("features", transport_type, serial));
Dan Albert90d4b732015-05-20 18:58:41 -07001546 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001547
1548 usage();
1549 return 1;
1550}
1551
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001552static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001553 std::string cmd = "shell:pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001554
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001555 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001556 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001557 }
1558
Elliott Hughes15551472015-04-21 17:58:55 -07001559 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001560}
1561
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001562static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001563 /* if the user choose the -k option, we refuse to do it until devices are
1564 out with the option to uninstall the remaining data somehow (adb/ui) */
1565 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1566 {
1567 printf(
1568 "The -k option uninstalls the application while retaining the data/cache.\n"
1569 "At the moment, there is no way to remove the remaining data.\n"
1570 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1571 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1572 return -1;
1573 }
1574
1575 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1576 return pm_command(transport, serial, argc, argv);
1577}
1578
Elliott Hughes5c742702015-07-30 17:42:01 -07001579static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001580 std::string cmd = "shell:rm -f " + escape_arg(filename);
Elliott Hughes15551472015-04-21 17:58:55 -07001581 return send_shell_command(transport, serial, cmd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001582}
1583
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001584static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001585 static const char *const DATA_DEST = "/data/local/tmp/%s";
1586 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001587 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001588 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001589 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001590
1591 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001592 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001593 where = SD_DEST;
1594 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001595 }
1596
Jeff Sharkey960df972014-06-09 17:30:57 -07001597 // Find last APK argument.
1598 // All other arguments passed through verbatim.
1599 int last_apk = -1;
1600 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001601 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001602 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001603 if (dot && !strcasecmp(dot, ".apk")) {
1604 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1605 fprintf(stderr, "Invalid APK file: %s\n", file);
1606 return -1;
1607 }
1608
1609 last_apk = i;
1610 break;
1611 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001612 }
1613
Jeff Sharkey960df972014-06-09 17:30:57 -07001614 if (last_apk == -1) {
1615 fprintf(stderr, "Missing APK file\n");
1616 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001617 }
1618
Elliott Hughesaa245492015-08-03 10:38:08 -07001619 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001620 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001621 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001622 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1623 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1624 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001625
Kenny Root60733e92012-03-26 16:14:02 -07001626cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001627 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001628 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001629}
1630
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001631static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001632 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001633{
Jeff Sharkey960df972014-06-09 17:30:57 -07001634 int i;
1635 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001636 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001637
1638 // Find all APK arguments starting at end.
1639 // All other arguments passed through verbatim.
1640 int first_apk = -1;
1641 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001642 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001643 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001644 if (dot && !strcasecmp(dot, ".apk")) {
1645 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1646 fprintf(stderr, "Invalid APK file: %s\n", file);
1647 return -1;
1648 }
1649
1650 total_size += sb.st_size;
1651 first_apk = i;
1652 } else {
1653 break;
1654 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001655 }
1656
Jeff Sharkey960df972014-06-09 17:30:57 -07001657 if (first_apk == -1) {
1658 fprintf(stderr, "Missing APK file\n");
1659 return 1;
1660 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001661
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001662 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001663 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001664 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001665 }
1666
1667 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001668 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001669 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001670 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001671 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001672 return -1;
1673 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001674 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001675 read_status_line(fd, buf, sizeof(buf));
1676 adb_close(fd);
1677
1678 int session_id = -1;
1679 if (!strncmp("Success", buf, 7)) {
1680 char* start = strrchr(buf, '[');
1681 char* end = strrchr(buf, ']');
1682 if (start && end) {
1683 *end = '\0';
1684 session_id = strtol(start + 1, NULL, 10);
1685 }
1686 }
1687 if (session_id < 0) {
1688 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001689 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001690 return -1;
1691 }
1692
1693 // Valid session, now stream the APKs
1694 int success = 1;
1695 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001696 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001697 if (stat(file, &sb) == -1) {
1698 fprintf(stderr, "Failed to stat %s\n", file);
1699 success = 0;
1700 goto finalize_session;
1701 }
1702
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001703 std::string cmd = android::base::StringPrintf(
1704 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001705 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001706
1707 int localFd = adb_open(file, O_RDONLY);
1708 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001709 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001710 success = 0;
1711 goto finalize_session;
1712 }
1713
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001714 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001715 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001716 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001717 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001718 adb_close(localFd);
1719 success = 0;
1720 goto finalize_session;
1721 }
1722
1723 copy_to_file(localFd, remoteFd);
1724 read_status_line(remoteFd, buf, sizeof(buf));
1725
1726 adb_close(localFd);
1727 adb_close(remoteFd);
1728
1729 if (strncmp("Success", buf, 7)) {
1730 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001731 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001732 success = 0;
1733 goto finalize_session;
1734 }
1735 }
1736
1737finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001738 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001739 std::string service =
1740 android::base::StringPrintf("exec:pm install-%s %d",
1741 success ? "commit" : "abandon", session_id);
1742 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001743 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001744 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001745 return -1;
1746 }
1747 read_status_line(fd, buf, sizeof(buf));
1748 adb_close(fd);
1749
1750 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001751 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001752 return 0;
1753 } else {
1754 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001755 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001756 return -1;
1757 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001758}