blob: d0ca67aea66e50b6fed27175a8ecda96c0aabc59 [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 Pursell70ef7b42015-09-30 13:35:42 -070052#include "services.h"
David Pursell606835a2015-09-08 17:17:02 -070053#include "shell_service.h"
54#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080055
Elliott Hughes3bd73c12015-05-05 13:10:43 -070056static int install_app(TransportType t, const char* serial, int argc, const char** argv);
57static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
58static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080059
Elliott Hughes58305772015-04-17 13:57:15 -070060static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080061extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080062
Elliott Hughes58305772015-04-17 13:57:15 -070063static std::string product_file(const char *extra) {
64 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080065 fprintf(stderr, "adb: Product directory not specified; "
66 "use -p or define ANDROID_PRODUCT_OUT\n");
67 exit(1);
68 }
69
Elliott Hughes58305772015-04-17 13:57:15 -070070 return android::base::StringPrintf("%s%s%s",
71 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080072}
73
Elliott Hughes58305772015-04-17 13:57:15 -070074static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070075 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080076 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080077 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 " -d - directs command to the only connected USB device\n"
79 " returns an error if more than one USB device is present.\n"
80 " -e - directs command to the only running emulator.\n"
81 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070082 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070083 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070084 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080085 " -p <product name or path> - simple product name like 'sooner', or\n"
86 " a relative/absolute path to a product\n"
87 " out directory like 'out/target/product/sooner'.\n"
88 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
89 " environment variable is used, which must\n"
90 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080091 " -H - Name of adb server host (default: localhost)\n"
92 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070093 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070094 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040095 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
96 " Port 5555 is used by default if no port number is specified.\n"
97 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
98 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +020099 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400100 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800101 "\n"
102 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700103 " adb push [-p] <local> <remote>\n"
104 " - copy file/dir to device\n"
105 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700106 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700107 " - copy file/dir from device\n"
108 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700109 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800110 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600111 " (-l means list but don't copy)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700112 " adb shell [-Ttx] - run remote shell interactively\n"
113 " adb shell [-Ttx] <command> - run remote shell command\n"
David Pursell4e2fd362015-09-22 10:43:08 -0700114 " (-T disables PTY allocation)\n"
115 " (-t forces PTY allocation)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700116 " (-x disables remote exit codes and stdout/stderr separation)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800117 " adb emu <command> - run emulator console command\n"
118 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100119 " adb forward --list - list all forward socket connections.\n"
120 " the format is a list of lines with the following format:\n"
121 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800122 " adb forward <local> <remote> - forward socket connections\n"
123 " forward specs are one of: \n"
124 " tcp:<port>\n"
125 " localabstract:<unix domain socket name>\n"
126 " localreserved:<unix domain socket name>\n"
127 " localfilesystem:<unix domain socket name>\n"
128 " dev:<character device name>\n"
129 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100130 " adb forward --no-rebind <local> <remote>\n"
131 " - same as 'adb forward <local> <remote>' but fails\n"
132 " if <local> is already forwarded\n"
133 " adb forward --remove <local> - remove a specific forward socket connection\n"
134 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100135 " adb reverse --list - list all reverse socket connections from device\n"
136 " adb reverse <remote> <local> - reverse socket connections\n"
137 " reverse specs are one of:\n"
138 " tcp:<port>\n"
139 " localabstract:<unix domain socket name>\n"
140 " localreserved:<unix domain socket name>\n"
141 " localfilesystem:<unix domain socket name>\n"
142 " adb reverse --norebind <remote> <local>\n"
143 " - same as 'adb reverse <remote> <local>' but fails\n"
144 " if <remote> is already reversed.\n"
145 " adb reverse --remove <remote>\n"
146 " - remove a specific reversed socket connection\n"
147 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800148 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700149 " adb install [-lrtsd] <file>\n"
150 " adb install-multiple [-lrtsdp] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700151 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700152 " (-l: forward lock application)\n"
153 " (-r: replace existing application)\n"
154 " (-t: allow test packages)\n"
155 " (-s: install application on sdcard)\n"
156 " (-d: allow version code downgrade)\n"
157 " (-p: partial application install)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800158 " adb uninstall [-k] <package> - remove this app package from the device\n"
159 " ('-k' means keep the data and cache directories)\n"
160 " adb bugreport - return all information from the device\n"
161 " that should be included in a bug report.\n"
162 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800163 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700164 " - write an archive of the device's data to <file>.\n"
165 " If no -f option is supplied then the data is written\n"
166 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700167 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700168 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800169 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
170 " (aka .obb) files associated with each application; the default\n"
171 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700172 " (-shared|-noshared enable/disable backup of the device's\n"
173 " shared storage / SD card contents; the default is noshared.)\n"
174 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700175 " (-system|-nosystem toggles whether -all automatically includes\n"
176 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700177 " (<packages...> is the list of applications to be backed up. If\n"
178 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700179 " list is optional. Applications explicitly given on the\n"
180 " command line will be included even if -nosystem would\n"
181 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700182 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700183 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700184 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800185 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
186 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800187 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
188 " and the public key is stored in <file>.pub. Any existing files\n"
189 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800190 " adb help - show this help message\n"
191 " adb version - show version num\n"
192 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800193 "scripting:\n"
194 " adb wait-for-device - block until device is online\n"
195 " adb start-server - ensure that there is a server running\n"
196 " adb kill-server - kill the server if it is running\n"
197 " adb get-state - prints: offline | bootloader | device\n"
198 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700199 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000200 " 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 -0700201 " adb reboot [bootloader|recovery]\n"
202 " - reboots the device, optionally into the bootloader or recovery program.\n"
203 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
204 " adb reboot sideload-auto-reboot\n"
205 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700206 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700207 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500208 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800209 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000210 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700211 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800212 "networking:\n"
213 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500214 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800215 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
216 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
217 "\n"
218 "adb sync notes: adb sync [ <directory> ]\n"
219 " <localdir> can be interpreted in several ways:\n"
220 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000221 " - 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 -0800222 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000223 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800224 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000225 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700226 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000227 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
228 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
229 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
230 " 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 -0800231 );
232}
233
Elliott Hughes58305772015-04-17 13:57:15 -0700234static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800235 help();
236 return 1;
237}
238
Yabin Cuid325e862014-11-17 14:48:25 -0800239#if defined(_WIN32)
240
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700241// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800242void stdin_raw_init(int fd);
243void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800244
245#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100246static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800247
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100248static void stdin_raw_init(int fd) {
249 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800250
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100251 termios tio;
252 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800253
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100254 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800255
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100256 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800257 tio.c_cc[VTIME] = 0;
258 tio.c_cc[VMIN] = 1;
259
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100260 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800261}
262
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100263static void stdin_raw_restore(int fd) {
264 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800265}
266#endif
267
David Pursell606835a2015-09-08 17:17:02 -0700268// Reads from |fd| and prints received data. If |use_shell_protocol| is true
269// this expects that incoming data will use the shell protocol, in which case
270// stdout/stderr are routed independently and the remote exit code will be
271// returned.
272static int read_and_dump(int fd, bool use_shell_protocol=false) {
273 int exit_code = 0;
274 std::unique_ptr<ShellProtocol> protocol;
275 int length = 0;
276 FILE* outfile = stdout;
277
278 char raw_buffer[BUFSIZ];
279 char* buffer_ptr = raw_buffer;
280 if (use_shell_protocol) {
281 protocol.reset(new ShellProtocol(fd));
282 if (!protocol) {
283 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
284 return 1;
285 }
286 buffer_ptr = protocol->data();
287 }
288
Elliott Hughes5677c232015-05-07 23:37:40 -0700289 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700290 if (use_shell_protocol) {
291 if (!protocol->Read()) {
292 break;
293 }
294 switch (protocol->id()) {
295 case ShellProtocol::kIdStdout:
296 outfile = stdout;
297 break;
298 case ShellProtocol::kIdStderr:
299 outfile = stderr;
300 break;
301 case ShellProtocol::kIdExit:
302 exit_code = protocol->data()[0];
303 continue;
304 default:
305 continue;
306 }
307 length = protocol->data_length();
308 } else {
309 D("read_and_dump(): pre adb_read(fd=%d)", fd);
310 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
311 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
312 if (length <= 0) {
313 break;
314 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800315 }
316
David Pursell606835a2015-09-08 17:17:02 -0700317 fwrite(buffer_ptr, 1, length, outfile);
318 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800319 }
David Pursell606835a2015-09-08 17:17:02 -0700320
321 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800322}
323
Jeff Sharkey960df972014-06-09 17:30:57 -0700324static void read_status_line(int fd, char* buf, size_t count)
325{
326 count--;
327 while (count > 0) {
328 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700329 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700330 break;
331 }
332
333 buf += len;
334 count -= len;
335 }
336 *buf = '\0';
337}
338
Christopher Tated2f54152011-04-21 12:53:28 -0700339static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700340 const size_t BUFSIZE = 32 * 1024;
341 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700342 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700343 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700344 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700345#ifdef _WIN32
346 int old_stdin_mode = -1;
347 int old_stdout_mode = -1;
348#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700349
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700350 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800351
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700352 if (inFd == STDIN_FILENO) {
353 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700354#ifdef _WIN32
355 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
356 if (old_stdin_mode == -1) {
357 fatal_errno("could not set stdin to binary");
358 }
359#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700360 }
Yabin Cuid325e862014-11-17 14:48:25 -0800361
Spencer Lowb7dfb792015-05-22 16:48:31 -0700362#ifdef _WIN32
363 if (outFd == STDOUT_FILENO) {
364 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
365 if (old_stdout_mode == -1) {
366 fatal_errno("could not set stdout to binary");
367 }
368 }
369#endif
370
Elliott Hughesa7090b92015-04-17 17:03:59 -0700371 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700372 if (inFd == STDIN_FILENO) {
373 len = unix_read(inFd, buf, BUFSIZE);
374 } else {
375 len = adb_read(inFd, buf, BUFSIZE);
376 }
Christopher Tated2f54152011-04-21 12:53:28 -0700377 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700378 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700379 break;
380 }
381 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700382 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700383 break;
384 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700385 if (outFd == STDOUT_FILENO) {
386 fwrite(buf, 1, len, stdout);
387 fflush(stdout);
388 } else {
389 adb_write(outFd, buf, len);
390 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700391 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700392 }
Yabin Cuid325e862014-11-17 14:48:25 -0800393
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700394 if (inFd == STDIN_FILENO) {
395 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700396#ifdef _WIN32
397 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
398 fatal_errno("could not restore stdin mode");
399 }
400#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700401 }
Yabin Cuid325e862014-11-17 14:48:25 -0800402
Spencer Lowb7dfb792015-05-22 16:48:31 -0700403#ifdef _WIN32
404 if (outFd == STDOUT_FILENO) {
405 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
406 fatal_errno("could not restore stdout mode");
407 }
408 }
409#endif
410
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700411 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700412 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700413}
414
David Pursell606835a2015-09-08 17:17:02 -0700415namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800416
David Pursell606835a2015-09-08 17:17:02 -0700417// Used to pass multiple values to the stdin read thread.
418struct StdinReadArgs {
419 int stdin_fd, write_fd;
420 std::unique_ptr<ShellProtocol> protocol;
421};
422
423} // namespace
424
425// Loops to read from stdin and push the data to the given FD.
426// The argument should be a pointer to a StdinReadArgs object. This function
427// will take ownership of the object and delete it when finished.
428static void* stdin_read_thread(void* x) {
429 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
430 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800431
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700432 adb_thread_setname("stdin reader");
433
David Pursell606835a2015-09-08 17:17:02 -0700434 char raw_buffer[1024];
435 char* buffer_ptr = raw_buffer;
436 size_t buffer_size = sizeof(raw_buffer);
437 if (args->protocol) {
438 buffer_ptr = args->protocol->data();
439 buffer_size = args->protocol->data_capacity();
440 }
441
Elliott Hughesaa245492015-08-03 10:38:08 -0700442 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700443 // Use unix_read() rather than adb_read() for stdin.
444 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
445 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
446 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700447 if (r <= 0) break;
David Pursell606835a2015-09-08 17:17:02 -0700448 for (int n = 0; n < r; n++){
449 switch(buffer_ptr[n]) {
Mike Lockwood67d53582010-05-25 13:40:15 -0400450 case '\n':
451 state = 1;
452 break;
453 case '\r':
454 state = 1;
455 break;
456 case '~':
457 if(state == 1) state++;
458 break;
459 case '.':
460 if(state == 2) {
461 fprintf(stderr,"\n* disconnect *\n");
David Pursell606835a2015-09-08 17:17:02 -0700462 stdin_raw_restore(args->stdin_fd);
Mike Lockwood67d53582010-05-25 13:40:15 -0400463 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800464 }
Mike Lockwood67d53582010-05-25 13:40:15 -0400465 default:
466 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800467 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800468 }
David Pursell606835a2015-09-08 17:17:02 -0700469 if (args->protocol) {
470 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
471 break;
472 }
473 } else {
474 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
475 break;
476 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800477 }
478 }
David Pursell606835a2015-09-08 17:17:02 -0700479
480 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800481}
482
David Pursell4e2fd362015-09-22 10:43:08 -0700483static int interactive_shell(const std::string& service_string,
484 bool use_shell_protocol) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700485 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700486 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700487 if (fd < 0) {
488 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800489 return 1;
490 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800491
David Pursell606835a2015-09-08 17:17:02 -0700492 StdinReadArgs* args = new StdinReadArgs;
493 if (!args) {
494 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700495 return 1;
496 }
David Pursell606835a2015-09-08 17:17:02 -0700497 args->stdin_fd = 0;
498 args->write_fd = fd;
499 if (use_shell_protocol) {
500 args->protocol.reset(new ShellProtocol(args->write_fd));
501 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700502
David Pursell606835a2015-09-08 17:17:02 -0700503 stdin_raw_init(args->stdin_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800504
David Pursell606835a2015-09-08 17:17:02 -0700505 int exit_code = 0;
506 if (!adb_thread_create(stdin_read_thread, args)) {
507 PLOG(ERROR) << "error starting stdin read thread";
508 exit_code = 1;
509 delete args;
510 } else {
511 exit_code = read_and_dump(fd, use_shell_protocol);
512 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700513
David Pursell606835a2015-09-08 17:17:02 -0700514 stdin_raw_restore(args->stdin_fd);
515 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800516}
517
518
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700519static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800520 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700521 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800522 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700523
524 const char* prefix = "host";
525 if (type == kTransportUsb) {
526 prefix = "host-usb";
527 } else if (type == kTransportLocal) {
528 prefix = "host-local";
529 }
530 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800531}
532
David Pursell4e2fd362015-09-22 10:43:08 -0700533// Returns the FeatureSet for the indicated transport.
534static FeatureSet GetFeatureSet(TransportType transport_type,
David Pursell71c83122015-09-14 15:33:50 -0700535 const char* serial) {
David Pursell4e2fd362015-09-22 10:43:08 -0700536 std::string result, error;
537
538 if (adb_query(format_host_command("features", transport_type, serial),
539 &result, &error)) {
540 return StringToFeatureSet(result);
David Pursell71c83122015-09-14 15:33:50 -0700541 }
David Pursell4e2fd362015-09-22 10:43:08 -0700542 return FeatureSet();
David Pursell71c83122015-09-14 15:33:50 -0700543}
544
Elliott Hughes6452a892015-04-29 12:28:13 -0700545static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700546 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800547{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700548 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700549 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700550 if (fd < 0) {
551 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800552 return -1;
553 }
554
555 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800556 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800557
Elliott Hughes6452a892015-04-29 12:28:13 -0700558 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800559 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800560
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700561 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700562 const char* x = strrchr(service, ':');
563 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800564 }
565
Elliott Hughes6452a892015-04-29 12:28:13 -0700566 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800567 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700568 if (!WriteFdExactly(fd, ptr, xfer)) {
569 std::string error;
570 adb_status(fd, &error);
571 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800572 return -1;
573 }
574 sz -= xfer;
575 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700576 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100577 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800578 fflush(stdout);
579 }
580 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700581 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800582 printf("\n");
583 }
584
Elliott Hughese67f1f82015-04-30 17:32:03 -0700585 if (!adb_status(fd, &error)) {
586 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800587 return -1;
588 }
589
590 adb_close(fd);
591 return 0;
592}
593
Doug Zongker71fe5842014-06-26 15:35:36 -0700594#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
595
596/*
597 * The sideload-host protocol serves the data in a file (given on the
598 * command line) to the client, using a simple protocol:
599 *
600 * - The connect message includes the total number of bytes in the
601 * file and a block size chosen by us.
602 *
603 * - The other side sends the desired block number as eight decimal
604 * digits (eg "00000023" for block 23). Blocks are numbered from
605 * zero.
606 *
607 * - We send back the data of the requested block. The last block is
608 * likely to be partial; when the last block is requested we only
609 * send the part of the block that exists, it's not padded up to the
610 * block size.
611 *
612 * - When the other side sends "DONEDONE" instead of a block number,
613 * we hang up.
614 */
Elliott Hughes58305772015-04-17 13:57:15 -0700615static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700616 unsigned sz;
617 size_t xfer = 0;
618 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800619 int last_percent = -1;
620 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700621
622 printf("loading: '%s'", fn);
623 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800624 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700625 if (data == 0) {
626 printf("\n");
627 fprintf(stderr, "* cannot read '%s' *\n", fn);
628 return -1;
629 }
630
Elliott Hughes6452a892015-04-29 12:28:13 -0700631 std::string service =
632 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700633 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700634 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700635 if (fd < 0) {
636 // Try falling back to the older sideload method. Maybe this
637 // is an older device that doesn't support sideload-host.
638 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700639 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700640 goto done;
641 }
642
Spencer Lowf055c192015-01-25 14:40:16 -0800643 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700644
Elliott Hughesa7090b92015-04-17 17:03:59 -0700645 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700646 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800647 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700648 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700649 status = -1;
650 goto done;
651 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700652 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700653
Elliott Hughes6452a892015-04-29 12:28:13 -0700654 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700655 status = 0;
656 break;
657 }
658
Doug Zongker71fe5842014-06-26 15:35:36 -0700659 int block = strtol(buf, NULL, 10);
660
661 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
662 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700663 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700664 status = -1;
665 goto done;
666 }
667 uint8_t* start = data + offset;
668 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
669 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
670 if (offset_end > sz) {
671 to_write = sz - offset;
672 }
673
Dan Albertcc731cc2015-02-24 21:26:58 -0800674 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700675 adb_status(fd, &error);
676 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700677 status = -1;
678 goto done;
679 }
680 xfer += to_write;
681
682 // For normal OTA packages, we expect to transfer every byte
683 // twice, plus a bit of overhead (one read during
684 // verification, one read of each byte for installation, plus
685 // extra access to things like the zip central directory).
686 // This estimate of the completion becomes 100% when we've
687 // transferred ~2.13 (=100/47) times the package size.
688 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
689 if (percent != last_percent) {
690 printf("\rserving: '%s' (~%d%%) ", fn, percent);
691 fflush(stdout);
692 last_percent = percent;
693 }
694 }
695
Colin Cross6d6a8982014-07-07 14:12:41 -0700696 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700697
698 done:
699 if (fd >= 0) adb_close(fd);
700 free(data);
701 return status;
702}
703
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800704/**
705 * Run ppp in "notty" mode against a resource listed as the first parameter
706 * eg:
707 *
708 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
709 *
710 */
Elliott Hughes58305772015-04-17 13:57:15 -0700711static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800712#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800713 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
714 return -1;
715#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800716 if (argc < 2) {
717 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
718 argv[0]);
719
720 return 1;
721 }
722
Dan Albertbac34742015-02-25 17:51:28 -0800723 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700724 std::string error;
725 int fd = adb_connect(adb_service_name, &error);
726 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800727 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700728 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800729 return 1;
730 }
731
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700732 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800733
734 if (pid < 0) {
735 perror("from fork()");
736 return 1;
737 } else if (pid == 0) {
738 int err;
739 int i;
740 const char **ppp_args;
741
742 // copy args
743 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
744 ppp_args[0] = "pppd";
745 for (i = 2 ; i < argc ; i++) {
746 //argv[2] and beyond become ppp_args[1] and beyond
747 ppp_args[i - 1] = argv[i];
748 }
749 ppp_args[i-1] = NULL;
750
751 // child side
752
753 dup2(fd, STDIN_FILENO);
754 dup2(fd, STDOUT_FILENO);
755 adb_close(STDERR_FILENO);
756 adb_close(fd);
757
758 err = execvp("pppd", (char * const *)ppp_args);
759
760 if (err < 0) {
761 perror("execing pppd");
762 }
763 exit(-1);
764 } else {
765 // parent side
766
767 adb_close(fd);
768 return 0;
769 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800770#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800771}
772
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700773static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700774 // Was the caller vague about what they'd like us to wait for?
775 // If so, check they weren't more specific in their choice of transport type.
776 if (strcmp(service, "wait-for-device") == 0) {
777 if (t == kTransportUsb) {
778 service = "wait-for-usb";
779 } else if (t == kTransportLocal) {
780 service = "wait-for-local";
781 } else {
782 service = "wait-for-any";
783 }
784 }
785
786 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700787 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700788}
789
David Pursell70ef7b42015-09-30 13:35:42 -0700790// Returns a shell service string with the indicated arguments and command.
791static std::string ShellServiceString(bool use_shell_protocol,
792 const std::string& type_arg,
793 const std::string& command) {
794 std::vector<std::string> args;
795 if (use_shell_protocol) {
796 args.push_back(kShellServiceArgShellProtocol);
797 }
798 if (!type_arg.empty()) {
799 args.push_back(type_arg);
800 }
801
802 // Shell service string can look like: shell[,arg1,arg2,...]:[command].
803 return android::base::StringPrintf("shell%s%s:%s",
804 args.empty() ? "" : ",",
805 android::base::Join(args, ',').c_str(),
806 command.c_str());
807}
808
809// Connects to the device "shell" service with |command| and prints the
810// resulting output.
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700811static int send_shell_command(TransportType transport_type, const char* serial,
David Pursell70ef7b42015-09-30 13:35:42 -0700812 const std::string& command,
813 bool disable_shell_protocol) {
814 // Only use shell protocol if it's supported and the caller doesn't want
815 // to explicitly disable it.
816 bool use_shell_protocol = false;
817 if (!disable_shell_protocol) {
818 FeatureSet features = GetFeatureSet(transport_type, serial);
819 use_shell_protocol = CanUseFeature(features, kFeatureShell2);
820 }
821
822 std::string service_string = ShellServiceString(use_shell_protocol, "",
823 command);
824
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700825 int fd;
826 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700827 std::string error;
David Pursell70ef7b42015-09-30 13:35:42 -0700828 fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700829 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800830 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700831 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800832 fprintf(stderr,"- waiting for device -\n");
833 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700834 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800835 }
836
David Pursell70ef7b42015-09-30 13:35:42 -0700837 int exit_code = read_and_dump(fd, use_shell_protocol);
David Pursell71c83122015-09-14 15:33:50 -0700838
839 if (adb_close(fd) < 0) {
840 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700841 }
David Pursell71c83122015-09-14 15:33:50 -0700842
843 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800844}
845
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700846static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700847 char* log_tags = getenv("ANDROID_LOG_TAGS");
848 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800849
David Pursell70ef7b42015-09-30 13:35:42 -0700850 std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800851
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700852 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700853 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800854 }
855
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700856 --argc;
857 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700858 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700859 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800860 }
861
David Pursell70ef7b42015-09-30 13:35:42 -0700862 // No need for shell protocol with logcat, always disable for simplicity.
863 return send_shell_command(transport, serial, cmd, true);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800864}
865
Dan Albertbac34742015-02-25 17:51:28 -0800866static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700867 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700868
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700869 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700870 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700871 if (!strcmp("-f", argv[i])) {
872 if (i == argc-1) {
873 fprintf(stderr, "adb: -f passed with no filename\n");
874 return usage();
875 }
876 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700877 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700878 argv[i++] = argv[j++];
879 }
880 argc -= 2;
881 argv[argc] = NULL;
882 }
Christopher Tated2f54152011-04-21 12:53:28 -0700883 }
884
Christopher Tatebb86bc52011-08-22 17:12:08 -0700885 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
886 if (argc < 2) return usage();
887
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800888 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700889 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700890 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700891 if (outFd < 0) {
892 fprintf(stderr, "adb: unable to open file %s\n", filename);
893 return -1;
894 }
895
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700896 std::string cmd = "backup:";
897 --argc;
898 ++argv;
899 while (argc-- > 0) {
900 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700901 }
902
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700903 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700904 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700905 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700906 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700907 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700908 adb_close(outFd);
909 return -1;
910 }
911
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800912 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700913 copy_to_file(fd, outFd);
914
915 adb_close(fd);
916 adb_close(outFd);
917 return 0;
918}
919
Dan Albertbac34742015-02-25 17:51:28 -0800920static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700921 if (argc != 2) return usage();
922
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700923 const char* filename = argv[1];
924 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700925 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700926 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700927 return -1;
928 }
929
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700930 std::string error;
931 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700932 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700933 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700934 adb_close(tarFd);
935 return -1;
936 }
937
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800938 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700939 copy_to_file(tarFd, fd);
940
941 adb_close(fd);
942 adb_close(tarFd);
943 return 0;
944}
945
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800946/* <hint> may be:
947 * - A simple product name
948 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800949 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
950 * e.g., "out/target/product/sooner"
951 * - An absolute path to the PRODUCT_OUT dir
952 * e.g., "/src/device/out/target/product/sooner"
953 *
954 * Given <hint>, try to construct an absolute path to the
955 * ANDROID_PRODUCT_OUT dir.
956 */
Elliott Hughes5c742702015-07-30 17:42:01 -0700957static std::string find_product_out_path(const std::string& hint) {
958 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -0700959 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800960 }
961
Elliott Hughes58305772015-04-17 13:57:15 -0700962 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -0700963 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -0700964 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800965 }
966
Elliott Hughes58305772015-04-17 13:57:15 -0700967 // If there are any slashes in it, assume it's a relative path;
968 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -0700969 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700970 std::string cwd;
971 if (!getcwd(&cwd)) {
972 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -0700973 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800974 }
Elliott Hughes5c742702015-07-30 17:42:01 -0700975 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 -0800976 }
977
Elliott Hughes58305772015-04-17 13:57:15 -0700978 // It's a string without any slashes. Try to do something with it.
979 //
980 // Try to find the root of the build tree, and build a PRODUCT_OUT
981 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -0700982 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -0700983 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -0700984 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -0700985 return "";
986 }
Elliott Hughesa7090b92015-04-17 17:03:59 -0700987
988 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -0700989 path += OS_PATH_SEPARATOR_STR;
990 path += "out";
991 path += OS_PATH_SEPARATOR_STR;
992 path += "target";
993 path += OS_PATH_SEPARATOR_STR;
994 path += "product";
995 path += OS_PATH_SEPARATOR_STR;
996 path += hint;
997 if (!directory_exists(path)) {
998 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -0700999 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -07001000 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001001 }
Elliott Hughes58305772015-04-17 13:57:15 -07001002 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001003}
1004
Dan Albertbac34742015-02-25 17:51:28 -08001005static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -07001006 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -08001007 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001008 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001009 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001010
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001011 while (narg > 0) {
1012 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001013 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001014 } else if (!strcmp(*arg, "-a")) {
1015 *copy_attrs = 1;
1016 } else {
1017 break;
1018 }
Mark Lindner76f2a932014-03-11 17:55:59 -07001019 ++arg;
1020 --narg;
1021 }
1022
1023 if (narg > 0) {
1024 *path1 = *arg;
1025 ++arg;
1026 --narg;
1027 }
1028
1029 if (narg > 0) {
1030 *path2 = *arg;
1031 }
1032}
1033
Elliott Hughes6452a892015-04-29 12:28:13 -07001034static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001035 std::string error;
1036 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001037 if (fd < 0) {
1038 fprintf(stderr, "error: %s\n", error.c_str());
1039 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001040 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001041 read_and_dump(fd);
1042 adb_close(fd);
1043 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001044}
1045
Elliott Hughes6452a892015-04-29 12:28:13 -07001046static int adb_query_command(const std::string& command) {
1047 std::string result;
1048 std::string error;
1049 if (!adb_query(command, &result, &error)) {
1050 fprintf(stderr, "error: %s\n", error.c_str());
1051 return 1;
1052 }
1053 printf("%s\n", result.c_str());
1054 return 0;
1055}
1056
Spencer Lowa13df302015-09-07 16:20:13 -07001057// Disallow stdin, stdout, and stderr.
1058static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1059#ifdef _WIN32
1060 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1061 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1062 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1063 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1064#else
1065 return ack_reply_fd > 2;
1066#endif
1067}
1068
Elliott Hughesab52c182015-05-01 17:04:38 -07001069int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001070 int no_daemon = 0;
1071 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001072 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001073 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001074 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001075 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001076
Elliott Hughes58305772015-04-17 13:57:15 -07001077 // If defined, this should be an absolute path to
1078 // the directory containing all of the various system images
1079 // for a particular product. If not defined, and the adb
1080 // command requires this information, then the user must
1081 // specify the path using "-p".
1082 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1083 if (ANDROID_PRODUCT_OUT != nullptr) {
1084 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001085 }
1086 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1087
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001088 const char* serial = getenv("ANDROID_SERIAL");
Nick Pellydb449262009-05-07 12:48:03 -07001089
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001090 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001091 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001092 int server_port = DEFAULT_ADB_PORT;
1093 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001094 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001095 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001096 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001097 "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 +01001098 server_port_str);
1099 return usage();
1100 }
1101 }
1102
1103 /* modifiers and flags */
Riley Andrews98f58e82014-12-05 17:37:24 -08001104 while (argc > 0) {
1105 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001106 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001107 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001108 no_daemon = 1;
1109 } else if (!strcmp(argv[0], "fork-server")) {
1110 /* this is a special flag used only when the ADB client launches the ADB Server */
1111 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001112 } else if (!strcmp(argv[0], "--reply-fd")) {
1113 if (argc < 2) return usage();
1114 const char* reply_fd_str = argv[1];
1115 argc--;
1116 argv++;
1117 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001118 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001119 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1120 return usage();
1121 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001122 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001123 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001124 if (argv[0][2] == '\0') {
1125 if (argc < 2) return usage();
1126 product = argv[1];
1127 argc--;
1128 argv++;
1129 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001130 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001131 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001132 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001133 if (gProductOutPath.empty()) {
1134 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001135 return usage();
1136 }
1137 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1138 if (isdigit(argv[0][2])) {
1139 serial = argv[0] + 2;
1140 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001141 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001142 serial = argv[1];
1143 argc--;
1144 argv++;
1145 }
1146 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001147 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001148 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001149 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001150 } else if (!strcmp(argv[0],"-a")) {
1151 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001152 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001153 const char *hostname = NULL;
1154 if (argv[0][2] == '\0') {
1155 if (argc < 2) return usage();
1156 hostname = argv[1];
1157 argc--;
1158 argv++;
1159 } else {
1160 hostname = argv[0] + 2;
1161 }
1162 adb_set_tcp_name(hostname);
1163
Riley Andrews98f58e82014-12-05 17:37:24 -08001164 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001165 if (argv[0][2] == '\0') {
1166 if (argc < 2) return usage();
1167 server_port_str = argv[1];
1168 argc--;
1169 argv++;
1170 } else {
1171 server_port_str = argv[0] + 2;
1172 }
1173 if (strlen(server_port_str) > 0) {
1174 server_port = (int) strtol(server_port_str, NULL, 0);
1175 if (server_port <= 0 || server_port > 65535) {
1176 fprintf(stderr,
1177 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1178 server_port_str);
1179 return usage();
1180 }
1181 } else {
1182 fprintf(stderr,
1183 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1184 return usage();
1185 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001186 } else {
1187 /* out of recognized modifiers and flags */
1188 break;
1189 }
1190 argc--;
1191 argv++;
1192 }
1193
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001194 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001195 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001196
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001197 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001198 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001199 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001200 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1201 return usage();
1202 }
1203 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001204 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001205 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001206 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001207 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001208 fprintf(stderr,"* could not start server *\n");
1209 }
1210 return r;
1211 }
1212
Riley Andrews98f58e82014-12-05 17:37:24 -08001213 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001214 return usage();
1215 }
1216
Riley Andrewsc8514c82014-12-05 17:32:46 -08001217 /* handle wait-for-* prefix */
1218 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001219 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001220
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001221 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001222 return 1;
1223 }
1224
Elliott Hughes2b101112015-05-04 19:29:32 -07001225 // Allow a command to be run after wait-for-device,
1226 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001227 if (argc == 1) {
1228 return 0;
1229 }
1230
1231 /* Fall through */
1232 argc--;
1233 argv++;
1234 }
1235
1236 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001237 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001238 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001239 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001240 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001241 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001242 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001243 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001244 fprintf(stderr, "Usage: adb devices [-l]\n");
1245 return 1;
1246 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001247
1248 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1249 printf("List of devices attached\n");
1250 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001251 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001252 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001253 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001254 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001255 return 1;
1256 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001257
1258 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1259 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001260 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001261 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001262 if (argc > 2) {
1263 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1264 return 1;
1265 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001266
1267 std::string query = android::base::StringPrintf("host:disconnect:%s",
1268 (argc == 2) ? argv[1] : "");
1269 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001270 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001271 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001272 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001273 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001274 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001275 char h = (argv[0][0] == 'h');
1276
David Pursell4e2fd362015-09-22 10:43:08 -07001277 FeatureSet features = GetFeatureSet(transport_type, serial);
1278
David Pursell70ef7b42015-09-30 13:35:42 -07001279 bool use_shell_protocol = CanUseFeature(features, kFeatureShell2);
David Pursell4e2fd362015-09-22 10:43:08 -07001280 if (!use_shell_protocol) {
1281 D("shell protocol not supported, using raw data transfer");
1282 } else {
1283 D("using shell protocol");
1284 }
1285
1286 // Parse shell-specific command-line options.
1287 // argv[0] is always "shell".
1288 --argc;
1289 ++argv;
1290 std::string shell_type_arg;
1291 while (argc) {
1292 if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
David Pursell70ef7b42015-09-30 13:35:42 -07001293 if (!CanUseFeature(features, kFeatureShell2)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001294 fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
1295 return 1;
1296 }
David Pursell70ef7b42015-09-30 13:35:42 -07001297 shell_type_arg = (argv[0][1] == 'T') ? kShellServiceArgRaw
1298 : kShellServiceArgPty;
1299 --argc;
1300 ++argv;
1301 } else if (!strcmp(argv[0], "-x")) {
1302 use_shell_protocol = false;
David Pursell4e2fd362015-09-22 10:43:08 -07001303 --argc;
1304 ++argv;
1305 } else {
1306 break;
1307 }
1308 }
David Pursell4e2fd362015-09-22 10:43:08 -07001309
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001310 if (h) {
1311 printf("\x1b[41;33m");
1312 fflush(stdout);
1313 }
1314
David Pursell4e2fd362015-09-22 10:43:08 -07001315 if (!argc) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001316 D("starting interactive shell");
David Pursell70ef7b42015-09-30 13:35:42 -07001317 std::string service_string =
1318 ShellServiceString(use_shell_protocol, shell_type_arg, "");
David Pursell4e2fd362015-09-22 10:43:08 -07001319 r = interactive_shell(service_string, use_shell_protocol);
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001320 if (h) {
1321 printf("\x1b[0m");
1322 fflush(stdout);
1323 }
1324 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001325 }
1326
David Pursell4e2fd362015-09-22 10:43:08 -07001327 // We don't escape here, just like ssh(1). http://b/20564385.
David Pursell70ef7b42015-09-30 13:35:42 -07001328 std::string command = android::base::Join(
David Pursell4e2fd362015-09-22 10:43:08 -07001329 std::vector<const char*>(argv, argv + argc), ' ');
David Pursell70ef7b42015-09-30 13:35:42 -07001330 std::string service_string =
1331 ShellServiceString(use_shell_protocol, shell_type_arg, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001332
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001333 while (true) {
David Pursell4e2fd362015-09-22 10:43:08 -07001334 D("non-interactive shell loop. cmd=%s", service_string.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001335 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -07001336 int fd = adb_connect(service_string, &error);
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001337 int r;
Riley Andrews98f58e82014-12-05 17:37:24 -08001338 if (fd >= 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001339 D("about to read_and_dump(fd=%d)", fd);
David Pursell606835a2015-09-08 17:17:02 -07001340 r = read_and_dump(fd, use_shell_protocol);
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001341 D("read_and_dump() done.");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001342 adb_close(fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001343 } else {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001344 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001345 r = -1;
1346 }
1347
Elliott Hughes32687be2015-05-05 12:50:26 -07001348 if (h) {
1349 printf("\x1b[0m");
1350 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001351 }
David Pursell606835a2015-09-08 17:17:02 -07001352 D("non-interactive shell loop. return r=%d", r);
Elliott Hughes32687be2015-05-05 12:50:26 -07001353 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001354 }
1355 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001356 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001357 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001358
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001359 std::string cmd = "exec:";
1360 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001361 argc -= 2;
1362 argv += 2;
1363 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001364 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001365 }
1366
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001367 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001368 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001369 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001370 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001371 return -1;
1372 }
1373
1374 if (exec_in) {
1375 copy_to_file(STDIN_FILENO, fd);
1376 } else {
1377 copy_to_file(fd, STDOUT_FILENO);
1378 }
1379
1380 adb_close(fd);
1381 return 0;
1382 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001383 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001384 std::string error;
1385 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001386 if (fd == -2) {
1387 // Failed to make network connection to server. Don't output the
1388 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001389 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001390 // Successful exit code because the server is already "killed".
1391 return 0;
1392 } else if (fd == -1) {
1393 // Some other error.
1394 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001395 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001396 } else {
1397 // Successfully connected, kill command sent, okay status came back.
1398 // Server should exit() in a moment, if not already.
1399 adb_close(fd);
1400 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001401 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001402 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001403 else if (!strcmp(argv[0], "sideload")) {
1404 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001405 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001406 return 1;
1407 } else {
1408 return 0;
1409 }
1410 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001411 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1412 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1413 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001414 else if (!strcmp(argv[0], "remount") ||
1415 !strcmp(argv[0], "reboot") ||
1416 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001417 !strcmp(argv[0], "usb") ||
1418 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001419 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001420 !strcmp(argv[0], "disable-verity") ||
1421 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001422 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001423 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001424 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001425 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001426 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001427 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001428 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001429 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001430 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001431 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001432 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001433 if (argc != 1) return usage();
David Pursell70ef7b42015-09-30 13:35:42 -07001434 // No need for shell protocol with bugreport, always disable for
1435 // simplicity.
1436 return send_shell_command(transport_type, serial, "bugreport", true);
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001437 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001438 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001439 bool reverse = !strcmp(argv[0], "reverse");
1440 ++argv;
1441 --argc;
1442 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001443
1444 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001445 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001446 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001447 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001448 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001449 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001450 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001451 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001452 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001453 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001454 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001455 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001456 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001457 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001458 }
1459
Elliott Hughes424af022015-05-29 17:55:19 -07001460 std::string cmd;
1461 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001462 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001463 return adb_query_command(host_prefix + ":list-forward");
1464 } else if (strcmp(argv[0], "--remove-all") == 0) {
1465 if (argc != 1) return usage();
1466 cmd = host_prefix + ":killforward-all";
1467 } else if (strcmp(argv[0], "--remove") == 0) {
1468 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001469 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001470 cmd = host_prefix + ":killforward:" + argv[1];
1471 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1472 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001473 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001474 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1475 } else {
1476 // forward <local> <remote>
1477 if (argc != 2) return usage();
1478 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001479 }
1480
Elliott Hughes424af022015-05-29 17:55:19 -07001481 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001482 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001483 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001484 else if (!strcmp(argv[0], "ls")) {
1485 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001486 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001487 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001488 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001489 bool show_progress = false;
1490 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001491 const char* lpath = NULL, *rpath = NULL;
1492
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001493 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001494 if (!lpath || !rpath || copy_attrs != 0) return usage();
1495 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001496 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001497 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001498 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001499 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001500 const char* rpath = NULL, *lpath = ".";
1501
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001502 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001503 if (!rpath) return usage();
1504 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001505 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001506 else if (!strcmp(argv[0], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001507 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001508 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001509 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001510 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001511 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001512 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001513 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001514 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001515 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001516 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001517 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001518 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001519 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001520 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001521 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001522 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001523 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001524 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001525 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001526 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001527 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001528 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001529 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001530 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001531 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001532 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001533 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001534 } else {
1535 return usage();
1536 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001537
Elliott Hughesd236d072015-04-21 10:17:07 -07001538 if (src != "" &&
1539 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001540 return usage();
1541 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001542
Elliott Hughes58305772015-04-17 13:57:15 -07001543 std::string system_src_path = product_file("system");
1544 std::string data_src_path = product_file("data");
1545 std::string vendor_src_path = product_file("vendor");
1546 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001547
Elliott Hughesaa245492015-08-03 10:38:08 -07001548 bool okay = true;
1549 if (okay && (src.empty() || src == "system")) {
1550 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001551 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001552 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1553 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001554 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001555 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1556 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001557 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001558 if (okay && (src.empty() || src == "data")) {
1559 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001560 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001561 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001562 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001563 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001564 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001565 !strcmp(argv[0],"get-serialno") ||
1566 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001567 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001568 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001569 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001570 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001571 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001572 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001573 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001574 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001575 return ppp(argc, argv);
1576 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001577 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001578 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001579 const int result = adb_connect("host:start-server", &error);
1580 if (result < 0) {
1581 fprintf(stderr, "error: %s\n", error.c_str());
1582 }
1583 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001584 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001585 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001586 return backup(argc, argv);
1587 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001588 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001589 return restore(argc, argv);
1590 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001591 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001592 if (argc < 2) return usage();
Yabin Cuiaed3c612015-09-22 15:52:57 -07001593 // Always print key generation information for keygen command.
1594 adb_trace_enable(AUTH);
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001595 return adb_auth_keygen(argv[1]);
1596 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001597 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001598 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001599 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001600 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001601 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001602 help();
1603 return 0;
1604 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001605 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001606 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001607 return 0;
1608 }
Dan Albert90d4b732015-05-20 18:58:41 -07001609 else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001610 // Only list the features common to both the adb client and the device.
1611 FeatureSet features = GetFeatureSet(transport_type, serial);
1612 for (const std::string& name : features) {
David Pursell70ef7b42015-09-30 13:35:42 -07001613 if (CanUseFeature(features, name)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001614 printf("%s\n", name.c_str());
1615 }
1616 }
1617 return 0;
Dan Albert90d4b732015-05-20 18:58:41 -07001618 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001619
1620 usage();
1621 return 1;
1622}
1623
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001624static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
David Pursell70ef7b42015-09-30 13:35:42 -07001625 std::string cmd = "pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001626
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001627 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001628 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001629 }
1630
David Pursell70ef7b42015-09-30 13:35:42 -07001631 // TODO(dpursell): add command-line arguments to install/uninstall to
1632 // manually disable shell protocol if needed.
1633 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001634}
1635
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001636static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001637 /* if the user choose the -k option, we refuse to do it until devices are
1638 out with the option to uninstall the remaining data somehow (adb/ui) */
1639 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1640 {
1641 printf(
1642 "The -k option uninstalls the application while retaining the data/cache.\n"
1643 "At the moment, there is no way to remove the remaining data.\n"
1644 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1645 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1646 return -1;
1647 }
1648
1649 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1650 return pm_command(transport, serial, argc, argv);
1651}
1652
Elliott Hughes5c742702015-07-30 17:42:01 -07001653static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
David Pursell70ef7b42015-09-30 13:35:42 -07001654 std::string cmd = "rm -f " + escape_arg(filename);
1655 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001656}
1657
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001658static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001659 static const char *const DATA_DEST = "/data/local/tmp/%s";
1660 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001661 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001662 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001663 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001664
1665 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001666 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001667 where = SD_DEST;
1668 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001669 }
1670
Jeff Sharkey960df972014-06-09 17:30:57 -07001671 // Find last APK argument.
1672 // All other arguments passed through verbatim.
1673 int last_apk = -1;
1674 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001675 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001676 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001677 if (dot && !strcasecmp(dot, ".apk")) {
1678 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1679 fprintf(stderr, "Invalid APK file: %s\n", file);
1680 return -1;
1681 }
1682
1683 last_apk = i;
1684 break;
1685 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001686 }
1687
Jeff Sharkey960df972014-06-09 17:30:57 -07001688 if (last_apk == -1) {
1689 fprintf(stderr, "Missing APK file\n");
1690 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001691 }
1692
Elliott Hughesaa245492015-08-03 10:38:08 -07001693 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001694 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001695 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001696 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1697 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1698 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001699
Kenny Root60733e92012-03-26 16:14:02 -07001700cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001701 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001702 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001703}
1704
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001705static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001706 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001707{
Jeff Sharkey960df972014-06-09 17:30:57 -07001708 int i;
1709 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001710 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001711
1712 // Find all APK arguments starting at end.
1713 // All other arguments passed through verbatim.
1714 int first_apk = -1;
1715 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001716 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001717 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001718 if (dot && !strcasecmp(dot, ".apk")) {
1719 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1720 fprintf(stderr, "Invalid APK file: %s\n", file);
1721 return -1;
1722 }
1723
1724 total_size += sb.st_size;
1725 first_apk = i;
1726 } else {
1727 break;
1728 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001729 }
1730
Jeff Sharkey960df972014-06-09 17:30:57 -07001731 if (first_apk == -1) {
1732 fprintf(stderr, "Missing APK file\n");
1733 return 1;
1734 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001735
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001736 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001737 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001738 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001739 }
1740
1741 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001742 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001743 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001744 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001745 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001746 return -1;
1747 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001748 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001749 read_status_line(fd, buf, sizeof(buf));
1750 adb_close(fd);
1751
1752 int session_id = -1;
1753 if (!strncmp("Success", buf, 7)) {
1754 char* start = strrchr(buf, '[');
1755 char* end = strrchr(buf, ']');
1756 if (start && end) {
1757 *end = '\0';
1758 session_id = strtol(start + 1, NULL, 10);
1759 }
1760 }
1761 if (session_id < 0) {
1762 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001763 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001764 return -1;
1765 }
1766
1767 // Valid session, now stream the APKs
1768 int success = 1;
1769 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001770 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001771 if (stat(file, &sb) == -1) {
1772 fprintf(stderr, "Failed to stat %s\n", file);
1773 success = 0;
1774 goto finalize_session;
1775 }
1776
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001777 std::string cmd = android::base::StringPrintf(
1778 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001779 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001780
1781 int localFd = adb_open(file, O_RDONLY);
1782 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001783 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001784 success = 0;
1785 goto finalize_session;
1786 }
1787
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001788 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001789 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001790 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001791 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001792 adb_close(localFd);
1793 success = 0;
1794 goto finalize_session;
1795 }
1796
1797 copy_to_file(localFd, remoteFd);
1798 read_status_line(remoteFd, buf, sizeof(buf));
1799
1800 adb_close(localFd);
1801 adb_close(remoteFd);
1802
1803 if (strncmp("Success", buf, 7)) {
1804 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001805 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001806 success = 0;
1807 goto finalize_session;
1808 }
1809 }
1810
1811finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001812 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001813 std::string service =
1814 android::base::StringPrintf("exec:pm install-%s %d",
1815 success ? "commit" : "abandon", session_id);
1816 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001817 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001818 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001819 return -1;
1820 }
1821 read_status_line(fd, buf, sizeof(buf));
1822 adb_close(fd);
1823
1824 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001825 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001826 return 0;
1827 } else {
1828 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001829 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001830 return -1;
1831 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001832}