blob: bc5ba38a006674c71f9d909e73b091c85a7d33bd [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG ADB
Dan Albert33134262015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Dan Albert76649012015-02-24 15:51:19 -080021#include <assert.h>
22#include <ctype.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <errno.h>
Elliott Hughes2940ccf2015-04-17 14:07:52 -070024#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <limits.h>
26#include <stdarg.h>
Dan Albert76649012015-02-24 15:51:19 -080027#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031#include <sys/stat.h>
Dan Albert76649012015-02-24 15:51:19 -080032#include <sys/types.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
David Pursell606835a2015-09-08 17:17:02 -070034#include <memory>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070035#include <string>
36
David Pursell606835a2015-09-08 17:17:02 -070037#include <base/logging.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070038#include <base/stringprintf.h>
David Pursell4e2fd362015-09-22 10:43:08 -070039#include <base/strings.h>
Elliott Hughes2baae3a2015-04-17 10:59:34 -070040
Yabin Cuid325e862014-11-17 14:48:25 -080041#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080042#include <termios.h>
Dan Albert76649012015-02-24 15:51:19 -080043#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080044#endif
45
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046#include "adb.h"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -080047#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080048#include "adb_client.h"
49#include "adb_io.h"
Elliott Hughes58305772015-04-17 13:57:15 -070050#include "adb_utils.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051#include "file_sync_service.h"
David Pursell70ef7b42015-09-30 13:35:42 -070052#include "services.h"
David Pursell606835a2015-09-08 17:17:02 -070053#include "shell_service.h"
54#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080055
Elliott Hughes3bd73c12015-05-05 13:10:43 -070056static int install_app(TransportType t, const char* serial, int argc, const char** argv);
57static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
58static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080059
Elliott Hughes58305772015-04-17 13:57:15 -070060static std::string gProductOutPath;
Matt Gumbeld7b33082012-11-14 10:16:17 -080061extern int gListenAll;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080062
Elliott Hughes58305772015-04-17 13:57:15 -070063static std::string product_file(const char *extra) {
64 if (gProductOutPath.empty()) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080065 fprintf(stderr, "adb: Product directory not specified; "
66 "use -p or define ANDROID_PRODUCT_OUT\n");
67 exit(1);
68 }
69
Elliott Hughes58305772015-04-17 13:57:15 -070070 return android::base::StringPrintf("%s%s%s",
71 gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080072}
73
Elliott Hughes58305772015-04-17 13:57:15 -070074static void help() {
Elliott Hughes42ae2602015-08-12 08:32:10 -070075 fprintf(stderr, "%s\n", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080076 fprintf(stderr,
Matt Gumbeld7b33082012-11-14 10:16:17 -080077 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 " -d - directs command to the only connected USB device\n"
79 " returns an error if more than one USB device is present.\n"
80 " -e - directs command to the only running emulator.\n"
81 " returns an error if more than one emulator is running.\n"
Scott Andersone109d262012-04-20 11:21:14 -070082 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070083 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughes31dbed72009-10-07 15:38:53 -070084 " environment variable.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080085 " -p <product name or path> - simple product name like 'sooner', or\n"
86 " a relative/absolute path to a product\n"
87 " out directory like 'out/target/product/sooner'.\n"
88 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
89 " environment variable is used, which must\n"
90 " be an absolute path.\n"
Matt Gumbeld7b33082012-11-14 10:16:17 -080091 " -H - Name of adb server host (default: localhost)\n"
92 " -P - Port of adb server (default: 5037)\n"
Scott Andersone109d262012-04-20 11:21:14 -070093 " devices [-l] - list all connected devices\n"
Scott Anderson2ca3e6b2012-05-30 18:11:27 -070094 " ('-l' will also list device qualifiers)\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -040095 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
96 " Port 5555 is used by default if no port number is specified.\n"
97 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
98 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischer6715a432011-04-26 12:46:05 +020099 " Using this command with no additional arguments\n"
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400100 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800101 "\n"
102 "device commands:\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700103 " adb push [-p] <local> <remote>\n"
104 " - copy file/dir to device\n"
105 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700106 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner76f2a932014-03-11 17:55:59 -0700107 " - copy file/dir from device\n"
108 " ('-p' to display the transfer progress)\n"
Lajos Molnarde8ff4a2013-04-19 12:41:09 -0700109 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800110 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnam705c9442010-02-22 08:36:49 -0600111 " (-l means list but don't copy)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700112 " adb shell [-Ttx] - run remote shell interactively\n"
113 " adb shell [-Ttx] <command> - run remote shell command\n"
David Pursell4e2fd362015-09-22 10:43:08 -0700114 " (-T disables PTY allocation)\n"
115 " (-t forces PTY allocation)\n"
David Pursell70ef7b42015-09-30 13:35:42 -0700116 " (-x disables remote exit codes and stdout/stderr separation)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800117 " adb emu <command> - run emulator console command\n"
118 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100119 " adb forward --list - list all forward socket connections.\n"
120 " the format is a list of lines with the following format:\n"
121 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800122 " adb forward <local> <remote> - forward socket connections\n"
123 " forward specs are one of: \n"
124 " tcp:<port>\n"
125 " localabstract:<unix domain socket name>\n"
126 " localreserved:<unix domain socket name>\n"
127 " localfilesystem:<unix domain socket name>\n"
128 " dev:<character device name>\n"
129 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +0100130 " adb forward --no-rebind <local> <remote>\n"
131 " - same as 'adb forward <local> <remote>' but fails\n"
132 " if <local> is already forwarded\n"
133 " adb forward --remove <local> - remove a specific forward socket connection\n"
134 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner25258692013-03-21 21:07:42 +0100135 " adb reverse --list - list all reverse socket connections from device\n"
136 " adb reverse <remote> <local> - reverse socket connections\n"
137 " reverse specs are one of:\n"
138 " tcp:<port>\n"
139 " localabstract:<unix domain socket name>\n"
140 " localreserved:<unix domain socket name>\n"
141 " localfilesystem:<unix domain socket name>\n"
142 " adb reverse --norebind <remote> <local>\n"
143 " - same as 'adb reverse <remote> <local>' but fails\n"
144 " if <remote> is already reversed.\n"
145 " adb reverse --remove <remote>\n"
146 " - remove a specific reversed socket connection\n"
147 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800148 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900149 " adb install [-lrtsdg] <file>\n"
Svetoslav23d84072015-06-01 16:02:50 -0700150 " - push this package file to the device and install it\n"
151 " (-l: forward lock application)\n"
152 " (-r: replace existing application)\n"
153 " (-t: allow test packages)\n"
154 " (-s: install application on sdcard)\n"
155 " (-d: allow version code downgrade)\n"
156 " (-g: grant all runtime permissions)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900157 " adb install-multiple [-lrtsdpg] <file...>\n"
Anonymous Coward4474ac42012-04-24 10:43:41 -0700158 " - push this package file to the device and install it\n"
Jeff Sharkey960df972014-06-09 17:30:57 -0700159 " (-l: forward lock application)\n"
160 " (-r: replace existing application)\n"
161 " (-t: allow test packages)\n"
162 " (-s: install application on sdcard)\n"
163 " (-d: allow version code downgrade)\n"
164 " (-p: partial application install)\n"
Lorenzo Colitti0b3baac2015-05-28 12:03:44 +0900165 " (-g: grant all runtime permissions)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800166 " adb uninstall [-k] <package> - remove this app package from the device\n"
167 " ('-k' means keep the data and cache directories)\n"
168 " adb bugreport - return all information from the device\n"
169 " that should be included in a bug report.\n"
170 "\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800171 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate56885092011-10-03 18:27:01 -0700172 " - write an archive of the device's data to <file>.\n"
173 " If no -f option is supplied then the data is written\n"
174 " to \"backup.ab\" in the current directory.\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700175 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700176 " in the archive; the default is noapk.)\n"
Christopher Tate0c06eb52013-03-06 16:40:52 -0800177 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
178 " (aka .obb) files associated with each application; the default\n"
179 " is noobb.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700180 " (-shared|-noshared enable/disable backup of the device's\n"
181 " shared storage / SD card contents; the default is noshared.)\n"
182 " (-all means to back up all installed applications)\n"
Christopher Tate56885092011-10-03 18:27:01 -0700183 " (-system|-nosystem toggles whether -all automatically includes\n"
184 " system applications; the default is to include system apps)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700185 " (<packages...> is the list of applications to be backed up. If\n"
186 " the -all or -shared flags are passed, then the package\n"
Christopher Tate56885092011-10-03 18:27:01 -0700187 " list is optional. Applications explicitly given on the\n"
188 " command line will be included even if -nosystem would\n"
189 " ordinarily cause them to be omitted.)\n"
Christopher Tated2f54152011-04-21 12:53:28 -0700190 "\n"
Christopher Tatede034ec2011-08-09 17:05:29 -0700191 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tate702967a2011-05-17 15:52:54 -0700192 "\n"
Paul Lawrence982089d2014-12-03 15:31:57 -0800193 " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n"
194 " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n"
Nick Kralevichbea3f9c2014-11-13 15:17:29 -0800195 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
196 " and the public key is stored in <file>.pub. Any existing files\n"
197 " are overwritten.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800198 " adb help - show this help message\n"
199 " adb version - show version num\n"
200 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800201 "scripting:\n"
202 " adb wait-for-device - block until device is online\n"
203 " adb start-server - ensure that there is a server running\n"
204 " adb kill-server - kill the server if it is running\n"
205 " adb get-state - prints: offline | bootloader | device\n"
206 " adb get-serialno - prints: <serial-number>\n"
Scott Andersone109d262012-04-20 11:21:14 -0700207 " adb get-devpath - prints: <device-path>\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000208 " 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 -0700209 " adb reboot [bootloader|recovery]\n"
210 " - reboots the device, optionally into the bootloader or recovery program.\n"
211 " adb reboot sideload - reboots the device into the sideload mode in recovery program (adb root required).\n"
212 " adb reboot sideload-auto-reboot\n"
213 " - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700214 " adb sideload <file> - sideloads the given package\n"
Mike Lockwoodff196702009-08-24 15:58:40 -0700215 " adb root - restarts the adbd daemon with root permissions\n"
Dan Pasanen98858812014-10-06 12:57:20 -0500216 " adb unroot - restarts the adbd daemon without root permissions\n"
Romain Guy311add42009-12-14 14:42:17 -0800217 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrenceec900bb2014-10-09 14:22:49 +0000218 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700219 "\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800220 "networking:\n"
221 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootc9891992009-06-08 14:40:30 -0500222 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800223 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
224 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
225 "\n"
226 "adb sync notes: adb sync [ <directory> ]\n"
227 " <localdir> can be interpreted in several ways:\n"
228 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000229 " - 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 -0800230 "\n"
Elliott Hughesec7a6672015-03-16 21:58:32 +0000231 " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800232 " is updated.\n"
Timcd643152010-02-16 20:18:29 +0000233 "\n"
Elliott Hughes7e067cf2015-06-12 14:26:29 -0700234 "environment variables:\n"
Timcd643152010-02-16 20:18:29 +0000235 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
236 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
237 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
238 " 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 -0800239 );
240}
241
Elliott Hughes58305772015-04-17 13:57:15 -0700242static int usage() {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800243 help();
244 return 1;
245}
246
Yabin Cuid325e862014-11-17 14:48:25 -0800247#if defined(_WIN32)
248
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700249// Implemented in sysdeps_win32.cpp.
Spencer Low50184062015-03-01 15:06:21 -0800250void stdin_raw_init(int fd);
251void stdin_raw_restore(int fd);
Yabin Cuid325e862014-11-17 14:48:25 -0800252
253#else
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100254static termios g_saved_terminal_state;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800255
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100256static void stdin_raw_init(int fd) {
257 if (tcgetattr(fd, &g_saved_terminal_state)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800258
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100259 termios tio;
260 if (tcgetattr(fd, &tio)) return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800261
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100262 cfmakeraw(&tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800263
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100264 // No timeout but request at least one character per read.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800265 tio.c_cc[VTIME] = 0;
266 tio.c_cc[VMIN] = 1;
267
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100268 tcsetattr(fd, TCSAFLUSH, &tio);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800269}
270
Alistair Buxtondfa09fd2013-03-01 22:16:41 +0100271static void stdin_raw_restore(int fd) {
272 tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800273}
274#endif
275
David Pursell606835a2015-09-08 17:17:02 -0700276// Reads from |fd| and prints received data. If |use_shell_protocol| is true
277// this expects that incoming data will use the shell protocol, in which case
278// stdout/stderr are routed independently and the remote exit code will be
279// returned.
280static int read_and_dump(int fd, bool use_shell_protocol=false) {
281 int exit_code = 0;
282 std::unique_ptr<ShellProtocol> protocol;
283 int length = 0;
284 FILE* outfile = stdout;
285
286 char raw_buffer[BUFSIZ];
287 char* buffer_ptr = raw_buffer;
288 if (use_shell_protocol) {
289 protocol.reset(new ShellProtocol(fd));
290 if (!protocol) {
291 LOG(ERROR) << "failed to allocate memory for ShellProtocol object";
292 return 1;
293 }
294 buffer_ptr = protocol->data();
295 }
296
Elliott Hughes5677c232015-05-07 23:37:40 -0700297 while (fd >= 0) {
David Pursell606835a2015-09-08 17:17:02 -0700298 if (use_shell_protocol) {
299 if (!protocol->Read()) {
300 break;
301 }
302 switch (protocol->id()) {
303 case ShellProtocol::kIdStdout:
304 outfile = stdout;
305 break;
306 case ShellProtocol::kIdStderr:
307 outfile = stderr;
308 break;
309 case ShellProtocol::kIdExit:
310 exit_code = protocol->data()[0];
311 continue;
312 default:
313 continue;
314 }
315 length = protocol->data_length();
316 } else {
317 D("read_and_dump(): pre adb_read(fd=%d)", fd);
318 length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
319 D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
320 if (length <= 0) {
321 break;
322 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800323 }
324
David Pursell606835a2015-09-08 17:17:02 -0700325 fwrite(buffer_ptr, 1, length, outfile);
326 fflush(outfile);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800327 }
David Pursell606835a2015-09-08 17:17:02 -0700328
329 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800330}
331
Jeff Sharkey960df972014-06-09 17:30:57 -0700332static void read_status_line(int fd, char* buf, size_t count)
333{
334 count--;
335 while (count > 0) {
336 int len = adb_read(fd, buf, count);
Elliott Hughes8fcd8bc2015-08-25 10:59:45 -0700337 if (len <= 0) {
Jeff Sharkey960df972014-06-09 17:30:57 -0700338 break;
339 }
340
341 buf += len;
342 count -= len;
343 }
344 *buf = '\0';
345}
346
Christopher Tated2f54152011-04-21 12:53:28 -0700347static void copy_to_file(int inFd, int outFd) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700348 const size_t BUFSIZE = 32 * 1024;
349 char* buf = (char*) malloc(BUFSIZE);
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700350 if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
Christopher Tated2f54152011-04-21 12:53:28 -0700351 int len;
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700352 long total = 0;
Spencer Lowb7dfb792015-05-22 16:48:31 -0700353#ifdef _WIN32
354 int old_stdin_mode = -1;
355 int old_stdout_mode = -1;
356#endif
Christopher Tated2f54152011-04-21 12:53:28 -0700357
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700358 D("copy_to_file(%d -> %d)", inFd, outFd);
Yabin Cuid325e862014-11-17 14:48:25 -0800359
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700360 if (inFd == STDIN_FILENO) {
361 stdin_raw_init(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700362#ifdef _WIN32
363 old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY);
364 if (old_stdin_mode == -1) {
365 fatal_errno("could not set stdin to binary");
366 }
367#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700368 }
Yabin Cuid325e862014-11-17 14:48:25 -0800369
Spencer Lowb7dfb792015-05-22 16:48:31 -0700370#ifdef _WIN32
371 if (outFd == STDOUT_FILENO) {
372 old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY);
373 if (old_stdout_mode == -1) {
374 fatal_errno("could not set stdout to binary");
375 }
376 }
377#endif
378
Elliott Hughesa7090b92015-04-17 17:03:59 -0700379 while (true) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700380 if (inFd == STDIN_FILENO) {
381 len = unix_read(inFd, buf, BUFSIZE);
382 } else {
383 len = adb_read(inFd, buf, BUFSIZE);
384 }
Christopher Tated2f54152011-04-21 12:53:28 -0700385 if (len == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700386 D("copy_to_file() : read 0 bytes; exiting");
Christopher Tated2f54152011-04-21 12:53:28 -0700387 break;
388 }
389 if (len < 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700390 D("copy_to_file(): read failed: %s", strerror(errno));
Christopher Tated2f54152011-04-21 12:53:28 -0700391 break;
392 }
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700393 if (outFd == STDOUT_FILENO) {
394 fwrite(buf, 1, len, stdout);
395 fflush(stdout);
396 } else {
397 adb_write(outFd, buf, len);
398 }
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700399 total += len;
Christopher Tated2f54152011-04-21 12:53:28 -0700400 }
Yabin Cuid325e862014-11-17 14:48:25 -0800401
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700402 if (inFd == STDIN_FILENO) {
403 stdin_raw_restore(STDIN_FILENO);
Spencer Lowb7dfb792015-05-22 16:48:31 -0700404#ifdef _WIN32
405 if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
406 fatal_errno("could not restore stdin mode");
407 }
408#endif
Jeff Sharkey5d9d4342014-05-26 18:30:43 -0700409 }
Yabin Cuid325e862014-11-17 14:48:25 -0800410
Spencer Lowb7dfb792015-05-22 16:48:31 -0700411#ifdef _WIN32
412 if (outFd == STDOUT_FILENO) {
413 if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
414 fatal_errno("could not restore stdout mode");
415 }
416 }
417#endif
418
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700419 D("copy_to_file() finished after %lu bytes", total);
Christopher Tate5b811fa2011-06-10 11:38:37 -0700420 free(buf);
Christopher Tated2f54152011-04-21 12:53:28 -0700421}
422
David Pursell606835a2015-09-08 17:17:02 -0700423namespace {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800424
David Pursell606835a2015-09-08 17:17:02 -0700425// Used to pass multiple values to the stdin read thread.
426struct StdinReadArgs {
427 int stdin_fd, write_fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700428 bool raw_stdin;
David Pursell606835a2015-09-08 17:17:02 -0700429 std::unique_ptr<ShellProtocol> protocol;
430};
431
432} // namespace
433
434// Loops to read from stdin and push the data to the given FD.
435// The argument should be a pointer to a StdinReadArgs object. This function
436// will take ownership of the object and delete it when finished.
437static void* stdin_read_thread(void* x) {
438 std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
439 int state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800440
Siva Velusamy49ee7cf2015-08-28 16:37:29 -0700441 adb_thread_setname("stdin reader");
442
David Pursell606835a2015-09-08 17:17:02 -0700443 char raw_buffer[1024];
444 char* buffer_ptr = raw_buffer;
445 size_t buffer_size = sizeof(raw_buffer);
446 if (args->protocol) {
447 buffer_ptr = args->protocol->data();
448 buffer_size = args->protocol->data_capacity();
449 }
450
Elliott Hughesaa245492015-08-03 10:38:08 -0700451 while (true) {
David Pursell606835a2015-09-08 17:17:02 -0700452 // Use unix_read() rather than adb_read() for stdin.
453 D("stdin_read_thread(): pre unix_read(fdi=%d,...)", args->stdin_fd);
454 int r = unix_read(args->stdin_fd, buffer_ptr, buffer_size);
455 D("stdin_read_thread(): post unix_read(fdi=%d,...)", args->stdin_fd);
David Pursell1ed57f02015-10-06 15:30:03 -0700456 if (r <= 0) {
457 // Only devices using the shell protocol know to close subprocess
458 // stdin. For older devices we want to just leave the connection
459 // open, otherwise an unpredictable amount of return data could
460 // be lost due to the FD closing before all data has been received.
461 if (args->protocol) {
462 args->protocol->Write(ShellProtocol::kIdCloseStdin, 0);
463 }
464 break;
465 }
466 // If we made stdin raw, check input for the "~." escape sequence. In
467 // this situation signals like Ctrl+C are sent remotely rather than
468 // interpreted locally so this provides an emergency out if the remote
469 // process starts ignoring the signal. SSH also does this, see the
470 // "escape characters" section on the ssh man page for more info.
471 if (args->raw_stdin) {
472 for (int n = 0; n < r; n++){
473 switch(buffer_ptr[n]) {
474 case '\n':
475 state = 1;
476 break;
477 case '\r':
478 state = 1;
479 break;
480 case '~':
481 if(state == 1) state++;
482 break;
483 case '.':
484 if(state == 2) {
485 stdin_raw_restore(args->stdin_fd);
486 fprintf(stderr,"\n* disconnect *\n");
487 exit(0);
488 }
489 default:
490 state = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800491 }
492 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800493 }
David Pursell606835a2015-09-08 17:17:02 -0700494 if (args->protocol) {
495 if (!args->protocol->Write(ShellProtocol::kIdStdin, r)) {
496 break;
497 }
498 } else {
499 if (!WriteFdExactly(args->write_fd, buffer_ptr, r)) {
500 break;
501 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800502 }
503 }
David Pursell606835a2015-09-08 17:17:02 -0700504
505 return nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800506}
507
David Pursell1ed57f02015-10-06 15:30:03 -0700508// Returns a shell service string with the indicated arguments and command.
509static std::string ShellServiceString(bool use_shell_protocol,
510 const std::string& type_arg,
511 const std::string& command) {
512 std::vector<std::string> args;
513 if (use_shell_protocol) {
514 args.push_back(kShellServiceArgShellProtocol);
515 }
516 if (!type_arg.empty()) {
517 args.push_back(type_arg);
518 }
519
520 // Shell service string can look like: shell[,arg1,arg2,...]:[command].
521 return android::base::StringPrintf("shell%s%s:%s",
522 args.empty() ? "" : ",",
523 android::base::Join(args, ',').c_str(),
524 command.c_str());
525}
526
527// Connects to a shell on the device and read/writes data.
528//
529// Note: currently this function doesn't properly clean up resources; the
530// FD connected to the adb server is never closed and the stdin read thread
531// may never exit.
532//
533// On success returns the remote exit code if |use_shell_protocol| is true,
534// 0 otherwise. On failure returns 1.
535static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
536 const std::string& command) {
537 std::string service_string = ShellServiceString(use_shell_protocol,
538 type_arg, command);
539
540 // Make local stdin raw if the device allocates a PTY, which happens if:
541 // 1. We are explicitly asking for a PTY shell, or
542 // 2. We don't specify shell type and are starting an interactive session.
543 bool raw_stdin = (type_arg == kShellServiceArgPty ||
544 (type_arg.empty() && command.empty()));
545
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700546 std::string error;
David Pursell4e2fd362015-09-22 10:43:08 -0700547 int fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700548 if (fd < 0) {
549 fprintf(stderr,"error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800550 return 1;
551 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800552
David Pursell606835a2015-09-08 17:17:02 -0700553 StdinReadArgs* args = new StdinReadArgs;
554 if (!args) {
555 LOG(ERROR) << "couldn't allocate StdinReadArgs object";
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700556 return 1;
557 }
David Pursell1ed57f02015-10-06 15:30:03 -0700558 args->stdin_fd = STDIN_FILENO;
David Pursell606835a2015-09-08 17:17:02 -0700559 args->write_fd = fd;
David Pursell1ed57f02015-10-06 15:30:03 -0700560 args->raw_stdin = raw_stdin;
David Pursell606835a2015-09-08 17:17:02 -0700561 if (use_shell_protocol) {
562 args->protocol.reset(new ShellProtocol(args->write_fd));
563 }
Elliott Hughesdc3b4592015-04-21 19:39:52 -0700564
David Pursell1ed57f02015-10-06 15:30:03 -0700565 if (raw_stdin) {
566 stdin_raw_init(STDIN_FILENO);
567 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800568
David Pursell606835a2015-09-08 17:17:02 -0700569 int exit_code = 0;
570 if (!adb_thread_create(stdin_read_thread, args)) {
571 PLOG(ERROR) << "error starting stdin read thread";
572 exit_code = 1;
573 delete args;
574 } else {
575 exit_code = read_and_dump(fd, use_shell_protocol);
576 }
Elliott Hughes9b0f3542015-05-05 13:41:21 -0700577
David Pursell1ed57f02015-10-06 15:30:03 -0700578 if (raw_stdin) {
579 stdin_raw_restore(STDIN_FILENO);
580 }
581
582 // TODO(dpursell): properly exit stdin_read_thread and close |fd|.
583
David Pursell606835a2015-09-08 17:17:02 -0700584 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800585}
586
587
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700588static std::string format_host_command(const char* command, TransportType type, const char* serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800589 if (serial) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700590 return android::base::StringPrintf("host-serial:%s:%s", serial, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800591 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700592
593 const char* prefix = "host";
594 if (type == kTransportUsb) {
595 prefix = "host-usb";
596 } else if (type == kTransportLocal) {
597 prefix = "host-local";
598 }
599 return android::base::StringPrintf("%s:%s", prefix, command);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800600}
601
David Pursell4e2fd362015-09-22 10:43:08 -0700602// Returns the FeatureSet for the indicated transport.
603static FeatureSet GetFeatureSet(TransportType transport_type,
David Pursell71c83122015-09-14 15:33:50 -0700604 const char* serial) {
David Pursell4e2fd362015-09-22 10:43:08 -0700605 std::string result, error;
606
607 if (adb_query(format_host_command("features", transport_type, serial),
608 &result, &error)) {
609 return StringToFeatureSet(result);
David Pursell71c83122015-09-14 15:33:50 -0700610 }
David Pursell4e2fd362015-09-22 10:43:08 -0700611 return FeatureSet();
David Pursell71c83122015-09-14 15:33:50 -0700612}
613
Elliott Hughes6452a892015-04-29 12:28:13 -0700614static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700615 bool show_progress)
Doug Zongker447f0612012-01-09 14:54:53 -0800616{
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700617 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700618 int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700619 if (fd < 0) {
620 fprintf(stderr,"error: %s\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800621 return -1;
622 }
623
624 int opt = CHUNK_SIZE;
Spencer Lowf055c192015-01-25 14:40:16 -0800625 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker447f0612012-01-09 14:54:53 -0800626
Elliott Hughes6452a892015-04-29 12:28:13 -0700627 unsigned total = sz;
Dan Albertbac34742015-02-25 17:51:28 -0800628 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
Doug Zongker447f0612012-01-09 14:54:53 -0800629
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700630 if (show_progress) {
Elliott Hughes3e7048c2015-07-27 21:21:39 -0700631 const char* x = strrchr(service, ':');
632 if (x) service = x + 1;
Doug Zongker447f0612012-01-09 14:54:53 -0800633 }
634
Elliott Hughes6452a892015-04-29 12:28:13 -0700635 while (sz > 0) {
Doug Zongker447f0612012-01-09 14:54:53 -0800636 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700637 if (!WriteFdExactly(fd, ptr, xfer)) {
638 std::string error;
639 adb_status(fd, &error);
640 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800641 return -1;
642 }
643 sz -= xfer;
644 ptr += xfer;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700645 if (show_progress) {
Magnus Eriksson86ae6d52013-03-05 07:37:32 +0100646 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker447f0612012-01-09 14:54:53 -0800647 fflush(stdout);
648 }
649 }
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700650 if (show_progress) {
Doug Zongker447f0612012-01-09 14:54:53 -0800651 printf("\n");
652 }
653
Elliott Hughese67f1f82015-04-30 17:32:03 -0700654 if (!adb_status(fd, &error)) {
655 fprintf(stderr,"* error response '%s' *\n", error.c_str());
Doug Zongker447f0612012-01-09 14:54:53 -0800656 return -1;
657 }
658
659 adb_close(fd);
660 return 0;
661}
662
Doug Zongker71fe5842014-06-26 15:35:36 -0700663#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
664
665/*
666 * The sideload-host protocol serves the data in a file (given on the
667 * command line) to the client, using a simple protocol:
668 *
669 * - The connect message includes the total number of bytes in the
670 * file and a block size chosen by us.
671 *
672 * - The other side sends the desired block number as eight decimal
673 * digits (eg "00000023" for block 23). Blocks are numbered from
674 * zero.
675 *
676 * - We send back the data of the requested block. The last block is
677 * likely to be partial; when the last block is requested we only
678 * send the part of the block that exists, it's not padded up to the
679 * block size.
680 *
681 * - When the other side sends "DONEDONE" instead of a block number,
682 * we hang up.
683 */
Elliott Hughes58305772015-04-17 13:57:15 -0700684static int adb_sideload_host(const char* fn) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700685 unsigned sz;
686 size_t xfer = 0;
687 int status;
Dan Albertbac34742015-02-25 17:51:28 -0800688 int last_percent = -1;
689 int opt = SIDELOAD_HOST_BLOCK_SIZE;
Doug Zongker71fe5842014-06-26 15:35:36 -0700690
691 printf("loading: '%s'", fn);
692 fflush(stdout);
Dan Albertbac34742015-02-25 17:51:28 -0800693 uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
Doug Zongker71fe5842014-06-26 15:35:36 -0700694 if (data == 0) {
695 printf("\n");
696 fprintf(stderr, "* cannot read '%s' *\n", fn);
697 return -1;
698 }
699
Elliott Hughes6452a892015-04-29 12:28:13 -0700700 std::string service =
701 android::base::StringPrintf("sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700702 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700703 int fd = adb_connect(service, &error);
Doug Zongker71fe5842014-06-26 15:35:36 -0700704 if (fd < 0) {
705 // Try falling back to the older sideload method. Maybe this
706 // is an older device that doesn't support sideload-host.
707 printf("\n");
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700708 status = adb_download_buffer("sideload", fn, data, sz, true);
Doug Zongker71fe5842014-06-26 15:35:36 -0700709 goto done;
710 }
711
Spencer Lowf055c192015-01-25 14:40:16 -0800712 opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker71fe5842014-06-26 15:35:36 -0700713
Elliott Hughesa7090b92015-04-17 17:03:59 -0700714 while (true) {
Elliott Hughes6452a892015-04-29 12:28:13 -0700715 char buf[9];
Dan Albertcc731cc2015-02-24 21:26:58 -0800716 if (!ReadFdExactly(fd, buf, 8)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700717 fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
Doug Zongker71fe5842014-06-26 15:35:36 -0700718 status = -1;
719 goto done;
720 }
Elliott Hughes6452a892015-04-29 12:28:13 -0700721 buf[8] = '\0';
Doug Zongker71fe5842014-06-26 15:35:36 -0700722
Elliott Hughes6452a892015-04-29 12:28:13 -0700723 if (strcmp("DONEDONE", buf) == 0) {
Doug Zongker71fe5842014-06-26 15:35:36 -0700724 status = 0;
725 break;
726 }
727
Doug Zongker71fe5842014-06-26 15:35:36 -0700728 int block = strtol(buf, NULL, 10);
729
730 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
731 if (offset >= sz) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700732 fprintf(stderr, "* attempt to read block %d past end\n", block);
Doug Zongker71fe5842014-06-26 15:35:36 -0700733 status = -1;
734 goto done;
735 }
736 uint8_t* start = data + offset;
737 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
738 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
739 if (offset_end > sz) {
740 to_write = sz - offset;
741 }
742
Dan Albertcc731cc2015-02-24 21:26:58 -0800743 if(!WriteFdExactly(fd, start, to_write)) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700744 adb_status(fd, &error);
745 fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
Doug Zongker71fe5842014-06-26 15:35:36 -0700746 status = -1;
747 goto done;
748 }
749 xfer += to_write;
750
751 // For normal OTA packages, we expect to transfer every byte
752 // twice, plus a bit of overhead (one read during
753 // verification, one read of each byte for installation, plus
754 // extra access to things like the zip central directory).
755 // This estimate of the completion becomes 100% when we've
756 // transferred ~2.13 (=100/47) times the package size.
757 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
758 if (percent != last_percent) {
759 printf("\rserving: '%s' (~%d%%) ", fn, percent);
760 fflush(stdout);
761 last_percent = percent;
762 }
763 }
764
Colin Cross6d6a8982014-07-07 14:12:41 -0700765 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongker71fe5842014-06-26 15:35:36 -0700766
767 done:
768 if (fd >= 0) adb_close(fd);
769 free(data);
770 return status;
771}
772
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800773/**
774 * Run ppp in "notty" mode against a resource listed as the first parameter
775 * eg:
776 *
777 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
778 *
779 */
Elliott Hughes58305772015-04-17 13:57:15 -0700780static int ppp(int argc, const char** argv) {
Yabin Cuie77b6a02014-11-11 09:24:11 -0800781#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800782 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
783 return -1;
784#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800785 if (argc < 2) {
786 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
787 argv[0]);
788
789 return 1;
790 }
791
Dan Albertbac34742015-02-25 17:51:28 -0800792 const char* adb_service_name = argv[1];
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700793 std::string error;
794 int fd = adb_connect(adb_service_name, &error);
795 if (fd < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800796 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700797 adb_service_name, error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800798 return 1;
799 }
800
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700801 pid_t pid = fork();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800802
803 if (pid < 0) {
804 perror("from fork()");
805 return 1;
806 } else if (pid == 0) {
807 int err;
808 int i;
809 const char **ppp_args;
810
811 // copy args
812 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
813 ppp_args[0] = "pppd";
814 for (i = 2 ; i < argc ; i++) {
815 //argv[2] and beyond become ppp_args[1] and beyond
816 ppp_args[i - 1] = argv[i];
817 }
818 ppp_args[i-1] = NULL;
819
820 // child side
821
822 dup2(fd, STDIN_FILENO);
823 dup2(fd, STDOUT_FILENO);
824 adb_close(STDERR_FILENO);
825 adb_close(fd);
826
827 err = execvp("pppd", (char * const *)ppp_args);
828
829 if (err < 0) {
830 perror("execing pppd");
831 }
832 exit(-1);
833 } else {
834 // parent side
835
836 adb_close(fd);
837 return 0;
838 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800839#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800840}
841
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700842static bool wait_for_device(const char* service, TransportType t, const char* serial) {
Elliott Hughes2b101112015-05-04 19:29:32 -0700843 // Was the caller vague about what they'd like us to wait for?
844 // If so, check they weren't more specific in their choice of transport type.
845 if (strcmp(service, "wait-for-device") == 0) {
846 if (t == kTransportUsb) {
847 service = "wait-for-usb";
848 } else if (t == kTransportLocal) {
849 service = "wait-for-local";
850 } else {
851 service = "wait-for-any";
852 }
853 }
854
855 std::string cmd = format_host_command(service, t, serial);
Elliott Hughes424af022015-05-29 17:55:19 -0700856 return adb_command(cmd);
Elliott Hughes2b101112015-05-04 19:29:32 -0700857}
858
David Pursell70ef7b42015-09-30 13:35:42 -0700859// Connects to the device "shell" service with |command| and prints the
860// resulting output.
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700861static int send_shell_command(TransportType transport_type, const char* serial,
David Pursell70ef7b42015-09-30 13:35:42 -0700862 const std::string& command,
863 bool disable_shell_protocol) {
864 // Only use shell protocol if it's supported and the caller doesn't want
865 // to explicitly disable it.
866 bool use_shell_protocol = false;
867 if (!disable_shell_protocol) {
868 FeatureSet features = GetFeatureSet(transport_type, serial);
869 use_shell_protocol = CanUseFeature(features, kFeatureShell2);
870 }
871
872 std::string service_string = ShellServiceString(use_shell_protocol, "",
873 command);
874
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700875 int fd;
876 while (true) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700877 std::string error;
David Pursell70ef7b42015-09-30 13:35:42 -0700878 fd = adb_connect(service_string, &error);
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700879 if (fd >= 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800880 break;
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700881 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800882 fprintf(stderr,"- waiting for device -\n");
883 adb_sleep_ms(1000);
Elliott Hughes2b101112015-05-04 19:29:32 -0700884 wait_for_device("wait-for-device", transport_type, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800885 }
886
David Pursell70ef7b42015-09-30 13:35:42 -0700887 int exit_code = read_and_dump(fd, use_shell_protocol);
David Pursell71c83122015-09-14 15:33:50 -0700888
889 if (adb_close(fd) < 0) {
890 PLOG(ERROR) << "failure closing FD " << fd;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700891 }
David Pursell71c83122015-09-14 15:33:50 -0700892
893 return exit_code;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800894}
895
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700896static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700897 char* log_tags = getenv("ANDROID_LOG_TAGS");
898 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800899
David Pursell70ef7b42015-09-30 13:35:42 -0700900 std::string cmd = "export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800901
Jeff Sharkeyfd546e82014-06-10 11:31:24 -0700902 if (!strcmp(argv[0], "longcat")) {
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700903 cmd += " -v long";
Christopher Tatedb0a8802011-11-30 13:00:33 -0800904 }
905
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700906 --argc;
907 ++argv;
Elliott Hughes2baae3a2015-04-17 10:59:34 -0700908 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700909 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800910 }
911
David Pursell70ef7b42015-09-30 13:35:42 -0700912 // No need for shell protocol with logcat, always disable for simplicity.
913 return send_shell_command(transport, serial, cmd, true);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800914}
915
Dan Albertbac34742015-02-25 17:51:28 -0800916static int backup(int argc, const char** argv) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700917 const char* filename = "./backup.ab";
Christopher Tated2f54152011-04-21 12:53:28 -0700918
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700919 /* find, extract, and use any -f argument */
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700920 for (int i = 1; i < argc; i++) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700921 if (!strcmp("-f", argv[i])) {
922 if (i == argc-1) {
923 fprintf(stderr, "adb: -f passed with no filename\n");
924 return usage();
925 }
926 filename = argv[i+1];
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700927 for (int j = i+2; j <= argc; ) {
Christopher Tatec9cd3b92011-06-01 17:56:23 -0700928 argv[i++] = argv[j++];
929 }
930 argc -= 2;
931 argv[argc] = NULL;
932 }
Christopher Tated2f54152011-04-21 12:53:28 -0700933 }
934
Christopher Tatebb86bc52011-08-22 17:12:08 -0700935 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
936 if (argc < 2) return usage();
937
Christopher Tateb1dfffe2011-12-08 19:04:34 -0800938 adb_unlink(filename);
Mark Salyzyn60299df2014-04-30 09:10:31 -0700939 mkdirs(filename);
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700940 int outFd = adb_creat(filename, 0640);
Christopher Tated2f54152011-04-21 12:53:28 -0700941 if (outFd < 0) {
942 fprintf(stderr, "adb: unable to open file %s\n", filename);
943 return -1;
944 }
945
Elliott Hughes6c34bba2015-04-17 20:11:08 -0700946 std::string cmd = "backup:";
947 --argc;
948 ++argv;
949 while (argc-- > 0) {
950 cmd += " " + escape_arg(*argv++);
Christopher Tated2f54152011-04-21 12:53:28 -0700951 }
952
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700953 D("backup. filename=%s cmd=%s", filename, cmd.c_str());
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700954 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -0700955 int fd = adb_connect(cmd, &error);
Christopher Tated2f54152011-04-21 12:53:28 -0700956 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700957 fprintf(stderr, "adb: unable to connect for backup: %s\n", error.c_str());
Christopher Tated2f54152011-04-21 12:53:28 -0700958 adb_close(outFd);
959 return -1;
960 }
961
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800962 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tated2f54152011-04-21 12:53:28 -0700963 copy_to_file(fd, outFd);
964
965 adb_close(fd);
966 adb_close(outFd);
967 return 0;
968}
969
Dan Albertbac34742015-02-25 17:51:28 -0800970static int restore(int argc, const char** argv) {
Christopher Tate702967a2011-05-17 15:52:54 -0700971 if (argc != 2) return usage();
972
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700973 const char* filename = argv[1];
974 int tarFd = adb_open(filename, O_RDONLY);
Christopher Tate702967a2011-05-17 15:52:54 -0700975 if (tarFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700976 fprintf(stderr, "adb: unable to open file %s: %s\n", filename, strerror(errno));
Christopher Tate702967a2011-05-17 15:52:54 -0700977 return -1;
978 }
979
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700980 std::string error;
981 int fd = adb_connect("restore:", &error);
Christopher Tate702967a2011-05-17 15:52:54 -0700982 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -0700983 fprintf(stderr, "adb: unable to connect for restore: %s\n", error.c_str());
Christopher Tate702967a2011-05-17 15:52:54 -0700984 adb_close(tarFd);
985 return -1;
986 }
987
Christopher Tatebffa4ca2012-01-06 15:43:03 -0800988 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tate702967a2011-05-17 15:52:54 -0700989 copy_to_file(tarFd, fd);
990
991 adb_close(fd);
992 adb_close(tarFd);
993 return 0;
994}
995
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800996/* <hint> may be:
997 * - A simple product name
998 * e.g., "sooner"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800999 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1000 * e.g., "out/target/product/sooner"
1001 * - An absolute path to the PRODUCT_OUT dir
1002 * e.g., "/src/device/out/target/product/sooner"
1003 *
1004 * Given <hint>, try to construct an absolute path to the
1005 * ANDROID_PRODUCT_OUT dir.
1006 */
Elliott Hughes5c742702015-07-30 17:42:01 -07001007static std::string find_product_out_path(const std::string& hint) {
1008 if (hint.empty()) {
Elliott Hughes58305772015-04-17 13:57:15 -07001009 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001010 }
1011
Elliott Hughes58305772015-04-17 13:57:15 -07001012 // If it's already absolute, don't bother doing any work.
Elliott Hughes5c742702015-07-30 17:42:01 -07001013 if (adb_is_absolute_host_path(hint.c_str())) {
Elliott Hughes58305772015-04-17 13:57:15 -07001014 return hint;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001015 }
1016
Elliott Hughes58305772015-04-17 13:57:15 -07001017 // If there are any slashes in it, assume it's a relative path;
1018 // make it absolute.
Elliott Hughes5c742702015-07-30 17:42:01 -07001019 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
Elliott Hughesa7090b92015-04-17 17:03:59 -07001020 std::string cwd;
1021 if (!getcwd(&cwd)) {
1022 fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
Elliott Hughes58305772015-04-17 13:57:15 -07001023 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001024 }
Elliott Hughes5c742702015-07-30 17:42:01 -07001025 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 -08001026 }
1027
Elliott Hughes58305772015-04-17 13:57:15 -07001028 // It's a string without any slashes. Try to do something with it.
1029 //
1030 // Try to find the root of the build tree, and build a PRODUCT_OUT
1031 // path from there.
Elliott Hughesa7090b92015-04-17 17:03:59 -07001032 char* top = getenv("ANDROID_BUILD_TOP");
Elliott Hughes58305772015-04-17 13:57:15 -07001033 if (top == nullptr) {
Elliott Hughesa7090b92015-04-17 17:03:59 -07001034 fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
Elliott Hughes58305772015-04-17 13:57:15 -07001035 return "";
1036 }
Elliott Hughesa7090b92015-04-17 17:03:59 -07001037
1038 std::string path = top;
Elliott Hughes58305772015-04-17 13:57:15 -07001039 path += OS_PATH_SEPARATOR_STR;
1040 path += "out";
1041 path += OS_PATH_SEPARATOR_STR;
1042 path += "target";
1043 path += OS_PATH_SEPARATOR_STR;
1044 path += "product";
1045 path += OS_PATH_SEPARATOR_STR;
1046 path += hint;
1047 if (!directory_exists(path)) {
1048 fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
Elliott Hughes5c742702015-07-30 17:42:01 -07001049 "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
Elliott Hughesa7090b92015-04-17 17:03:59 -07001050 return "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001051 }
Elliott Hughes58305772015-04-17 13:57:15 -07001052 return path;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001053}
1054
Dan Albertbac34742015-02-25 17:51:28 -08001055static void parse_push_pull_args(const char **arg, int narg, char const **path1,
Elliott Hughesaa245492015-08-03 10:38:08 -07001056 char const **path2, bool* show_progress,
Dan Albertbac34742015-02-25 17:51:28 -08001057 int *copy_attrs) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001058 *show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001059 *copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001060
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001061 while (narg > 0) {
1062 if (!strcmp(*arg, "-p")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001063 *show_progress = true;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001064 } else if (!strcmp(*arg, "-a")) {
1065 *copy_attrs = 1;
1066 } else {
1067 break;
1068 }
Mark Lindner76f2a932014-03-11 17:55:59 -07001069 ++arg;
1070 --narg;
1071 }
1072
1073 if (narg > 0) {
1074 *path1 = *arg;
1075 ++arg;
1076 --narg;
1077 }
1078
1079 if (narg > 0) {
1080 *path2 = *arg;
1081 }
1082}
1083
Elliott Hughes6452a892015-04-29 12:28:13 -07001084static int adb_connect_command(const std::string& command) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001085 std::string error;
1086 int fd = adb_connect(command, &error);
Elliott Hughes5677c232015-05-07 23:37:40 -07001087 if (fd < 0) {
1088 fprintf(stderr, "error: %s\n", error.c_str());
1089 return 1;
Tao Bao175b7bb2015-03-29 11:22:34 -07001090 }
Elliott Hughes5677c232015-05-07 23:37:40 -07001091 read_and_dump(fd);
1092 adb_close(fd);
1093 return 0;
Tao Bao175b7bb2015-03-29 11:22:34 -07001094}
1095
Elliott Hughes6452a892015-04-29 12:28:13 -07001096static int adb_query_command(const std::string& command) {
1097 std::string result;
1098 std::string error;
1099 if (!adb_query(command, &result, &error)) {
1100 fprintf(stderr, "error: %s\n", error.c_str());
1101 return 1;
1102 }
1103 printf("%s\n", result.c_str());
1104 return 0;
1105}
1106
Spencer Lowa13df302015-09-07 16:20:13 -07001107// Disallow stdin, stdout, and stderr.
1108static bool _is_valid_ack_reply_fd(const int ack_reply_fd) {
1109#ifdef _WIN32
1110 const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
1111 return (GetStdHandle(STD_INPUT_HANDLE) != ack_reply_handle) &&
1112 (GetStdHandle(STD_OUTPUT_HANDLE) != ack_reply_handle) &&
1113 (GetStdHandle(STD_ERROR_HANDLE) != ack_reply_handle);
1114#else
1115 return ack_reply_fd > 2;
1116#endif
1117}
1118
Elliott Hughesab52c182015-05-01 17:04:38 -07001119int adb_commandline(int argc, const char **argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001120 int no_daemon = 0;
1121 int is_daemon = 0;
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001122 int is_server = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001123 int r;
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001124 TransportType transport_type = kTransportAny;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001125 int ack_reply_fd = -1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001126
Elliott Hughes58305772015-04-17 13:57:15 -07001127 // If defined, this should be an absolute path to
1128 // the directory containing all of the various system images
1129 // for a particular product. If not defined, and the adb
1130 // command requires this information, then the user must
1131 // specify the path using "-p".
1132 char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
1133 if (ANDROID_PRODUCT_OUT != nullptr) {
1134 gProductOutPath = ANDROID_PRODUCT_OUT;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001135 }
1136 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1137
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001138 /* Validate and assign the server port */
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001139 const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001140 int server_port = DEFAULT_ADB_PORT;
1141 if (server_port_str && strlen(server_port_str) > 0) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001142 server_port = strtol(server_port_str, nullptr, 0);
Matt Gumbeld7b33082012-11-14 10:16:17 -08001143 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001144 fprintf(stderr,
Spencer Lowf18fc082015-08-11 17:05:02 -07001145 "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 +01001146 server_port_str);
1147 return usage();
1148 }
1149 }
1150
Elliott Hughes8d28e192015-10-07 14:55:10 -07001151 // We need to check for -d and -e before we look at $ANDROID_SERIAL.
1152 const char* serial = nullptr;
1153
Riley Andrews98f58e82014-12-05 17:37:24 -08001154 while (argc > 0) {
1155 if (!strcmp(argv[0],"server")) {
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001156 is_server = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001157 } else if (!strcmp(argv[0],"nodaemon")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001158 no_daemon = 1;
1159 } else if (!strcmp(argv[0], "fork-server")) {
1160 /* this is a special flag used only when the ADB client launches the ADB Server */
1161 is_daemon = 1;
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001162 } else if (!strcmp(argv[0], "--reply-fd")) {
1163 if (argc < 2) return usage();
1164 const char* reply_fd_str = argv[1];
1165 argc--;
1166 argv++;
1167 ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
Spencer Lowa13df302015-09-07 16:20:13 -07001168 if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001169 fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
1170 return usage();
1171 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001172 } else if (!strncmp(argv[0], "-p", 2)) {
Elliott Hughes048b27c2015-07-31 13:18:22 -07001173 const char* product = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001174 if (argv[0][2] == '\0') {
1175 if (argc < 2) return usage();
1176 product = argv[1];
1177 argc--;
1178 argv++;
1179 } else {
Vairavan Srinivasan81273232012-08-04 16:40:50 -07001180 product = argv[0] + 2;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001181 }
Elliott Hughes048b27c2015-07-31 13:18:22 -07001182 gProductOutPath = find_product_out_path(product);
Elliott Hughes58305772015-04-17 13:57:15 -07001183 if (gProductOutPath.empty()) {
1184 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001185 return usage();
1186 }
1187 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1188 if (isdigit(argv[0][2])) {
1189 serial = argv[0] + 2;
1190 } else {
Riley Andrews98f58e82014-12-05 17:37:24 -08001191 if (argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001192 serial = argv[1];
1193 argc--;
1194 argv++;
1195 }
1196 } else if (!strcmp(argv[0],"-d")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001197 transport_type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001198 } else if (!strcmp(argv[0],"-e")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001199 transport_type = kTransportLocal;
Matt Gumbeld7b33082012-11-14 10:16:17 -08001200 } else if (!strcmp(argv[0],"-a")) {
1201 gListenAll = 1;
Riley Andrews98f58e82014-12-05 17:37:24 -08001202 } else if (!strncmp(argv[0], "-H", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001203 const char *hostname = NULL;
1204 if (argv[0][2] == '\0') {
1205 if (argc < 2) return usage();
1206 hostname = argv[1];
1207 argc--;
1208 argv++;
1209 } else {
1210 hostname = argv[0] + 2;
1211 }
1212 adb_set_tcp_name(hostname);
1213
Riley Andrews98f58e82014-12-05 17:37:24 -08001214 } else if (!strncmp(argv[0], "-P", 2)) {
Matt Gumbeld7b33082012-11-14 10:16:17 -08001215 if (argv[0][2] == '\0') {
1216 if (argc < 2) return usage();
1217 server_port_str = argv[1];
1218 argc--;
1219 argv++;
1220 } else {
1221 server_port_str = argv[0] + 2;
1222 }
1223 if (strlen(server_port_str) > 0) {
1224 server_port = (int) strtol(server_port_str, NULL, 0);
1225 if (server_port <= 0 || server_port > 65535) {
1226 fprintf(stderr,
1227 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1228 server_port_str);
1229 return usage();
1230 }
1231 } else {
1232 fprintf(stderr,
1233 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1234 return usage();
1235 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001236 } else {
1237 /* out of recognized modifiers and flags */
1238 break;
1239 }
1240 argc--;
1241 argv++;
1242 }
1243
Elliott Hughes8d28e192015-10-07 14:55:10 -07001244 // If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
1245 if (transport_type == kTransportAny && serial == nullptr) {
1246 serial = getenv("ANDROID_SERIAL");
1247 }
1248
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001249 adb_set_transport(transport_type, serial);
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001250 adb_set_tcp_specifics(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001251
David 'Digit' Turner305b4b02011-01-31 14:23:56 +01001252 if (is_server) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001253 if (no_daemon || is_daemon) {
Spencer Low5c398d22015-08-08 15:07:07 -07001254 if (is_daemon && (ack_reply_fd == -1)) {
Siva Velusamy9f2d1a92015-08-07 10:10:29 -07001255 fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
1256 return usage();
1257 }
1258 r = adb_main(is_daemon, server_port, ack_reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001259 } else {
Stefan Hilzingera84a42e2010-04-19 12:21:12 +01001260 r = launch_server(server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001261 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001262 if (r) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001263 fprintf(stderr,"* could not start server *\n");
1264 }
1265 return r;
1266 }
1267
Riley Andrews98f58e82014-12-05 17:37:24 -08001268 if (argc == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001269 return usage();
1270 }
1271
Riley Andrewsc8514c82014-12-05 17:32:46 -08001272 /* handle wait-for-* prefix */
1273 if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
Dan Albertbac34742015-02-25 17:51:28 -08001274 const char* service = argv[0];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001275
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001276 if (!wait_for_device(service, transport_type, serial)) {
Riley Andrewsc8514c82014-12-05 17:32:46 -08001277 return 1;
1278 }
1279
Elliott Hughes2b101112015-05-04 19:29:32 -07001280 // Allow a command to be run after wait-for-device,
1281 // e.g. 'adb wait-for-device shell'.
Riley Andrewsc8514c82014-12-05 17:32:46 -08001282 if (argc == 1) {
1283 return 0;
1284 }
1285
1286 /* Fall through */
1287 argc--;
1288 argv++;
1289 }
1290
1291 /* adb_connect() commands */
Riley Andrews98f58e82014-12-05 17:37:24 -08001292 if (!strcmp(argv[0], "devices")) {
Dan Albertbac34742015-02-25 17:51:28 -08001293 const char *listopt;
Elliott Hughes6452a892015-04-29 12:28:13 -07001294 if (argc < 2) {
Scott Andersone109d262012-04-20 11:21:14 -07001295 listopt = "";
Elliott Hughes6452a892015-04-29 12:28:13 -07001296 } else if (argc == 2 && !strcmp(argv[1], "-l")) {
Scott Andersone109d262012-04-20 11:21:14 -07001297 listopt = argv[1];
Elliott Hughes6452a892015-04-29 12:28:13 -07001298 } else {
Scott Andersone109d262012-04-20 11:21:14 -07001299 fprintf(stderr, "Usage: adb devices [-l]\n");
1300 return 1;
1301 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001302
1303 std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
1304 printf("List of devices attached\n");
1305 return adb_query_command(query);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001306 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001307 else if (!strcmp(argv[0], "connect")) {
Mike Lockwoodff196702009-08-24 15:58:40 -07001308 if (argc != 2) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001309 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwoodff196702009-08-24 15:58:40 -07001310 return 1;
1311 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001312
1313 std::string query = android::base::StringPrintf("host:connect:%s", argv[1]);
1314 return adb_query_command(query);
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001315 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001316 else if (!strcmp(argv[0], "disconnect")) {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -04001317 if (argc > 2) {
1318 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1319 return 1;
1320 }
Elliott Hughes6452a892015-04-29 12:28:13 -07001321
1322 std::string query = android::base::StringPrintf("host:disconnect:%s",
1323 (argc == 2) ? argv[1] : "");
1324 return adb_query_command(query);
Mike Lockwoodff196702009-08-24 15:58:40 -07001325 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001326 else if (!strcmp(argv[0], "emu")) {
Spencer Low142ec752015-05-06 16:13:42 -07001327 return adb_send_emulator_command(argc, argv, serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001328 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001329 else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001330 char h = (argv[0][0] == 'h');
1331
David Pursell4e2fd362015-09-22 10:43:08 -07001332 FeatureSet features = GetFeatureSet(transport_type, serial);
1333
David Pursell70ef7b42015-09-30 13:35:42 -07001334 bool use_shell_protocol = CanUseFeature(features, kFeatureShell2);
David Pursell4e2fd362015-09-22 10:43:08 -07001335 if (!use_shell_protocol) {
1336 D("shell protocol not supported, using raw data transfer");
1337 } else {
1338 D("using shell protocol");
1339 }
1340
1341 // Parse shell-specific command-line options.
1342 // argv[0] is always "shell".
1343 --argc;
1344 ++argv;
1345 std::string shell_type_arg;
1346 while (argc) {
1347 if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
David Pursell70ef7b42015-09-30 13:35:42 -07001348 if (!CanUseFeature(features, kFeatureShell2)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001349 fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
1350 return 1;
1351 }
David Pursell70ef7b42015-09-30 13:35:42 -07001352 shell_type_arg = (argv[0][1] == 'T') ? kShellServiceArgRaw
1353 : kShellServiceArgPty;
1354 --argc;
1355 ++argv;
1356 } else if (!strcmp(argv[0], "-x")) {
1357 use_shell_protocol = false;
David Pursell4e2fd362015-09-22 10:43:08 -07001358 --argc;
1359 ++argv;
1360 } else {
1361 break;
1362 }
1363 }
David Pursell4e2fd362015-09-22 10:43:08 -07001364
David Pursell1ed57f02015-10-06 15:30:03 -07001365 std::string command;
1366 if (argc) {
1367 // We don't escape here, just like ssh(1). http://b/20564385.
1368 command = android::base::Join(
1369 std::vector<const char*>(argv, argv + argc), ' ');
1370 }
1371
Daniel Sandlerff91ab82010-08-19 01:10:18 -04001372 if (h) {
1373 printf("\x1b[41;33m");
1374 fflush(stdout);
1375 }
1376
David Pursell1ed57f02015-10-06 15:30:03 -07001377 r = RemoteShell(use_shell_protocol, shell_type_arg, command);
1378
1379 if (h) {
1380 printf("\x1b[0m");
1381 fflush(stdout);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001382 }
1383
David Pursell1ed57f02015-10-06 15:30:03 -07001384 return r;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001385 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001386 else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001387 int exec_in = !strcmp(argv[0], "exec-in");
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001388
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001389 std::string cmd = "exec:";
1390 cmd += argv[1];
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001391 argc -= 2;
1392 argv += 2;
1393 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001394 cmd += " " + escape_arg(*argv++);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001395 }
1396
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001397 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001398 int fd = adb_connect(cmd, &error);
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001399 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001400 fprintf(stderr, "error: %s\n", error.c_str());
Jeff Sharkey5d9d4342014-05-26 18:30:43 -07001401 return -1;
1402 }
1403
1404 if (exec_in) {
1405 copy_to_file(STDIN_FILENO, fd);
1406 } else {
1407 copy_to_file(fd, STDOUT_FILENO);
1408 }
1409
1410 adb_close(fd);
1411 return 0;
1412 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001413 else if (!strcmp(argv[0], "kill-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001414 std::string error;
1415 int fd = _adb_connect("host:kill", &error);
Spencer Lowf18fc082015-08-11 17:05:02 -07001416 if (fd == -2) {
1417 // Failed to make network connection to server. Don't output the
1418 // network error since that is expected.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001419 fprintf(stderr,"* server not running *\n");
Spencer Lowf18fc082015-08-11 17:05:02 -07001420 // Successful exit code because the server is already "killed".
1421 return 0;
1422 } else if (fd == -1) {
1423 // Some other error.
1424 fprintf(stderr, "error: %s\n", error.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001425 return 1;
Spencer Lowf18fc082015-08-11 17:05:02 -07001426 } else {
1427 // Successfully connected, kill command sent, okay status came back.
1428 // Server should exit() in a moment, if not already.
1429 adb_close(fd);
1430 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001431 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001432 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001433 else if (!strcmp(argv[0], "sideload")) {
1434 if (argc != 2) return usage();
Doug Zongker71fe5842014-06-26 15:35:36 -07001435 if (adb_sideload_host(argv[1])) {
Doug Zongker447f0612012-01-09 14:54:53 -08001436 return 1;
1437 } else {
1438 return 0;
1439 }
1440 }
Elliott Hughes19d80b82015-07-21 16:13:40 -07001441 else if (!strcmp(argv[0], "tcpip") && argc > 1) {
1442 return adb_connect_command(android::base::StringPrintf("tcpip:%s", argv[1]));
1443 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001444 else if (!strcmp(argv[0], "remount") ||
1445 !strcmp(argv[0], "reboot") ||
1446 !strcmp(argv[0], "reboot-bootloader") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001447 !strcmp(argv[0], "usb") ||
1448 !strcmp(argv[0], "root") ||
Dan Pasanen98858812014-10-06 12:57:20 -05001449 !strcmp(argv[0], "unroot") ||
Riley Andrewsc8514c82014-12-05 17:32:46 -08001450 !strcmp(argv[0], "disable-verity") ||
1451 !strcmp(argv[0], "enable-verity")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001452 std::string command;
Tao Bao175b7bb2015-03-29 11:22:34 -07001453 if (!strcmp(argv[0], "reboot-bootloader")) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001454 command = "reboot:bootloader";
Tao Bao175b7bb2015-03-29 11:22:34 -07001455 } else if (argc > 1) {
Elliott Hughes5677c232015-05-07 23:37:40 -07001456 command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
Tao Bao175b7bb2015-03-29 11:22:34 -07001457 } else {
Elliott Hughes5677c232015-05-07 23:37:40 -07001458 command = android::base::StringPrintf("%s:", argv[0]);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001459 }
Tao Bao175b7bb2015-03-29 11:22:34 -07001460 return adb_connect_command(command);
The Android Open Source Projecte037fd72009-03-13 13:04:37 -07001461 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001462 else if (!strcmp(argv[0], "bugreport")) {
Dan Egnorc130ea72010-01-20 13:50:36 -08001463 if (argc != 1) return usage();
David Pursell70ef7b42015-09-30 13:35:42 -07001464 // No need for shell protocol with bugreport, always disable for
1465 // simplicity.
1466 return send_shell_command(transport_type, serial, "bugreport", true);
Mike Lockwoodf56d1b52009-09-03 14:54:58 -04001467 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001468 else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
Elliott Hughes424af022015-05-29 17:55:19 -07001469 bool reverse = !strcmp(argv[0], "reverse");
1470 ++argv;
1471 --argc;
1472 if (argc < 1) return usage();
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001473
1474 // Determine the <host-prefix> for this command.
Elliott Hughes424af022015-05-29 17:55:19 -07001475 std::string host_prefix;
David 'Digit' Turner25258692013-03-21 21:07:42 +01001476 if (reverse) {
Elliott Hughes424af022015-05-29 17:55:19 -07001477 host_prefix = "reverse";
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001478 } else {
David 'Digit' Turner25258692013-03-21 21:07:42 +01001479 if (serial) {
Elliott Hughes424af022015-05-29 17:55:19 -07001480 host_prefix = android::base::StringPrintf("host-serial:%s", serial);
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001481 } else if (transport_type == kTransportUsb) {
Elliott Hughes424af022015-05-29 17:55:19 -07001482 host_prefix = "host-usb";
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001483 } else if (transport_type == kTransportLocal) {
Elliott Hughes424af022015-05-29 17:55:19 -07001484 host_prefix = "host-local";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001485 } else {
Elliott Hughes424af022015-05-29 17:55:19 -07001486 host_prefix = "host";
David 'Digit' Turner25258692013-03-21 21:07:42 +01001487 }
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001488 }
1489
Elliott Hughes424af022015-05-29 17:55:19 -07001490 std::string cmd;
1491 if (strcmp(argv[0], "--list") == 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -07001492 if (argc != 1) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001493 return adb_query_command(host_prefix + ":list-forward");
1494 } else if (strcmp(argv[0], "--remove-all") == 0) {
1495 if (argc != 1) return usage();
1496 cmd = host_prefix + ":killforward-all";
1497 } else if (strcmp(argv[0], "--remove") == 0) {
1498 // forward --remove <local>
Elliott Hughesab52c182015-05-01 17:04:38 -07001499 if (argc != 2) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001500 cmd = host_prefix + ":killforward:" + argv[1];
1501 } else if (strcmp(argv[0], "--no-rebind") == 0) {
1502 // forward --no-rebind <local> <remote>
Elliott Hughesab52c182015-05-01 17:04:38 -07001503 if (argc != 3) return usage();
Elliott Hughes424af022015-05-29 17:55:19 -07001504 cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
1505 } else {
1506 // forward <local> <remote>
1507 if (argc != 2) return usage();
1508 cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
David 'Digit' Turner0d82fbf2012-11-14 15:01:55 +01001509 }
1510
Elliott Hughes424af022015-05-29 17:55:19 -07001511 return adb_command(cmd) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001512 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001513 /* do_sync_*() commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001514 else if (!strcmp(argv[0], "ls")) {
1515 if (argc != 2) return usage();
Elliott Hughesaa245492015-08-03 10:38:08 -07001516 return do_sync_ls(argv[1]) ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001517 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001518 else if (!strcmp(argv[0], "push")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001519 bool show_progress = false;
1520 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001521 const char* lpath = NULL, *rpath = NULL;
1522
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001523 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001524 if (!lpath || !rpath || copy_attrs != 0) return usage();
1525 return do_sync_push(lpath, rpath, show_progress) ? 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], "pull")) {
Elliott Hughesaa245492015-08-03 10:38:08 -07001528 bool show_progress = false;
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001529 int copy_attrs = 0;
Mark Lindner76f2a932014-03-11 17:55:59 -07001530 const char* rpath = NULL, *lpath = ".";
1531
Lajos Molnarde8ff4a2013-04-19 12:41:09 -07001532 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Elliott Hughesaa245492015-08-03 10:38:08 -07001533 if (!rpath) return usage();
1534 return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 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], "install")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001537 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001538 return install_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001539 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001540 else if (!strcmp(argv[0], "install-multiple")) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001541 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001542 return install_multiple_app(transport_type, serial, argc, argv);
Jeff Sharkey960df972014-06-09 17:30:57 -07001543 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001544 else if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001545 if (argc < 2) return usage();
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001546 return uninstall_app(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001547 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001548 else if (!strcmp(argv[0], "sync")) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001549 std::string src;
Elliott Hughes58305772015-04-17 13:57:15 -07001550 bool list_only = false;
Riley Andrews98f58e82014-12-05 17:37:24 -08001551 if (argc < 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001552 // No local path was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001553 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001554 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001555 list_only = true;
Anthony Newnam705c9442010-02-22 08:36:49 -06001556 if (argc == 3) {
Elliott Hughesd236d072015-04-21 10:17:07 -07001557 src = argv[2];
Anthony Newnam705c9442010-02-22 08:36:49 -06001558 } else {
Elliott Hughesd236d072015-04-21 10:17:07 -07001559 src = "";
Anthony Newnam705c9442010-02-22 08:36:49 -06001560 }
Riley Andrews98f58e82014-12-05 17:37:24 -08001561 } else if (argc == 2) {
Elliott Hughes58305772015-04-17 13:57:15 -07001562 // A local path or "android"/"data" arg was specified.
Elliott Hughesd236d072015-04-21 10:17:07 -07001563 src = argv[1];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001564 } else {
1565 return usage();
1566 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001567
Elliott Hughesd236d072015-04-21 10:17:07 -07001568 if (src != "" &&
1569 src != "system" && src != "data" && src != "vendor" && src != "oem") {
Elliott Hughes58305772015-04-17 13:57:15 -07001570 return usage();
1571 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001572
Elliott Hughes58305772015-04-17 13:57:15 -07001573 std::string system_src_path = product_file("system");
1574 std::string data_src_path = product_file("data");
1575 std::string vendor_src_path = product_file("vendor");
1576 std::string oem_src_path = product_file("oem");
Elliott Hughes58305772015-04-17 13:57:15 -07001577
Elliott Hughesaa245492015-08-03 10:38:08 -07001578 bool okay = true;
1579 if (okay && (src.empty() || src == "system")) {
1580 okay = do_sync_sync(system_src_path, "/system", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001581 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001582 if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
1583 okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001584 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001585 if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
1586 okay = do_sync_sync(oem_src_path, "/oem", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001587 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001588 if (okay && (src.empty() || src == "data")) {
1589 okay = do_sync_sync(data_src_path, "/data", list_only);
Elliott Hughes58305772015-04-17 13:57:15 -07001590 }
Elliott Hughesaa245492015-08-03 10:38:08 -07001591 return okay ? 0 : 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001592 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001593 /* passthrough commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001594 else if (!strcmp(argv[0],"get-state") ||
Scott Andersone109d262012-04-20 11:21:14 -07001595 !strcmp(argv[0],"get-serialno") ||
1596 !strcmp(argv[0],"get-devpath"))
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001597 {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001598 return adb_query_command(format_host_command(argv[0], transport_type, serial));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001599 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001600 /* other commands */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001601 else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001602 return logcat(transport_type, serial, argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001603 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001604 else if (!strcmp(argv[0],"ppp")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001605 return ppp(argc, argv);
1606 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001607 else if (!strcmp(argv[0], "start-server")) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001608 std::string error;
Spencer Lowf18fc082015-08-11 17:05:02 -07001609 const int result = adb_connect("host:start-server", &error);
1610 if (result < 0) {
1611 fprintf(stderr, "error: %s\n", error.c_str());
1612 }
1613 return result;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001614 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001615 else if (!strcmp(argv[0], "backup")) {
Christopher Tated2f54152011-04-21 12:53:28 -07001616 return backup(argc, argv);
1617 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001618 else if (!strcmp(argv[0], "restore")) {
Christopher Tate702967a2011-05-17 15:52:54 -07001619 return restore(argc, argv);
1620 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001621 else if (!strcmp(argv[0], "keygen")) {
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001622 if (argc < 2) return usage();
Yabin Cuiaed3c612015-09-22 15:52:57 -07001623 // Always print key generation information for keygen command.
1624 adb_trace_enable(AUTH);
Nick Kralevichbea3f9c2014-11-13 15:17:29 -08001625 return adb_auth_keygen(argv[1]);
1626 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001627 else if (!strcmp(argv[0], "jdwp")) {
Tao Bao175b7bb2015-03-29 11:22:34 -07001628 return adb_connect_command("jdwp");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001629 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001630 /* "adb /?" is a common idiom under Windows */
Riley Andrewsc8514c82014-12-05 17:32:46 -08001631 else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001632 help();
1633 return 0;
1634 }
Riley Andrewsc8514c82014-12-05 17:32:46 -08001635 else if (!strcmp(argv[0], "version")) {
Elliott Hughes42ae2602015-08-12 08:32:10 -07001636 fprintf(stdout, "%s", adb_version().c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001637 return 0;
1638 }
Dan Albert90d4b732015-05-20 18:58:41 -07001639 else if (!strcmp(argv[0], "features")) {
David Pursell4e2fd362015-09-22 10:43:08 -07001640 // Only list the features common to both the adb client and the device.
1641 FeatureSet features = GetFeatureSet(transport_type, serial);
1642 for (const std::string& name : features) {
David Pursell70ef7b42015-09-30 13:35:42 -07001643 if (CanUseFeature(features, name)) {
David Pursell4e2fd362015-09-22 10:43:08 -07001644 printf("%s\n", name.c_str());
1645 }
1646 }
1647 return 0;
Dan Albert90d4b732015-05-20 18:58:41 -07001648 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001649
1650 usage();
1651 return 1;
1652}
1653
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001654static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) {
David Pursell70ef7b42015-09-30 13:35:42 -07001655 std::string cmd = "pm";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001656
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001657 while (argc-- > 0) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001658 cmd += " " + escape_arg(*argv++);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001659 }
1660
David Pursell70ef7b42015-09-30 13:35:42 -07001661 // TODO(dpursell): add command-line arguments to install/uninstall to
1662 // manually disable shell protocol if needed.
1663 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001664}
1665
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001666static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001667 /* if the user choose the -k option, we refuse to do it until devices are
1668 out with the option to uninstall the remaining data somehow (adb/ui) */
1669 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1670 {
1671 printf(
1672 "The -k option uninstalls the application while retaining the data/cache.\n"
1673 "At the moment, there is no way to remove the remaining data.\n"
1674 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1675 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1676 return -1;
1677 }
1678
1679 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1680 return pm_command(transport, serial, argc, argv);
1681}
1682
Elliott Hughes5c742702015-07-30 17:42:01 -07001683static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
David Pursell70ef7b42015-09-30 13:35:42 -07001684 std::string cmd = "rm -f " + escape_arg(filename);
1685 return send_shell_command(transport, serial, cmd, false);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001686}
1687
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001688static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
Dan Albert286bb6d2015-07-09 20:35:09 +00001689 static const char *const DATA_DEST = "/data/local/tmp/%s";
1690 static const char *const SD_DEST = "/sdcard/tmp/%s";
Kenny Root597ea5b2011-08-05 11:19:45 -07001691 const char* where = DATA_DEST;
Kenny Root597ea5b2011-08-05 11:19:45 -07001692 int i;
Jeff Sharkey960df972014-06-09 17:30:57 -07001693 struct stat sb;
Kenny Root597ea5b2011-08-05 11:19:45 -07001694
1695 for (i = 1; i < argc; i++) {
Jeff Sharkey960df972014-06-09 17:30:57 -07001696 if (!strcmp(argv[i], "-s")) {
Kenny Root597ea5b2011-08-05 11:19:45 -07001697 where = SD_DEST;
1698 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001699 }
1700
Jeff Sharkey960df972014-06-09 17:30:57 -07001701 // Find last APK argument.
1702 // All other arguments passed through verbatim.
1703 int last_apk = -1;
1704 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001705 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001706 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001707 if (dot && !strcasecmp(dot, ".apk")) {
1708 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1709 fprintf(stderr, "Invalid APK file: %s\n", file);
1710 return -1;
1711 }
1712
1713 last_apk = i;
1714 break;
1715 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001716 }
1717
Jeff Sharkey960df972014-06-09 17:30:57 -07001718 if (last_apk == -1) {
1719 fprintf(stderr, "Missing APK file\n");
1720 return -1;
Kenny Root597ea5b2011-08-05 11:19:45 -07001721 }
1722
Elliott Hughesaa245492015-08-03 10:38:08 -07001723 int result = -1;
Dan Albertbac34742015-02-25 17:51:28 -08001724 const char* apk_file = argv[last_apk];
Elliott Hughes5c742702015-07-30 17:42:01 -07001725 std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
Elliott Hughesaa245492015-08-03 10:38:08 -07001726 if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk;
1727 argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
1728 result = pm_command(transport, serial, argc, argv);
Kenny Root597ea5b2011-08-05 11:19:45 -07001729
Kenny Root60733e92012-03-26 16:14:02 -07001730cleanup_apk:
Dan Albert286bb6d2015-07-09 20:35:09 +00001731 delete_file(transport, serial, apk_dest);
Elliott Hughesaa245492015-08-03 10:38:08 -07001732 return result;
Jeff Sharkey960df972014-06-09 17:30:57 -07001733}
1734
Elliott Hughes3bd73c12015-05-05 13:10:43 -07001735static int install_multiple_app(TransportType transport, const char* serial, int argc,
Elliott Hughes58305772015-04-17 13:57:15 -07001736 const char** argv)
Jeff Sharkey960df972014-06-09 17:30:57 -07001737{
Jeff Sharkey960df972014-06-09 17:30:57 -07001738 int i;
1739 struct stat sb;
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001740 uint64_t total_size = 0;
Jeff Sharkey960df972014-06-09 17:30:57 -07001741
1742 // Find all APK arguments starting at end.
1743 // All other arguments passed through verbatim.
1744 int first_apk = -1;
1745 for (i = argc - 1; i >= 0; i--) {
Dan Albertbac34742015-02-25 17:51:28 -08001746 const char* file = argv[i];
Elliott Hughes3e7048c2015-07-27 21:21:39 -07001747 const char* dot = strrchr(file, '.');
Jeff Sharkey960df972014-06-09 17:30:57 -07001748 if (dot && !strcasecmp(dot, ".apk")) {
1749 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1750 fprintf(stderr, "Invalid APK file: %s\n", file);
1751 return -1;
1752 }
1753
1754 total_size += sb.st_size;
1755 first_apk = i;
1756 } else {
1757 break;
1758 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001759 }
1760
Jeff Sharkey960df972014-06-09 17:30:57 -07001761 if (first_apk == -1) {
1762 fprintf(stderr, "Missing APK file\n");
1763 return 1;
1764 }
Kenny Root597ea5b2011-08-05 11:19:45 -07001765
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001766 std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
Jeff Sharkey960df972014-06-09 17:30:57 -07001767 for (i = 1; i < first_apk; i++) {
Elliott Hughes6c34bba2015-04-17 20:11:08 -07001768 cmd += " " + escape_arg(argv[i]);
Jeff Sharkey960df972014-06-09 17:30:57 -07001769 }
1770
1771 // Create install session
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001772 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001773 int fd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001774 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001775 fprintf(stderr, "Connect error for create: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001776 return -1;
1777 }
Elliott Hughes2baae3a2015-04-17 10:59:34 -07001778 char buf[BUFSIZ];
Jeff Sharkey960df972014-06-09 17:30:57 -07001779 read_status_line(fd, buf, sizeof(buf));
1780 adb_close(fd);
1781
1782 int session_id = -1;
1783 if (!strncmp("Success", buf, 7)) {
1784 char* start = strrchr(buf, '[');
1785 char* end = strrchr(buf, ']');
1786 if (start && end) {
1787 *end = '\0';
1788 session_id = strtol(start + 1, NULL, 10);
1789 }
1790 }
1791 if (session_id < 0) {
1792 fprintf(stderr, "Failed to create session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001793 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001794 return -1;
1795 }
1796
1797 // Valid session, now stream the APKs
1798 int success = 1;
1799 for (i = first_apk; i < argc; i++) {
Dan Albertbac34742015-02-25 17:51:28 -08001800 const char* file = argv[i];
Jeff Sharkey960df972014-06-09 17:30:57 -07001801 if (stat(file, &sb) == -1) {
1802 fprintf(stderr, "Failed to stat %s\n", file);
1803 success = 0;
1804 goto finalize_session;
1805 }
1806
Elliott Hughes2940ccf2015-04-17 14:07:52 -07001807 std::string cmd = android::base::StringPrintf(
1808 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
Elliott Hughes5c742702015-07-30 17:42:01 -07001809 static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001810
1811 int localFd = adb_open(file, O_RDONLY);
1812 if (localFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001813 fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
Jeff Sharkey960df972014-06-09 17:30:57 -07001814 success = 0;
1815 goto finalize_session;
1816 }
1817
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001818 std::string error;
Elliott Hughes6452a892015-04-29 12:28:13 -07001819 int remoteFd = adb_connect(cmd, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001820 if (remoteFd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001821 fprintf(stderr, "Connect error for write: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001822 adb_close(localFd);
1823 success = 0;
1824 goto finalize_session;
1825 }
1826
1827 copy_to_file(localFd, remoteFd);
1828 read_status_line(remoteFd, buf, sizeof(buf));
1829
1830 adb_close(localFd);
1831 adb_close(remoteFd);
1832
1833 if (strncmp("Success", buf, 7)) {
1834 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate71bbc672014-07-14 16:45:13 -07001835 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001836 success = 0;
1837 goto finalize_session;
1838 }
1839 }
1840
1841finalize_session:
Jeff Sharkeyac77e1f2014-07-25 09:58:25 -07001842 // Commit session if we streamed everything okay; otherwise abandon
Elliott Hughes6452a892015-04-29 12:28:13 -07001843 std::string service =
1844 android::base::StringPrintf("exec:pm install-%s %d",
1845 success ? "commit" : "abandon", session_id);
1846 fd = adb_connect(service, &error);
Jeff Sharkey960df972014-06-09 17:30:57 -07001847 if (fd < 0) {
Elliott Hughes078f0fc2015-04-29 08:35:59 -07001848 fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
Jeff Sharkey960df972014-06-09 17:30:57 -07001849 return -1;
1850 }
1851 read_status_line(fd, buf, sizeof(buf));
1852 adb_close(fd);
1853
1854 if (!strncmp("Success", buf, 7)) {
Christopher Tate71bbc672014-07-14 16:45:13 -07001855 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001856 return 0;
1857 } else {
1858 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate71bbc672014-07-14 16:45:13 -07001859 fputs(buf, stderr);
Jeff Sharkey960df972014-06-09 17:30:57 -07001860 return -1;
1861 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001862}