blob: a915a3359b978906d97516cce10610fdfd2ce581 [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)
Josh Gao8dcdb572015-10-23 15:03:31 -070042#include <signal.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080044#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080045#endif
46
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080047#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080048#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080049#include "adb_client.h"
50#include "adb_io.h"
Elliott Hughes58305772015-04-17 13:57:15 -070051#include "adb_utils.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080052#include "file_sync_service.h"
David Pursell70ef7b42015-09-30 13:35:42 -070053#include "services.h"
David Pursell606835a2015-09-08 17:17:02 -070054#include "shell_service.h"
55#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056
Elliott Hughes3bd73c12015-05-05 13:10:43 -070057static int install_app(TransportType t, const char* serial, int argc, const char** argv);
58static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
59static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060
Elliott Hughes58305772015-04-17 13:57:15 -070061static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080062extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063
Elliott Hughes58305772015-04-17 13:57:15 -070064static std::string product_file(const char *extra) {
65 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080066 fprintf(stderr, "adb: Product directory not specified; "
67 "use -p or define ANDROID_PRODUCT_OUT\n");
68 exit(1);
69 }
70
Elliott Hughes58305772015-04-17 13:57:15 -070071 return android::base::StringPrintf("%s%s%s",
72 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080073}
74
Elliott Hughes58305772015-04-17 13:57:15 -070075static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070076 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080077 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080078 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080079 " -d - directs command to the only connected USB device\n"
80 " returns an error if more than one USB device is present.\n"
81 " -e - directs command to the only running emulator.\n"
82 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070083 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070084 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070085 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080086 " -p <product name or path> - simple product name like 'sooner', or\n"
87 " a relative/absolute path to a product\n"
88 " out directory like 'out/target/product/sooner'.\n"
89 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
90 " environment variable is used, which must\n"
91 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080092 " -H - Name of adb server host (default: localhost)\n"
93 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070094 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070095 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040096 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
97 " Port 5555 is used by default if no port number is specified.\n"
98 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
99 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +0200100 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400101 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800102 "\n"
103 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700104 " adb push [-p] <local> <remote>\n"
105 " - copy file/dir to device\n"
106 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700107 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700108 " - copy file/dir from device\n"
109 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700110 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800111 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600112 " (-l means list but don't copy)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700113 " adb shell [-Ttx] - run remote shell interactively\n"
114 " adb shell [-Ttx] <command> - run remote shell command\n"
David Pursell4e2fd362015-09-22 10:43:08 -0700115 " (-T disables PTY allocation)\n"
116 " (-t forces PTY allocation)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700117 " (-x disables remote exit codes and stdout/stderr separation)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800118 " adb emu <command> - run emulator console command\n"
119 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100120 " adb forward --list - list all forward socket connections.\n"
121 " the format is a list of lines with the following format:\n"
122 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800123 " adb forward <local> <remote> - forward socket connections\n"
124 " forward specs are one of: \n"
125 " tcp:<port>\n"
126 " localabstract:<unix domain socket name>\n"
127 " localreserved:<unix domain socket name>\n"
128 " localfilesystem:<unix domain socket name>\n"
129 " dev:<character device name>\n"
130 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100131 " adb forward --no-rebind <local> <remote>\n"
132 " - same as 'adb forward <local> <remote>' but fails\n"
133 " if <local> is already forwarded\n"
134 " adb forward --remove <local> - remove a specific forward socket connection\n"
135 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100136 " adb reverse --list - list all reverse socket connections from device\n"
137 " adb reverse <remote> <local> - reverse socket connections\n"
138 " reverse specs are one of:\n"
139 " tcp:<port>\n"
140 " localabstract:<unix domain socket name>\n"
141 " localreserved:<unix domain socket name>\n"
142 " localfilesystem:<unix domain socket name>\n"
143 " adb reverse --norebind <remote> <local>\n"
144 " - same as 'adb reverse <remote> <local>' but fails\n"
145 " if <remote> is already reversed.\n"
146 " adb reverse --remove <remote>\n"
147 " - remove a specific reversed socket connection\n"
148 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800149 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900150 " adb install [-lrtsdg] <file>\n"
Svetoslav23d84072015-06-01 16:02:50 -0700151 " - push this package file to the device and install it\n"
152 " (-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 " (-g: grant all runtime permissions)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900158 " adb install-multiple [-lrtsdpg] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700159 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700160 " (-l: forward lock application)\n"
161 " (-r: replace existing application)\n"
162 " (-t: allow test packages)\n"
163 " (-s: install application on sdcard)\n"
164 " (-d: allow version code downgrade)\n"
165 " (-p: partial application install)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900166 " (-g: grant all runtime permissions)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800167 " adb uninstall [-k] <package> - remove this app package from the device\n"
168 " ('-k' means keep the data and cache directories)\n"
169 " adb bugreport - return all information from the device\n"
170 " that should be included in a bug report.\n"
171 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800172 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700173 " - write an archive of the device's data to <file>.\n"
174 " If no -f option is supplied then the data is written\n"
175 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700176 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700177 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800178 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
179 " (aka .obb) files associated with each application; the default\n"
180 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700181 " (-shared|-noshared enable/disable backup of the device's\n"
182 " shared storage / SD card contents; the default is noshared.)\n"
183 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700184 " (-system|-nosystem toggles whether -all automatically includes\n"
185 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700186 " (<packages...> is the list of applications to be backed up. If\n"
187 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700188 " list is optional. Applications explicitly given on the\n"
189 " command line will be included even if -nosystem would\n"
190 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700191 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700192 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700193 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800194 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
195 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800196 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
197 " and the public key is stored in <file>.pub. Any existing files\n"
198 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800199 " adb help - show this help message\n"
200 " adb version - show version num\n"
201 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800202 "scripting:\n"
203 " adb wait-for-device - block until device is online\n"
204 " adb start-server - ensure that there is a server running\n"
205 " adb kill-server - kill the server if it is running\n"
206 " adb get-state - prints: offline | bootloader | device\n"
207 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700208 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000209 " 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 -0700210 " adb reboot [bootloader|recovery]\n"
211 " - reboots the device, optionally into the bootloader or recovery program.\n"
212 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
213 " adb reboot sideload-auto-reboot\n"
214 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700215 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700216 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500217 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800218 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000219 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700220 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800221 "networking:\n"
222 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500223 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800224 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
225 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
226 "\n"
227 "adb sync notes: adb sync [ <directory> ]\n"
228 " <localdir> can be interpreted in several ways:\n"
229 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000230 " - 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 -0800231 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000232 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800233 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000234 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700235 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000236 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
237 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
238 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
239 " 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 -0800240 );
241}
242
Elliott Hughes58305772015-04-17 13:57:15 -0700243static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800244 help();
245 return 1;
246}
247
Yabin Cuid325e862014-11-17 14:48:25 -0800248#if defined(_WIN32)
249
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700250// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800251void stdin_raw_init(int fd);
252void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800253
254#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100255static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100257static void stdin_raw_init(int fd) {
258 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800259
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100260 termios tio;
261 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800262
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100263 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800264
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100265 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800266 tio.c_cc[VTIME] = 0;
267 tio.c_cc[VMIN] = 1;
268
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100269 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800270}
271
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100272static void stdin_raw_restore(int fd) {
273 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800274}
275#endif
276
David Pursell606835a2015-09-08 17:17:02 -0700277// Reads from |fd| and prints received data. If |use_shell_protocol| is true
278// this expects that incoming data will use the shell protocol, in which case
279// stdout/stderr are routed independently and the remote exit code will be
280// returned.
281static int read_and_dump(int fd, bool use_shell_protocol=false) {
282 int exit_code = 0;
283 std::unique_ptr<ShellProtocol> protocol;
284 int length = 0;
285 FILE* outfile = stdout;
286
287 char raw_buffer[BUFSIZ];
288 char* buffer_ptr = raw_buffer;
289 if (use_shell_protocol) {
290 protocol.reset(new ShellProtocol(fd));
291 if (!protocol) {
292 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
293 return 1;
294 }
295 buffer_ptr = protocol->data();
296 }
297
Elliott Hughes5677c232015-05-07 23:37:40 -0700298 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700299 if (use_shell_protocol) {
300 if (!protocol->Read()) {
301 break;
302 }
303 switch (protocol->id()) {
304 case ShellProtocol::kIdStdout:
305 outfile = stdout;
306 break;
307 case ShellProtocol::kIdStderr:
308 outfile = stderr;
309 break;
310 case ShellProtocol::kIdExit:
311 exit_code = protocol->data()[0];
312 continue;
313 default:
314 continue;
315 }
316 length = protocol->data_length();
317 } else {
318 D("read_and_dump(): pre adb_read(fd=%d)", fd);
319 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
320 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
321 if (length <= 0) {
322 break;
323 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800324 }
325
David Pursell606835a2015-09-08 17:17:02 -0700326 fwrite(buffer_ptr, 1, length, outfile);
327 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800328 }
David Pursell606835a2015-09-08 17:17:02 -0700329
330 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800331}
332
Jeff Sharkey960df972014-06-09 17:30:57 -0700333static void read_status_line(int fd, char* buf, size_t count)
334{
335 count--;
336 while (count > 0) {
337 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700338 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700339 break;
340 }
341
342 buf += len;
343 count -= len;
344 }
345 *buf = '\0';
346}
347
Christopher Tated2f54152011-04-21 12:53:28 -0700348static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700349 const size_t BUFSIZE = 32 * 1024;
350 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700351 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700352 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700353 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700354#ifdef _WIN32
355 int old_stdin_mode = -1;
356 int old_stdout_mode = -1;
357#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700358
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700359 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800360
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700361 if (inFd == STDIN_FILENO) {
362 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700363#ifdef _WIN32
364 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
365 if (old_stdin_mode == -1) {
366 fatal_errno("could not set stdin to binary");
367 }
368#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700369 }
Yabin Cuid325e862014-11-17 14:48:25 -0800370
Spencer Lowb7dfb792015-05-22 16:48:31 -0700371#ifdef _WIN32
372 if (outFd == STDOUT_FILENO) {
373 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
374 if (old_stdout_mode == -1) {
375 fatal_errno("could not set stdout to binary");
376 }
377 }
378#endif
379
Elliott Hughesa7090b92015-04-17 17:03:59 -0700380 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700381 if (inFd == STDIN_FILENO) {
382 len = unix_read(inFd, buf, BUFSIZE);
383 } else {
384 len = adb_read(inFd, buf, BUFSIZE);
385 }
Christopher Tated2f54152011-04-21 12:53:28 -0700386 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700387 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700388 break;
389 }
390 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700391 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700392 break;
393 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700394 if (outFd == STDOUT_FILENO) {
395 fwrite(buf, 1, len, stdout);
396 fflush(stdout);
397 } else {
398 adb_write(outFd, buf, len);
399 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700400 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700401 }
Yabin Cuid325e862014-11-17 14:48:25 -0800402
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700403 if (inFd == STDIN_FILENO) {
404 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700405#ifdef _WIN32
406 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
407 fatal_errno("could not restore stdin mode");
408 }
409#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700410 }
Yabin Cuid325e862014-11-17 14:48:25 -0800411
Spencer Lowb7dfb792015-05-22 16:48:31 -0700412#ifdef _WIN32
413 if (outFd == STDOUT_FILENO) {
414 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
415 fatal_errno("could not restore stdout mode");
416 }
417 }
418#endif
419
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700420 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700421 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700422}
423
David Pursell606835a2015-09-08 17:17:02 -0700424namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800425
David Pursell606835a2015-09-08 17:17:02 -0700426// Used to pass multiple values to the stdin read thread.
427struct StdinReadArgs {
428 int stdin_fd, write_fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700429 bool raw_stdin;
David Pursell606835a2015-09-08 17:17:02 -0700430 std::unique_ptr<ShellProtocol> protocol;
431};
432
433} // namespace
434
435// Loops to read from stdin and push the data to the given FD.
436// The argument should be a pointer to a StdinReadArgs object. This function
437// will take ownership of the object and delete it when finished.
438static void* stdin_read_thread(void* x) {
439 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
440 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800441
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700442 adb_thread_setname("stdin reader");
443
Josh Gao8dcdb572015-10-23 15:03:31 -0700444#ifndef __WIN32
445 // Mask SIGTTIN in case we're in a backgrounded process
446 sigset_t sigset;
447 sigemptyset(&sigset);
448 sigaddset(&sigset, SIGTTIN);
449 pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
450#endif
451
David Pursell606835a2015-09-08 17:17:02 -0700452 char raw_buffer[1024];
453 char* buffer_ptr = raw_buffer;
454 size_t buffer_size = sizeof(raw_buffer);
455 if (args->protocol) {
456 buffer_ptr = args->protocol->data();
457 buffer_size = args->protocol->data_capacity();
458 }
459
Elliott Hughesaa245492015-08-03 10:38:08 -0700460 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700461 // Use unix_read() rather than adb_read() for stdin.
462 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
463 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
464 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
David Pursell1ed57f02015-10-06 15:30:03 -0700465 if (r <= 0) {
466 // Only devices using the shell protocol know to close subprocess
467 // stdin. For older devices we want to just leave the connection
468 // open, otherwise an unpredictable amount of return data could
469 // be lost due to the FD closing before all data has been received.
470 if (args->protocol) {
471 args->protocol->Write(ShellProtocol::kIdCloseStdin, 0);
472 }
473 break;
474 }
475 // If we made stdin raw, check input for the "~." escape sequence. In
476 // this situation signals like Ctrl+C are sent remotely rather than
477 // interpreted locally so this provides an emergency out if the remote
478 // process starts ignoring the signal. SSH also does this, see the
479 // "escape characters" section on the ssh man page for more info.
480 if (args->raw_stdin) {
481 for (int n = 0; n < r; n++){
482 switch(buffer_ptr[n]) {
483 case '\n':
484 state = 1;
485 break;
486 case '\r':
487 state = 1;
488 break;
489 case '~':
490 if(state == 1) state++;
491 break;
492 case '.':
493 if(state == 2) {
494 stdin_raw_restore(args->stdin_fd);
495 fprintf(stderr,"\n* disconnect *\n");
496 exit(0);
497 }
498 default:
499 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800500 }
501 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800502 }
David Pursell606835a2015-09-08 17:17:02 -0700503 if (args->protocol) {
504 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
505 break;
506 }
507 } else {
508 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
509 break;
510 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800511 }
512 }
David Pursell606835a2015-09-08 17:17:02 -0700513
514 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800515}
516
David Pursell1ed57f02015-10-06 15:30:03 -0700517// Returns a shell service string with the indicated arguments and command.
518static std::string ShellServiceString(bool use_shell_protocol,
519 const std::string& type_arg,
520 const std::string& command) {
521 std::vector<std::string> args;
522 if (use_shell_protocol) {
523 args.push_back(kShellServiceArgShellProtocol);
524 }
525 if (!type_arg.empty()) {
526 args.push_back(type_arg);
527 }
528
529 // Shell service string can look like: shell[,arg1,arg2,...]:[command].
530 return android::base::StringPrintf("shell%s%s:%s",
531 args.empty() ? "" : ",",
532 android::base::Join(args, ',').c_str(),
533 command.c_str());
534}
535
536// Connects to a shell on the device and read/writes data.
537//
538// Note: currently this function doesn't properly clean up resources; the
539// FD connected to the adb server is never closed and the stdin read thread
540// may never exit.
541//
542// On success returns the remote exit code if |use_shell_protocol| is true,
543// 0 otherwise. On failure returns 1.
544static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
545 const std::string& command) {
546 std::string service_string = ShellServiceString(use_shell_protocol,
547 type_arg, command);
548
549 // Make local stdin raw if the device allocates a PTY, which happens if:
550 // 1. We are explicitly asking for a PTY shell, or
551 // 2. We don't specify shell type and are starting an interactive session.
552 bool raw_stdin = (type_arg == kShellServiceArgPty ||
553 (type_arg.empty() && command.empty()));
554
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700555 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700556 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700557 if (fd < 0) {
558 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800559 return 1;
560 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800561
David Pursell606835a2015-09-08 17:17:02 -0700562 StdinReadArgs* args = new StdinReadArgs;
563 if (!args) {
564 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700565 return 1;
566 }
David Pursell1ed57f02015-10-06 15:30:03 -0700567 args->stdin_fd = STDIN_FILENO;
David Pursell606835a2015-09-08 17:17:02 -0700568 args->write_fd = fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700569 args->raw_stdin = raw_stdin;
David Pursell606835a2015-09-08 17:17:02 -0700570 if (use_shell_protocol) {
571 args->protocol.reset(new ShellProtocol(args->write_fd));
572 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700573
David Pursell1ed57f02015-10-06 15:30:03 -0700574 if (raw_stdin) {
575 stdin_raw_init(STDIN_FILENO);
576 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800577
David Pursell606835a2015-09-08 17:17:02 -0700578 int exit_code = 0;
579 if (!adb_thread_create(stdin_read_thread, args)) {
580 PLOG(ERROR) << "error starting stdin read thread";
581 exit_code = 1;
582 delete args;
583 } else {
584 exit_code = read_and_dump(fd, use_shell_protocol);
585 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700586
David Pursell1ed57f02015-10-06 15:30:03 -0700587 if (raw_stdin) {
588 stdin_raw_restore(STDIN_FILENO);
589 }
590
591 // TODO(dpursell): properly exit stdin_read_thread and close |fd|.
592
David Pursell606835a2015-09-08 17:17:02 -0700593 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800594}
595
596
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700597static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800598 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700599 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800600 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700601
602 const char* prefix = "host";
603 if (type == kTransportUsb) {
604 prefix = "host-usb";
605 } else if (type == kTransportLocal) {
606 prefix = "host-local";
607 }
608 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800609}
610
David Pursell4e2fd362015-09-22 10:43:08 -0700611// Returns the FeatureSet for the indicated transport.
612static FeatureSet GetFeatureSet(TransportType transport_type,
David Pursell71c83122015-09-14 15:33:50 -0700613 const char* serial) {
David Pursell4e2fd362015-09-22 10:43:08 -0700614 std::string result, error;
615
616 if (adb_query(format_host_command("features", transport_type, serial),
617 &result, &error)) {
618 return StringToFeatureSet(result);
David Pursell71c83122015-09-14 15:33:50 -0700619 }
David Pursell4e2fd362015-09-22 10:43:08 -0700620 return FeatureSet();
David Pursell71c83122015-09-14 15:33:50 -0700621}
622
Elliott Hughes6452a892015-04-29 12:28:13 -0700623static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700624 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800625{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700626 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700627 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700628 if (fd < 0) {
629 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800630 return -1;
631 }
632
633 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800634 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800635
Elliott Hughes6452a892015-04-29 12:28:13 -0700636 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800637 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800638
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700639 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700640 const char* x = strrchr(service, ':');
641 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800642 }
643
Elliott Hughes6452a892015-04-29 12:28:13 -0700644 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800645 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700646 if (!WriteFdExactly(fd, ptr, xfer)) {
647 std::string error;
648 adb_status(fd, &error);
649 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800650 return -1;
651 }
652 sz -= xfer;
653 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700654 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100655 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800656 fflush(stdout);
657 }
658 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700659 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800660 printf("\n");
661 }
662
Elliott Hughese67f1f82015-04-30 17:32:03 -0700663 if (!adb_status(fd, &error)) {
664 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800665 return -1;
666 }
667
668 adb_close(fd);
669 return 0;
670}
671
Doug Zongker71fe5842014-06-26 15:35:36 -0700672#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
673
674/*
675 * The sideload-host protocol serves the data in a file (given on the
676 * command line) to the client, using a simple protocol:
677 *
678 * - The connect message includes the total number of bytes in the
679 * file and a block size chosen by us.
680 *
681 * - The other side sends the desired block number as eight decimal
682 * digits (eg "00000023" for block 23). Blocks are numbered from
683 * zero.
684 *
685 * - We send back the data of the requested block. The last block is
686 * likely to be partial; when the last block is requested we only
687 * send the part of the block that exists, it's not padded up to the
688 * block size.
689 *
690 * - When the other side sends "DONEDONE" instead of a block number,
691 * we hang up.
692 */
Elliott Hughes58305772015-04-17 13:57:15 -0700693static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700694 unsigned sz;
695 size_t xfer = 0;
696 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800697 int last_percent = -1;
698 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700699
700 printf("loading: '%s'", fn);
701 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800702 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700703 if (data == 0) {
704 printf("\n");
705 fprintf(stderr, "* cannot read '%s' *\n", fn);
706 return -1;
707 }
708
Elliott Hughes6452a892015-04-29 12:28:13 -0700709 std::string service =
710 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700711 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700712 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700713 if (fd < 0) {
714 // Try falling back to the older sideload method. Maybe this
715 // is an older device that doesn't support sideload-host.
716 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700717 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700718 goto done;
719 }
720
Spencer Lowf055c192015-01-25 14:40:16 -0800721 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700722
Elliott Hughesa7090b92015-04-17 17:03:59 -0700723 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700724 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800725 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700726 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700727 status = -1;
728 goto done;
729 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700730 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700731
Elliott Hughes6452a892015-04-29 12:28:13 -0700732 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700733 status = 0;
734 break;
735 }
736
Doug Zongker71fe5842014-06-26 15:35:36 -0700737 int block = strtol(buf, NULL, 10);
738
739 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
740 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700741 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700742 status = -1;
743 goto done;
744 }
745 uint8_t* start = data + offset;
746 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
747 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
748 if (offset_end > sz) {
749 to_write = sz - offset;
750 }
751
Dan Albertcc731cc2015-02-24 21:26:58 -0800752 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700753 adb_status(fd, &error);
754 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700755 status = -1;
756 goto done;
757 }
758 xfer += to_write;
759
760 // For normal OTA packages, we expect to transfer every byte
761 // twice, plus a bit of overhead (one read during
762 // verification, one read of each byte for installation, plus
763 // extra access to things like the zip central directory).
764 // This estimate of the completion becomes 100% when we've
765 // transferred ~2.13 (=100/47) times the package size.
766 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
767 if (percent != last_percent) {
768 printf("\rserving: '%s' (~%d%%) ", fn, percent);
769 fflush(stdout);
770 last_percent = percent;
771 }
772 }
773
Colin Cross6d6a8982014-07-07 14:12:41 -0700774 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700775
776 done:
777 if (fd >= 0) adb_close(fd);
778 free(data);
779 return status;
780}
781
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800782/**
783 * Run ppp in "notty" mode against a resource listed as the first parameter
784 * eg:
785 *
786 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
787 *
788 */
Elliott Hughes58305772015-04-17 13:57:15 -0700789static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800790#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800791 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
792 return -1;
793#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800794 if (argc < 2) {
795 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
796 argv[0]);
797
798 return 1;
799 }
800
Dan Albertbac34742015-02-25 17:51:28 -0800801 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700802 std::string error;
803 int fd = adb_connect(adb_service_name, &error);
804 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800805 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700806 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800807 return 1;
808 }
809
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700810 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800811
812 if (pid < 0) {
813 perror("from fork()");
814 return 1;
815 } else if (pid == 0) {
816 int err;
817 int i;
818 const char **ppp_args;
819
820 // copy args
821 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
822 ppp_args[0] = "pppd";
823 for (i = 2 ; i < argc ; i++) {
824 //argv[2] and beyond become ppp_args[1] and beyond
825 ppp_args[i - 1] = argv[i];
826 }
827 ppp_args[i-1] = NULL;
828
829 // child side
830
831 dup2(fd, STDIN_FILENO);
832 dup2(fd, STDOUT_FILENO);
833 adb_close(STDERR_FILENO);
834 adb_close(fd);
835
836 err = execvp("pppd", (char * const *)ppp_args);
837
838 if (err < 0) {
839 perror("execing pppd");
840 }
841 exit(-1);
842 } else {
843 // parent side
844
845 adb_close(fd);
846 return 0;
847 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800848#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800849}
850
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700851static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700852 // Was the caller vague about what they'd like us to wait for?
853 // If so, check they weren't more specific in their choice of transport type.
854 if (strcmp(service, "wait-for-device") == 0) {
855 if (t == kTransportUsb) {
856 service = "wait-for-usb";
857 } else if (t == kTransportLocal) {
858 service = "wait-for-local";
859 } else {
860 service = "wait-for-any";
861 }
862 }
863
864 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700865 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700866}
867
David Pursell70ef7b42015-09-30 13:35:42 -0700868// Connects to the device "shell" service with |command| and prints the
869// resulting output.
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700870static int send_shell_command(TransportType transport_type, const char* serial,
David Pursell70ef7b42015-09-30 13:35:42 -0700871 const std::string& command,
872 bool disable_shell_protocol) {
873 // Only use shell protocol if it's supported and the caller doesn't want
874 // to explicitly disable it.
875 bool use_shell_protocol = false;
876 if (!disable_shell_protocol) {
877 FeatureSet features = GetFeatureSet(transport_type, serial);
878 use_shell_protocol = CanUseFeature(features, kFeatureShell2);
879 }
880
881 std::string service_string = ShellServiceString(use_shell_protocol, "",
882 command);
883
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700884 int fd;
885 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700886 std::string error;
David Pursell70ef7b42015-09-30 13:35:42 -0700887 fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700888 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800889 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700890 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800891 fprintf(stderr,"- waiting for device -\n");
892 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700893 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800894 }
895
David Pursell70ef7b42015-09-30 13:35:42 -0700896 int exit_code = read_and_dump(fd, use_shell_protocol);
David Pursell71c83122015-09-14 15:33:50 -0700897
898 if (adb_close(fd) < 0) {
899 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700900 }
David Pursell71c83122015-09-14 15:33:50 -0700901
902 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800903}
904
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700905static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700906 char* log_tags = getenv("ANDROID_LOG_TAGS");
907 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800908
David Pursell70ef7b42015-09-30 13:35:42 -0700909 std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800910
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700911 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700912 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800913 }
914
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700915 --argc;
916 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700917 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700918 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800919 }
920
David Pursell70ef7b42015-09-30 13:35:42 -0700921 // No need for shell protocol with logcat, always disable for simplicity.
922 return send_shell_command(transport, serial, cmd, true);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800923}
924
Dan Albertbac34742015-02-25 17:51:28 -0800925static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700926 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700927
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700928 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700929 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700930 if (!strcmp("-f", argv[i])) {
931 if (i == argc-1) {
932 fprintf(stderr, "adb: -f passed with no filename\n");
933 return usage();
934 }
935 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700936 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700937 argv[i++] = argv[j++];
938 }
939 argc -= 2;
940 argv[argc] = NULL;
941 }
Christopher Tated2f54152011-04-21 12:53:28 -0700942 }
943
Christopher Tatebb86bc52011-08-22 17:12:08 -0700944 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
945 if (argc < 2) return usage();
946
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800947 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700948 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700949 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700950 if (outFd < 0) {
951 fprintf(stderr, "adb: unable to open file %s\n", filename);
952 return -1;
953 }
954
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700955 std::string cmd = "backup:";
956 --argc;
957 ++argv;
958 while (argc-- > 0) {
959 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700960 }
961
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700962 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700963 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700964 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700965 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700966 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700967 adb_close(outFd);
968 return -1;
969 }
970
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800971 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700972 copy_to_file(fd, outFd);
973
974 adb_close(fd);
975 adb_close(outFd);
976 return 0;
977}
978
Dan Albertbac34742015-02-25 17:51:28 -0800979static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700980 if (argc != 2) return usage();
981
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700982 const char* filename = argv[1];
983 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700984 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700985 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700986 return -1;
987 }
988
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700989 std::string error;
990 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700991 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700992 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700993 adb_close(tarFd);
994 return -1;
995 }
996
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800997 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700998 copy_to_file(tarFd, fd);
999
1000 adb_close(fd);
1001 adb_close(tarFd);
1002 return 0;
1003}
1004
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001005/* <hint> may be:
1006 * - A simple product name
1007 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001008 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1009 * e.g., "out/target/product/sooner"
1010 * - An absolute path to the PRODUCT_OUT dir
1011 * e.g., "/src/device/out/target/product/sooner"
1012 *
1013 * Given <hint>, try to construct an absolute path to the
1014 * ANDROID_PRODUCT_OUT dir.
1015 */
Elliott Hughes5c742702015-07-30 17:42:01 -07001016static std::string find_product_out_path(const std::string& hint) {
1017 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -07001018 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001019 }
1020
Elliott Hughes58305772015-04-17 13:57:15 -07001021 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -07001022 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -07001023 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001024 }
1025
Elliott Hughes58305772015-04-17 13:57:15 -07001026 // If there are any slashes in it, assume it's a relative path;
1027 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -07001028 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -07001029 std::string cwd;
1030 if (!getcwd(&cwd)) {
1031 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -07001032 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001033 }
Elliott Hughes5c742702015-07-30 17:42:01 -07001034 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 -08001035 }
1036
Elliott Hughes58305772015-04-17 13:57:15 -07001037 // It's a string without any slashes. Try to do something with it.
1038 //
1039 // Try to find the root of the build tree, and build a PRODUCT_OUT
1040 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -07001041 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -07001042 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -07001043 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -07001044 return "";
1045 }
Elliott Hughesa7090b92015-04-17 17:03:59 -07001046
1047 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -07001048 path += OS_PATH_SEPARATOR_STR;
1049 path += "out";
1050 path += OS_PATH_SEPARATOR_STR;
1051 path += "target";
1052 path += OS_PATH_SEPARATOR_STR;
1053 path += "product";
1054 path += OS_PATH_SEPARATOR_STR;
1055 path += hint;
1056 if (!directory_exists(path)) {
1057 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -07001058 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -07001059 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001060 }
Elliott Hughes58305772015-04-17 13:57:15 -07001061 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001062}
1063
Dan Albertbac34742015-02-25 17:51:28 -08001064static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -07001065 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -08001066 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001067 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001068 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001069
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001070 while (narg > 0) {
1071 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001072 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001073 } else if (!strcmp(*arg, "-a")) {
1074 *copy_attrs = 1;
1075 } else {
1076 break;
1077 }
Mark Lindner76f2a932014-03-11 17:55:59 -07001078 ++arg;
1079 --narg;
1080 }
1081
1082 if (narg > 0) {
1083 *path1 = *arg;
1084 ++arg;
1085 --narg;
1086 }
1087
1088 if (narg > 0) {
1089 *path2 = *arg;
1090 }
1091}
1092
Elliott Hughes6452a892015-04-29 12:28:13 -07001093static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001094 std::string error;
1095 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001096 if (fd < 0) {
1097 fprintf(stderr, "error: %s\n", error.c_str());
1098 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001099 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001100 read_and_dump(fd);
1101 adb_close(fd);
1102 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001103}
1104
Elliott Hughes6452a892015-04-29 12:28:13 -07001105static int adb_query_command(const std::string& command) {
1106 std::string result;
1107 std::string error;
1108 if (!adb_query(command, &result, &error)) {
1109 fprintf(stderr, "error: %s\n", error.c_str());
1110 return 1;
1111 }
1112 printf("%s\n", result.c_str());
1113 return 0;
1114}
1115
Spencer Lowa13df302015-09-07 16:20:13 -07001116// Disallow stdin, stdout, and stderr.
1117static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1118#ifdef _WIN32
1119 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1120 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1121 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1122 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1123#else
1124 return ack_reply_fd > 2;
1125#endif
1126}
1127
Elliott Hughesab52c182015-05-01 17:04:38 -07001128int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001129 int no_daemon = 0;
1130 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001131 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001132 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001133 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001134 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001135
Elliott Hughes58305772015-04-17 13:57:15 -07001136 // If defined, this should be an absolute path to
1137 // the directory containing all of the various system images
1138 // for a particular product. If not defined, and the adb
1139 // command requires this information, then the user must
1140 // specify the path using "-p".
1141 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1142 if (ANDROID_PRODUCT_OUT != nullptr) {
1143 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001144 }
1145 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1146
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001147 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001148 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001149 int server_port = DEFAULT_ADB_PORT;
1150 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001151 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001152 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001153 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001154 "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 +01001155 server_port_str);
1156 return usage();
1157 }
1158 }
1159
Elliott Hughes8d28e192015-10-07 14:55:10 -07001160 // We need to check for -d and -e before we look at $ANDROID_SERIAL.
1161 const char* serial = nullptr;
1162
Riley Andrews98f58e82014-12-05 17:37:24 -08001163 while (argc > 0) {
1164 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001165 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001166 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001167 no_daemon = 1;
1168 } else if (!strcmp(argv[0], "fork-server")) {
1169 /* this is a special flag used only when the ADB client launches the ADB Server */
1170 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001171 } else if (!strcmp(argv[0], "--reply-fd")) {
1172 if (argc < 2) return usage();
1173 const char* reply_fd_str = argv[1];
1174 argc--;
1175 argv++;
1176 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001177 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001178 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1179 return usage();
1180 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001181 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001182 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001183 if (argv[0][2] == '\0') {
1184 if (argc < 2) return usage();
1185 product = argv[1];
1186 argc--;
1187 argv++;
1188 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001189 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001190 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001191 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001192 if (gProductOutPath.empty()) {
1193 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001194 return usage();
1195 }
1196 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1197 if (isdigit(argv[0][2])) {
1198 serial = argv[0] + 2;
1199 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001200 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001201 serial = argv[1];
1202 argc--;
1203 argv++;
1204 }
1205 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001206 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001207 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001208 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001209 } else if (!strcmp(argv[0],"-a")) {
1210 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001211 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001212 const char *hostname = NULL;
1213 if (argv[0][2] == '\0') {
1214 if (argc < 2) return usage();
1215 hostname = argv[1];
1216 argc--;
1217 argv++;
1218 } else {
1219 hostname = argv[0] + 2;
1220 }
1221 adb_set_tcp_name(hostname);
1222
Riley Andrews98f58e82014-12-05 17:37:24 -08001223 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001224 if (argv[0][2] == '\0') {
1225 if (argc < 2) return usage();
1226 server_port_str = argv[1];
1227 argc--;
1228 argv++;
1229 } else {
1230 server_port_str = argv[0] + 2;
1231 }
1232 if (strlen(server_port_str) > 0) {
1233 server_port = (int) strtol(server_port_str, NULL, 0);
1234 if (server_port <= 0 || server_port > 65535) {
1235 fprintf(stderr,
1236 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1237 server_port_str);
1238 return usage();
1239 }
1240 } else {
1241 fprintf(stderr,
1242 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1243 return usage();
1244 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001245 } else {
1246 /* out of recognized modifiers and flags */
1247 break;
1248 }
1249 argc--;
1250 argv++;
1251 }
1252
Elliott Hughes8d28e192015-10-07 14:55:10 -07001253 // If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
1254 if (transport_type == kTransportAny && serial == nullptr) {
1255 serial = getenv("ANDROID_SERIAL");
1256 }
1257
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001258 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001259 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001260
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001261 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001262 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001263 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001264 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1265 return usage();
1266 }
1267 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001268 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001269 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001270 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001271 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001272 fprintf(stderr,"* could not start server *\n");
1273 }
1274 return r;
1275 }
1276
Riley Andrews98f58e82014-12-05 17:37:24 -08001277 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001278 return usage();
1279 }
1280
Riley Andrewsc8514c82014-12-05 17:32:46 -08001281 /* handle wait-for-* prefix */
1282 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001283 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001284
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001285 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001286 return 1;
1287 }
1288
Elliott Hughes2b101112015-05-04 19:29:32 -07001289 // Allow a command to be run after wait-for-device,
1290 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001291 if (argc == 1) {
1292 return 0;
1293 }
1294
1295 /* Fall through */
1296 argc--;
1297 argv++;
1298 }
1299
1300 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001301 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001302 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001303 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001304 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001305 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001306 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001307 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001308 fprintf(stderr, "Usage: adb devices [-l]\n");
1309 return 1;
1310 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001311
1312 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1313 printf("List of devices attached\n");
1314 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001315 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001316 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001317 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001318 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001319 return 1;
1320 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001321
1322 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1323 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001324 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001325 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001326 if (argc > 2) {
1327 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1328 return 1;
1329 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001330
1331 std::string query = android::base::StringPrintf("host:disconnect:%s",
1332 (argc == 2) ? argv[1] : "");
1333 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001334 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001335 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001336 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001337 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001338 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001339 char h = (argv[0][0] == 'h');
1340
David Pursell4e2fd362015-09-22 10:43:08 -07001341 FeatureSet features = GetFeatureSet(transport_type, serial);
1342
David Pursell70ef7b42015-09-30 13:35:42 -07001343 bool use_shell_protocol = CanUseFeature(features, kFeatureShell2);
David Pursell4e2fd362015-09-22 10:43:08 -07001344 if (!use_shell_protocol) {
1345 D("shell protocol not supported, using raw data transfer");
1346 } else {
1347 D("using shell protocol");
1348 }
1349
1350 // Parse shell-specific command-line options.
1351 // argv[0] is always "shell".
1352 --argc;
1353 ++argv;
1354 std::string shell_type_arg;
1355 while (argc) {
1356 if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
David Pursell70ef7b42015-09-30 13:35:42 -07001357 if (!CanUseFeature(features, kFeatureShell2)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001358 fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
1359 return 1;
1360 }
David Pursell70ef7b42015-09-30 13:35:42 -07001361 shell_type_arg = (argv[0][1] == 'T') ? kShellServiceArgRaw
1362 : kShellServiceArgPty;
1363 --argc;
1364 ++argv;
1365 } else if (!strcmp(argv[0], "-x")) {
1366 use_shell_protocol = false;
David Pursell4e2fd362015-09-22 10:43:08 -07001367 --argc;
1368 ++argv;
1369 } else {
1370 break;
1371 }
1372 }
David Pursell4e2fd362015-09-22 10:43:08 -07001373
David Pursell1ed57f02015-10-06 15:30:03 -07001374 std::string command;
1375 if (argc) {
1376 // We don't escape here, just like ssh(1). http://b/20564385.
1377 command = android::base::Join(
1378 std::vector<const char*>(argv, argv + argc), ' ');
1379 }
1380
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001381 if (h) {
1382 printf("\x1b[41;33m");
1383 fflush(stdout);
1384 }
1385
David Pursell1ed57f02015-10-06 15:30:03 -07001386 r = RemoteShell(use_shell_protocol, shell_type_arg, command);
1387
1388 if (h) {
1389 printf("\x1b[0m");
1390 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001391 }
1392
David Pursell1ed57f02015-10-06 15:30:03 -07001393 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001394 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001395 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001396 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001397
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001398 std::string cmd = "exec:";
1399 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001400 argc -= 2;
1401 argv += 2;
1402 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001403 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001404 }
1405
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001406 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001407 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001408 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001409 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001410 return -1;
1411 }
1412
1413 if (exec_in) {
1414 copy_to_file(STDIN_FILENO, fd);
1415 } else {
1416 copy_to_file(fd, STDOUT_FILENO);
1417 }
1418
1419 adb_close(fd);
1420 return 0;
1421 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001422 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001423 std::string error;
1424 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001425 if (fd == -2) {
1426 // Failed to make network connection to server. Don't output the
1427 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001428 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001429 // Successful exit code because the server is already "killed".
1430 return 0;
1431 } else if (fd == -1) {
1432 // Some other error.
1433 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001434 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001435 } else {
1436 // Successfully connected, kill command sent, okay status came back.
1437 // Server should exit() in a moment, if not already.
1438 adb_close(fd);
1439 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001440 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001441 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001442 else if (!strcmp(argv[0], "sideload")) {
1443 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001444 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001445 return 1;
1446 } else {
1447 return 0;
1448 }
1449 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001450 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1451 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1452 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001453 else if (!strcmp(argv[0], "remount") ||
1454 !strcmp(argv[0], "reboot") ||
1455 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001456 !strcmp(argv[0], "usb") ||
1457 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001458 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001459 !strcmp(argv[0], "disable-verity") ||
1460 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001461 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001462 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001463 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001464 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001465 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001466 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001467 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001468 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001469 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001470 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001471 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001472 if (argc != 1) return usage();
David Pursell70ef7b42015-09-30 13:35:42 -07001473 // No need for shell protocol with bugreport, always disable for
1474 // simplicity.
1475 return send_shell_command(transport_type, serial, "bugreport", true);
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001476 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001477 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001478 bool reverse = !strcmp(argv[0], "reverse");
1479 ++argv;
1480 --argc;
1481 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001482
1483 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001484 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001485 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001486 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001487 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001488 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001489 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001490 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001491 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001492 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001493 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001494 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001495 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001496 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001497 }
1498
Elliott Hughes424af022015-05-29 17:55:19 -07001499 std::string cmd;
1500 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001501 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001502 return adb_query_command(host_prefix + ":list-forward");
1503 } else if (strcmp(argv[0], "--remove-all") == 0) {
1504 if (argc != 1) return usage();
1505 cmd = host_prefix + ":killforward-all";
1506 } else if (strcmp(argv[0], "--remove") == 0) {
1507 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001508 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001509 cmd = host_prefix + ":killforward:" + argv[1];
1510 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1511 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001512 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001513 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1514 } else {
1515 // forward <local> <remote>
1516 if (argc != 2) return usage();
1517 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001518 }
1519
Elliott Hughes424af022015-05-29 17:55:19 -07001520 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001521 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001522 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001523 else if (!strcmp(argv[0], "ls")) {
1524 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001525 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001526 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001527 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001528 bool show_progress = false;
1529 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001530 const char* lpath = NULL, *rpath = NULL;
1531
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001532 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001533 if (!lpath || !rpath || copy_attrs != 0) return usage();
1534 return do_sync_push(lpath, rpath, show_progress) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001535 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001536 else if (!strcmp(argv[0], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001537 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001538 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001539 const char* rpath = NULL, *lpath = ".";
1540
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001541 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001542 if (!rpath) return usage();
1543 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001544 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001545 else if (!strcmp(argv[0], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001546 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001547 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001548 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001549 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001550 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001551 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001552 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001553 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001554 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001555 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001556 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001557 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001558 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001559 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001560 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001561 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001562 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001563 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001564 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001565 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001566 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001567 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001568 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001569 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001570 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001571 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001572 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001573 } else {
1574 return usage();
1575 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001576
Elliott Hughesd236d072015-04-21 10:17:07 -07001577 if (src != "" &&
1578 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001579 return usage();
1580 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001581
Elliott Hughes58305772015-04-17 13:57:15 -07001582 std::string system_src_path = product_file("system");
1583 std::string data_src_path = product_file("data");
1584 std::string vendor_src_path = product_file("vendor");
1585 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001586
Elliott Hughesaa245492015-08-03 10:38:08 -07001587 bool okay = true;
1588 if (okay && (src.empty() || src == "system")) {
1589 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001590 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001591 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1592 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001593 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001594 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1595 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001596 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001597 if (okay && (src.empty() || src == "data")) {
1598 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001599 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001600 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001601 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001602 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001603 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001604 !strcmp(argv[0],"get-serialno") ||
1605 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001606 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001607 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001608 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001609 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001610 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001611 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001612 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001613 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001614 return ppp(argc, argv);
1615 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001616 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001617 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001618 const int result = adb_connect("host:start-server", &error);
1619 if (result < 0) {
1620 fprintf(stderr, "error: %s\n", error.c_str());
1621 }
1622 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001623 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001624 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001625 return backup(argc, argv);
1626 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001627 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001628 return restore(argc, argv);
1629 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001630 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001631 if (argc < 2) return usage();
Yabin Cuiaed3c612015-09-22 15:52:57 -07001632 // Always print key generation information for keygen command.
1633 adb_trace_enable(AUTH);
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001634 return adb_auth_keygen(argv[1]);
1635 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001636 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001637 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001638 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001639 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001640 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001641 help();
1642 return 0;
1643 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001644 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001645 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001646 return 0;
1647 }
Dan Albert90d4b732015-05-20 18:58:41 -07001648 else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001649 // Only list the features common to both the adb client and the device.
1650 FeatureSet features = GetFeatureSet(transport_type, serial);
1651 for (const std::string& name : features) {
David Pursell70ef7b42015-09-30 13:35:42 -07001652 if (CanUseFeature(features, name)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001653 printf("%s\n", name.c_str());
1654 }
1655 }
1656 return 0;
Dan Albert90d4b732015-05-20 18:58:41 -07001657 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001658
1659 usage();
1660 return 1;
1661}
1662
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001663static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
David Pursell70ef7b42015-09-30 13:35:42 -07001664 std::string cmd = "pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001665
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001666 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001667 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001668 }
1669
David Pursell70ef7b42015-09-30 13:35:42 -07001670 // TODO(dpursell): add command-line arguments to install/uninstall to
1671 // manually disable shell protocol if needed.
1672 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001673}
1674
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001675static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001676 /* if the user choose the -k option, we refuse to do it until devices are
1677 out with the option to uninstall the remaining data somehow (adb/ui) */
1678 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1679 {
1680 printf(
1681 "The -k option uninstalls the application while retaining the data/cache.\n"
1682 "At the moment, there is no way to remove the remaining data.\n"
1683 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1684 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1685 return -1;
1686 }
1687
1688 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1689 return pm_command(transport, serial, argc, argv);
1690}
1691
Elliott Hughes5c742702015-07-30 17:42:01 -07001692static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
David Pursell70ef7b42015-09-30 13:35:42 -07001693 std::string cmd = "rm -f " + escape_arg(filename);
1694 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001695}
1696
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001697static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001698 static const char *const DATA_DEST = "/data/local/tmp/%s";
1699 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001700 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001701 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001702 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001703
1704 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001705 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001706 where = SD_DEST;
1707 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001708 }
1709
Jeff Sharkey960df972014-06-09 17:30:57 -07001710 // Find last APK argument.
1711 // All other arguments passed through verbatim.
1712 int last_apk = -1;
1713 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001714 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001715 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001716 if (dot && !strcasecmp(dot, ".apk")) {
1717 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1718 fprintf(stderr, "Invalid APK file: %s\n", file);
1719 return -1;
1720 }
1721
1722 last_apk = i;
1723 break;
1724 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001725 }
1726
Jeff Sharkey960df972014-06-09 17:30:57 -07001727 if (last_apk == -1) {
1728 fprintf(stderr, "Missing APK file\n");
1729 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001730 }
1731
Elliott Hughesaa245492015-08-03 10:38:08 -07001732 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001733 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001734 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001735 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1736 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1737 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001738
Kenny Root60733e92012-03-26 16:14:02 -07001739cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001740 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001741 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001742}
1743
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001744static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001745 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001746{
Jeff Sharkey960df972014-06-09 17:30:57 -07001747 int i;
1748 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001749 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001750
1751 // Find all APK arguments starting at end.
1752 // All other arguments passed through verbatim.
1753 int first_apk = -1;
1754 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001755 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001756 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001757 if (dot && !strcasecmp(dot, ".apk")) {
1758 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1759 fprintf(stderr, "Invalid APK file: %s\n", file);
1760 return -1;
1761 }
1762
1763 total_size += sb.st_size;
1764 first_apk = i;
1765 } else {
1766 break;
1767 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001768 }
1769
Jeff Sharkey960df972014-06-09 17:30:57 -07001770 if (first_apk == -1) {
1771 fprintf(stderr, "Missing APK file\n");
1772 return 1;
1773 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001774
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001775 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001776 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001777 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001778 }
1779
1780 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001781 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001782 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001783 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001784 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001785 return -1;
1786 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001787 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001788 read_status_line(fd, buf, sizeof(buf));
1789 adb_close(fd);
1790
1791 int session_id = -1;
1792 if (!strncmp("Success", buf, 7)) {
1793 char* start = strrchr(buf, '[');
1794 char* end = strrchr(buf, ']');
1795 if (start && end) {
1796 *end = '\0';
1797 session_id = strtol(start + 1, NULL, 10);
1798 }
1799 }
1800 if (session_id < 0) {
1801 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001802 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001803 return -1;
1804 }
1805
1806 // Valid session, now stream the APKs
1807 int success = 1;
1808 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001809 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001810 if (stat(file, &sb) == -1) {
1811 fprintf(stderr, "Failed to stat %s\n", file);
1812 success = 0;
1813 goto finalize_session;
1814 }
1815
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001816 std::string cmd = android::base::StringPrintf(
1817 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001818 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001819
1820 int localFd = adb_open(file, O_RDONLY);
1821 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001822 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001823 success = 0;
1824 goto finalize_session;
1825 }
1826
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001827 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001828 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001829 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001830 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001831 adb_close(localFd);
1832 success = 0;
1833 goto finalize_session;
1834 }
1835
1836 copy_to_file(localFd, remoteFd);
1837 read_status_line(remoteFd, buf, sizeof(buf));
1838
1839 adb_close(localFd);
1840 adb_close(remoteFd);
1841
1842 if (strncmp("Success", buf, 7)) {
1843 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001844 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001845 success = 0;
1846 goto finalize_session;
1847 }
1848 }
1849
1850finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001851 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001852 std::string service =
1853 android::base::StringPrintf("exec:pm install-%s %d",
1854 success ? "commit" : "abandon", session_id);
1855 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001856 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001857 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001858 return -1;
1859 }
1860 read_status_line(fd, buf, sizeof(buf));
1861 adb_close(fd);
1862
1863 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001864 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001865 return 0;
1866 } else {
1867 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001868 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001869 return -1;
1870 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001871}