blob: 49f1b958585a0ed9b5ecd10e8e72282b6327699f [file] [log] [blame]
The Android Open Source Project9ca14dc2009-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
17#include <stdio.h>
Andrew Hsiehb73d0e02014-05-07 20:21:11 +080018#include <stdint.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080019#include <stdlib.h>
20#include <string.h>
21#include <errno.h>
22#include <unistd.h>
23#include <limits.h>
24#include <stdarg.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <ctype.h>
28#include <assert.h>
29
30#include "sysdeps.h"
31
Yabin Cui6704a3c2014-11-17 14:48:25 -080032#if !defined(_WIN32)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080033#include <termios.h>
34#endif
35
36#define TRACE_TAG TRACE_ADB
37#include "adb.h"
38#include "adb_client.h"
Nick Kralevich6183c962014-11-13 15:17:29 -080039#include "adb_auth.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080040#include "file_sync_service.h"
41
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080042static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
43
Alexey Tarasov857f17a2009-10-22 02:55:00 +110044void get_my_path(char *s, size_t maxLen);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080045int find_sync_dirs(const char *srcarg,
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -070046 char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080047int install_app(transport_type transport, char* serial, int argc, char** argv);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -070048int install_multiple_app(transport_type transport, char* serial, int argc, char** argv);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080049int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
50
51static const char *gProductOutPath = NULL;
Matt Gumbel411775c2012-11-14 10:16:17 -080052extern int gListenAll;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080053
54static char *product_file(const char *extra)
55{
56 int n;
57 char *x;
58
59 if (gProductOutPath == NULL) {
60 fprintf(stderr, "adb: Product directory not specified; "
61 "use -p or define ANDROID_PRODUCT_OUT\n");
62 exit(1);
63 }
64
65 n = strlen(gProductOutPath) + strlen(extra) + 2;
66 x = malloc(n);
67 if (x == 0) {
68 fprintf(stderr, "adb: Out of memory (product_file())\n");
69 exit(1);
70 }
71
72 snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
73 return x;
74}
75
76void version(FILE * out) {
77 fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
78 ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
79}
80
81void help()
82{
83 version(stderr);
84
85 fprintf(stderr,
86 "\n"
Matt Gumbel411775c2012-11-14 10:16:17 -080087 " -a - directs adb to listen on all interfaces for a connection\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080088 " -d - directs command to the only connected USB device\n"
89 " returns an error if more than one USB device is present.\n"
90 " -e - directs command to the only running emulator.\n"
91 " returns an error if more than one emulator is running.\n"
Scott Anderson6dfaf4b2012-04-20 11:21:14 -070092 " -s <specific device> - directs command to the device or emulator with the given\n"
Scott Anderson27042382012-05-30 18:11:27 -070093 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
Elliott Hughesec424ad2009-10-07 15:38:53 -070094 " environment variable.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080095 " -p <product name or path> - simple product name like 'sooner', or\n"
96 " a relative/absolute path to a product\n"
97 " out directory like 'out/target/product/sooner'.\n"
98 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
99 " environment variable is used, which must\n"
100 " be an absolute path.\n"
Matt Gumbel411775c2012-11-14 10:16:17 -0800101 " -H - Name of adb server host (default: localhost)\n"
102 " -P - Port of adb server (default: 5037)\n"
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700103 " devices [-l] - list all connected devices\n"
Scott Anderson27042382012-05-30 18:11:27 -0700104 " ('-l' will also list device qualifiers)\n"
Mike Lockwood01c2c302010-05-24 10:44:35 -0400105 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
106 " Port 5555 is used by default if no port number is specified.\n"
107 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
108 " Port 5555 is used by default if no port number is specified.\n"
Bernhard Reutner-Fischerc3e82b82011-04-26 12:46:05 +0200109 " Using this command with no additional arguments\n"
Mike Lockwood01c2c302010-05-24 10:44:35 -0400110 " will disconnect from all connected TCP/IP devices.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800111 "\n"
112 "device commands:\n"
Mark Lindner9f9d1452014-03-11 17:55:59 -0700113 " adb push [-p] <local> <remote>\n"
114 " - copy file/dir to device\n"
115 " ('-p' to display the transfer progress)\n"
Lajos Molnar4e23e3c2013-04-19 12:41:09 -0700116 " adb pull [-p] [-a] <remote> [<local>]\n"
Mark Lindner9f9d1452014-03-11 17:55:59 -0700117 " - copy file/dir from device\n"
118 " ('-p' to display the transfer progress)\n"
Lajos Molnar4e23e3c2013-04-19 12:41:09 -0700119 " ('-a' means copy timestamp and mode)\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800120 " adb sync [ <directory> ] - copy host->device only if changed\n"
Anthony Newnamdd2db142010-02-22 08:36:49 -0600121 " (-l means list but don't copy)\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800122 " (see 'adb help all')\n"
123 " adb shell - run remote shell interactively\n"
124 " adb shell <command> - run remote shell command\n"
125 " adb emu <command> - run emulator console command\n"
126 " adb logcat [ <filter-spec> ] - View device log\n"
David 'Digit' Turner6c489802012-11-14 15:01:55 +0100127 " adb forward --list - list all forward socket connections.\n"
128 " the format is a list of lines with the following format:\n"
129 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800130 " adb forward <local> <remote> - forward socket connections\n"
131 " forward specs are one of: \n"
132 " tcp:<port>\n"
133 " localabstract:<unix domain socket name>\n"
134 " localreserved:<unix domain socket name>\n"
135 " localfilesystem:<unix domain socket name>\n"
136 " dev:<character device name>\n"
137 " jdwp:<process pid> (remote only)\n"
David 'Digit' Turner6c489802012-11-14 15:01:55 +0100138 " adb forward --no-rebind <local> <remote>\n"
139 " - same as 'adb forward <local> <remote>' but fails\n"
140 " if <local> is already forwarded\n"
141 " adb forward --remove <local> - remove a specific forward socket connection\n"
142 " adb forward --remove-all - remove all forward socket connections\n"
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100143 " adb reverse --list - list all reverse socket connections from device\n"
144 " adb reverse <remote> <local> - reverse socket connections\n"
145 " reverse specs are one of:\n"
146 " tcp:<port>\n"
147 " localabstract:<unix domain socket name>\n"
148 " localreserved:<unix domain socket name>\n"
149 " localfilesystem:<unix domain socket name>\n"
150 " adb reverse --norebind <remote> <local>\n"
151 " - same as 'adb reverse <remote> <local>' but fails\n"
152 " if <remote> is already reversed.\n"
153 " adb reverse --remove <remote>\n"
154 " - remove a specific reversed socket connection\n"
155 " adb reverse --remove-all - remove all reversed socket connections from device\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800156 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
Jeff Sharkey0e0d2512014-06-09 17:30:57 -0700157 " adb install [-lrtsd] <file>\n"
158 " adb install-multiple [-lrtsdp] <file...>\n"
Anonymous Coward5fe7ec22012-04-24 10:43:41 -0700159 " - push this package file to the device and install it\n"
Jeff Sharkey0e0d2512014-06-09 17:30:57 -0700160 " (-l: forward lock application)\n"
161 " (-r: replace existing application)\n"
162 " (-t: allow test packages)\n"
163 " (-s: install application on sdcard)\n"
164 " (-d: allow version code downgrade)\n"
165 " (-p: partial application install)\n"
The Android Open Source Project9ca14dc2009-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 Tate6f2937c2013-03-06 16:40:52 -0800171 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
Christopher Tate1cbb6df2011-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 Tate73779122011-04-21 12:53:28 -0700175 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
Christopher Tate24b56162011-08-09 17:05:29 -0700176 " in the archive; the default is noapk.)\n"
Christopher Tate6f2937c2013-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 Tate73779122011-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 Tate1cbb6df2011-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 Tate73779122011-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 Tate1cbb6df2011-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 Tate73779122011-04-21 12:53:28 -0700190 "\n"
Christopher Tate24b56162011-08-09 17:05:29 -0700191 " adb restore <file> - restore device contents from the <file> backup archive\n"
Christopher Tatecf5379b2011-05-17 15:52:54 -0700192 "\n"
Paul Lawrence8ba2b022014-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 Kralevich6183c962014-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 Project9ca14dc2009-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 Project9ca14dc2009-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 Anderson6dfaf4b2012-04-20 11:21:14 -0700207 " adb get-devpath - prints: <device-path>\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800208 " adb status-window - continuously print device status for a specified device\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700209 " adb remount - remounts the /system and /vendor (if present) partitions on the device read-write\n"
Mike Lockwood12a35ea2009-08-04 20:37:51 -0400210 " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
Romain Guyf925d912009-12-14 14:42:17 -0800211 " adb reboot-bootloader - reboots the device into the bootloader\n"
Mike Lockwood26b88e32009-08-24 15:58:40 -0700212 " adb root - restarts the adbd daemon with root permissions\n"
Romain Guyf925d912009-12-14 14:42:17 -0800213 " adb usb - restarts the adbd daemon listening on USB\n"
Paul Lawrence5f356482014-10-09 14:22:49 +0000214 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800215 "networking:\n"
216 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootf8eb5782009-06-08 14:40:30 -0500217 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800218 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
219 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
220 "\n"
221 "adb sync notes: adb sync [ <directory> ]\n"
222 " <localdir> can be interpreted in several ways:\n"
223 "\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700224 " - If <directory> is not specified, /system, /vendor (if present), and /data partitions will be updated.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800225 "\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700226 " - If it is \"system\", \"vendor\" or \"data\", only the corresponding partition\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800227 " is updated.\n"
Tim1b29ed32010-02-16 20:18:29 +0000228 "\n"
229 "environmental variables:\n"
230 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
231 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
232 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
233 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800234 );
235}
236
237int usage()
238{
239 help();
240 return 1;
241}
242
Yabin Cui6704a3c2014-11-17 14:48:25 -0800243#if defined(_WIN32)
244
245// Windows does not have <termio.h>.
246static void stdin_raw_init(int fd) {
247
248}
249
250static void stdin_raw_restore(int fd) {
251
252}
253
254#else
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800255static struct termios tio_save;
256
257static void stdin_raw_init(int fd)
258{
259 struct termios tio;
260
261 if(tcgetattr(fd, &tio)) return;
262 if(tcgetattr(fd, &tio_save)) return;
263
264 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
265
266 /* no timeout but request at least one character per read */
267 tio.c_cc[VTIME] = 0;
268 tio.c_cc[VMIN] = 1;
269
270 tcsetattr(fd, TCSANOW, &tio);
271 tcflush(fd, TCIFLUSH);
272}
273
274static void stdin_raw_restore(int fd)
275{
276 tcsetattr(fd, TCSANOW, &tio_save);
277 tcflush(fd, TCIFLUSH);
278}
279#endif
280
281static void read_and_dump(int fd)
282{
283 char buf[4096];
284 int len;
285
286 while(fd >= 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700287 D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800288 len = adb_read(fd, buf, 4096);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700289 D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800290 if(len == 0) {
291 break;
292 }
293
294 if(len < 0) {
295 if(errno == EINTR) continue;
296 break;
297 }
Mike Lockwood597ea9a2009-09-22 01:18:40 -0400298 fwrite(buf, 1, len, stdout);
299 fflush(stdout);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800300 }
301}
302
Jeff Sharkey0e0d2512014-06-09 17:30:57 -0700303static void read_status_line(int fd, char* buf, size_t count)
304{
305 count--;
306 while (count > 0) {
307 int len = adb_read(fd, buf, count);
308 if (len == 0) {
309 break;
310 } else if (len < 0) {
311 if (errno == EINTR) continue;
312 break;
313 }
314
315 buf += len;
316 count -= len;
317 }
318 *buf = '\0';
319}
320
Christopher Tate73779122011-04-21 12:53:28 -0700321static void copy_to_file(int inFd, int outFd) {
Christopher Tatea162e242011-06-10 11:38:37 -0700322 const size_t BUFSIZE = 32 * 1024;
323 char* buf = (char*) malloc(BUFSIZE);
Christopher Tate73779122011-04-21 12:53:28 -0700324 int len;
Christopher Tatefba22972011-06-01 17:56:23 -0700325 long total = 0;
Christopher Tate73779122011-04-21 12:53:28 -0700326
327 D("copy_to_file(%d -> %d)\n", inFd, outFd);
Yabin Cui6704a3c2014-11-17 14:48:25 -0800328
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700329 if (inFd == STDIN_FILENO) {
330 stdin_raw_init(STDIN_FILENO);
331 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800332
Christopher Tate73779122011-04-21 12:53:28 -0700333 for (;;) {
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700334 if (inFd == STDIN_FILENO) {
335 len = unix_read(inFd, buf, BUFSIZE);
336 } else {
337 len = adb_read(inFd, buf, BUFSIZE);
338 }
Christopher Tate73779122011-04-21 12:53:28 -0700339 if (len == 0) {
Christopher Tatea162e242011-06-10 11:38:37 -0700340 D("copy_to_file() : read 0 bytes; exiting\n");
Christopher Tate73779122011-04-21 12:53:28 -0700341 break;
342 }
343 if (len < 0) {
Christopher Tatea162e242011-06-10 11:38:37 -0700344 if (errno == EINTR) {
345 D("copy_to_file() : EINTR, retrying\n");
346 continue;
347 }
Christopher Tate73779122011-04-21 12:53:28 -0700348 D("copy_to_file() : error %d\n", errno);
349 break;
350 }
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700351 if (outFd == STDOUT_FILENO) {
352 fwrite(buf, 1, len, stdout);
353 fflush(stdout);
354 } else {
355 adb_write(outFd, buf, len);
356 }
Christopher Tatefba22972011-06-01 17:56:23 -0700357 total += len;
Christopher Tate73779122011-04-21 12:53:28 -0700358 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800359
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700360 if (inFd == STDIN_FILENO) {
361 stdin_raw_restore(STDIN_FILENO);
362 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800363
Christopher Tatefba22972011-06-01 17:56:23 -0700364 D("copy_to_file() finished after %lu bytes\n", total);
Christopher Tatea162e242011-06-10 11:38:37 -0700365 free(buf);
Christopher Tate73779122011-04-21 12:53:28 -0700366}
367
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800368static void *stdin_read_thread(void *x)
369{
370 int fd, fdi;
371 unsigned char buf[1024];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800372 int r, n;
373 int state = 0;
374
375 int *fds = (int*) x;
376 fd = fds[0];
377 fdi = fds[1];
378 free(fds);
379
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800380 for(;;) {
381 /* fdi is really the client's stdin, so use read, not adb_read here */
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700382 D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800383 r = unix_read(fdi, buf, 1024);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700384 D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800385 if(r == 0) break;
386 if(r < 0) {
387 if(errno == EINTR) continue;
388 break;
389 }
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400390 for(n = 0; n < r; n++){
391 switch(buf[n]) {
392 case '\n':
393 state = 1;
394 break;
395 case '\r':
396 state = 1;
397 break;
398 case '~':
399 if(state == 1) state++;
400 break;
401 case '.':
402 if(state == 2) {
403 fprintf(stderr,"\n* disconnect *\n");
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400404 stdin_raw_restore(fdi);
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400405 exit(0);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800406 }
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400407 default:
408 state = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800409 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800410 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800411 r = adb_write(fd, buf, r);
412 if(r <= 0) {
413 break;
414 }
415 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800416 return 0;
417}
418
419int interactive_shell(void)
420{
421 adb_thread_t thr;
422 int fdi, fd;
423 int *fds;
424
425 fd = adb_connect("shell:");
426 if(fd < 0) {
427 fprintf(stderr,"error: %s\n", adb_error());
428 return 1;
429 }
430 fdi = 0; //dup(0);
431
432 fds = malloc(sizeof(int) * 2);
433 fds[0] = fd;
434 fds[1] = fdi;
435
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800436 stdin_raw_init(fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800437 adb_thread_create(&thr, stdin_read_thread, fds);
438 read_and_dump(fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800439 stdin_raw_restore(fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800440 return 0;
441}
442
443
444static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial)
445{
446 if (serial) {
447 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
448 } else {
449 const char* prefix = "host";
450 if (ttype == kTransportUsb)
451 prefix = "host-usb";
452 else if (ttype == kTransportLocal)
453 prefix = "host-local";
454
455 snprintf(buffer, buflen, "%s:%s", prefix, command);
456 }
457}
458
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100459int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
Doug Zongker6b217ed2012-01-09 14:54:53 -0800460 unsigned progress)
461{
462 char buf[4096];
463 unsigned total;
464 int fd;
465 const unsigned char *ptr;
466
467 sprintf(buf,"%s:%d", service, sz);
468 fd = adb_connect(buf);
469 if(fd < 0) {
470 fprintf(stderr,"error: %s\n", adb_error());
471 return -1;
472 }
473
474 int opt = CHUNK_SIZE;
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700475 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker6b217ed2012-01-09 14:54:53 -0800476
477 total = sz;
478 ptr = data;
479
480 if(progress) {
481 char *x = strrchr(service, ':');
482 if(x) service = x + 1;
483 }
484
485 while(sz > 0) {
486 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
487 if(writex(fd, ptr, xfer)) {
488 adb_status(fd);
489 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
490 return -1;
491 }
492 sz -= xfer;
493 ptr += xfer;
494 if(progress) {
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100495 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker6b217ed2012-01-09 14:54:53 -0800496 fflush(stdout);
497 }
498 }
499 if(progress) {
500 printf("\n");
501 }
502
503 if(readx(fd, buf, 4)){
504 fprintf(stderr,"* error reading response *\n");
505 adb_close(fd);
506 return -1;
507 }
508 if(memcmp(buf, "OKAY", 4)) {
509 buf[4] = 0;
510 fprintf(stderr,"* error response '%s' *\n", buf);
511 adb_close(fd);
512 return -1;
513 }
514
515 adb_close(fd);
516 return 0;
517}
518
519
520int adb_download(const char *service, const char *fn, unsigned progress)
521{
522 void *data;
523 unsigned sz;
524
525 data = load_file(fn, &sz);
526 if(data == 0) {
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100527 fprintf(stderr,"* cannot read '%s' *\n", fn);
Doug Zongker6b217ed2012-01-09 14:54:53 -0800528 return -1;
529 }
530
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100531 int status = adb_download_buffer(service, fn, data, sz, progress);
Doug Zongker6b217ed2012-01-09 14:54:53 -0800532 free(data);
533 return status;
534}
535
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700536#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
537
538/*
539 * The sideload-host protocol serves the data in a file (given on the
540 * command line) to the client, using a simple protocol:
541 *
542 * - The connect message includes the total number of bytes in the
543 * file and a block size chosen by us.
544 *
545 * - The other side sends the desired block number as eight decimal
546 * digits (eg "00000023" for block 23). Blocks are numbered from
547 * zero.
548 *
549 * - We send back the data of the requested block. The last block is
550 * likely to be partial; when the last block is requested we only
551 * send the part of the block that exists, it's not padded up to the
552 * block size.
553 *
554 * - When the other side sends "DONEDONE" instead of a block number,
555 * we hang up.
556 */
557int adb_sideload_host(const char* fn) {
558 uint8_t* data;
559 unsigned sz;
560 size_t xfer = 0;
561 int status;
562
563 printf("loading: '%s'", fn);
564 fflush(stdout);
565 data = load_file(fn, &sz);
566 if (data == 0) {
567 printf("\n");
568 fprintf(stderr, "* cannot read '%s' *\n", fn);
569 return -1;
570 }
571
572 char buf[100];
573 sprintf(buf, "sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
574 int fd = adb_connect(buf);
575 if (fd < 0) {
576 // Try falling back to the older sideload method. Maybe this
577 // is an older device that doesn't support sideload-host.
578 printf("\n");
579 status = adb_download_buffer("sideload", fn, data, sz, 1);
580 goto done;
581 }
582
583 int opt = SIDELOAD_HOST_BLOCK_SIZE;
584 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
585
586 int last_percent = -1;
Doug Zongkera27ee6c2014-07-07 15:28:43 -0700587 for (;;) {
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700588 if (readx(fd, buf, 8)) {
589 fprintf(stderr, "* failed to read command: %s\n", adb_error());
590 status = -1;
591 goto done;
592 }
593
594 if (strncmp("DONEDONE", buf, 8) == 0) {
595 status = 0;
596 break;
597 }
598
599 buf[8] = '\0';
600 int block = strtol(buf, NULL, 10);
601
602 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
603 if (offset >= sz) {
604 fprintf(stderr, "* attempt to read past end: %s\n", adb_error());
605 status = -1;
606 goto done;
607 }
608 uint8_t* start = data + offset;
609 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
610 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
611 if (offset_end > sz) {
612 to_write = sz - offset;
613 }
614
615 if(writex(fd, start, to_write)) {
616 adb_status(fd);
617 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
618 status = -1;
619 goto done;
620 }
621 xfer += to_write;
622
623 // For normal OTA packages, we expect to transfer every byte
624 // twice, plus a bit of overhead (one read during
625 // verification, one read of each byte for installation, plus
626 // extra access to things like the zip central directory).
627 // This estimate of the completion becomes 100% when we've
628 // transferred ~2.13 (=100/47) times the package size.
629 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
630 if (percent != last_percent) {
631 printf("\rserving: '%s' (~%d%%) ", fn, percent);
632 fflush(stdout);
633 last_percent = percent;
634 }
635 }
636
Colin Cross2328bea2014-07-07 14:12:41 -0700637 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700638
639 done:
640 if (fd >= 0) adb_close(fd);
641 free(data);
642 return status;
643}
644
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800645static void status_window(transport_type ttype, const char* serial)
646{
647 char command[4096];
648 char *state = 0;
649 char *laststate = 0;
650
651 /* silence stderr */
652#ifdef _WIN32
653 /* XXX: TODO */
654#else
655 int fd;
656 fd = unix_open("/dev/null", O_WRONLY);
657 dup2(fd, 2);
658 adb_close(fd);
659#endif
660
661 format_host_command(command, sizeof command, "get-state", ttype, serial);
662
663 for(;;) {
664 adb_sleep_ms(250);
665
666 if(state) {
667 free(state);
668 state = 0;
669 }
670
671 state = adb_query(command);
672
673 if(state) {
674 if(laststate && !strcmp(state,laststate)){
675 continue;
676 } else {
677 if(laststate) free(laststate);
678 laststate = strdup(state);
679 }
680 }
681
682 printf("%c[2J%c[2H", 27, 27);
683 printf("Android Debug Bridge\n");
684 printf("State: %s\n", state ? state : "offline");
685 fflush(stdout);
686 }
687}
688
Brian Carlstrom529fca82014-08-05 22:51:18 -0700689static int should_escape(const char c)
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700690{
691 return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
692}
693
694/* Duplicate and escape given argument. */
Jeff Sharkey026d9622014-06-10 16:22:17 -0700695static char *escape_arg(const char *s)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800696{
697 const char *ts;
698 size_t alloc_len;
699 char *ret;
700 char *dest;
701
Jeff Sharkey026d9622014-06-10 16:22:17 -0700702 alloc_len = 0;
Jeff Sharkey824d1062014-06-10 11:31:24 -0700703 for (ts = s; *ts != '\0'; ts++) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800704 alloc_len++;
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700705 if (should_escape(*ts)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800706 alloc_len++;
707 }
708 }
709
Jeff Sharkey026d9622014-06-10 16:22:17 -0700710 if (alloc_len == 0) {
711 // Preserve empty arguments
712 ret = (char *) malloc(3);
713 ret[0] = '\"';
714 ret[1] = '\"';
715 ret[2] = '\0';
716 return ret;
717 }
718
Jeff Sharkey824d1062014-06-10 11:31:24 -0700719 ret = (char *) malloc(alloc_len + 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800720 dest = ret;
721
Jeff Sharkey824d1062014-06-10 11:31:24 -0700722 for (ts = s; *ts != '\0'; ts++) {
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700723 if (should_escape(*ts)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800724 *dest++ = '\\';
725 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800726 *dest++ = *ts;
727 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800728 *dest++ = '\0';
729
730 return ret;
731}
732
733/**
734 * Run ppp in "notty" mode against a resource listed as the first parameter
735 * eg:
736 *
737 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
738 *
739 */
740int ppp(int argc, char **argv)
741{
Yabin Cui2fa43212014-11-11 09:24:11 -0800742#if defined(_WIN32)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800743 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
744 return -1;
745#else
746 char *adb_service_name;
747 pid_t pid;
748 int fd;
749
750 if (argc < 2) {
751 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
752 argv[0]);
753
754 return 1;
755 }
756
757 adb_service_name = argv[1];
758
759 fd = adb_connect(adb_service_name);
760
761 if(fd < 0) {
762 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
763 adb_service_name, adb_error());
764 return 1;
765 }
766
767 pid = fork();
768
769 if (pid < 0) {
770 perror("from fork()");
771 return 1;
772 } else if (pid == 0) {
773 int err;
774 int i;
775 const char **ppp_args;
776
777 // copy args
778 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
779 ppp_args[0] = "pppd";
780 for (i = 2 ; i < argc ; i++) {
781 //argv[2] and beyond become ppp_args[1] and beyond
782 ppp_args[i - 1] = argv[i];
783 }
784 ppp_args[i-1] = NULL;
785
786 // child side
787
788 dup2(fd, STDIN_FILENO);
789 dup2(fd, STDOUT_FILENO);
790 adb_close(STDERR_FILENO);
791 adb_close(fd);
792
793 err = execvp("pppd", (char * const *)ppp_args);
794
795 if (err < 0) {
796 perror("execing pppd");
797 }
798 exit(-1);
799 } else {
800 // parent side
801
802 adb_close(fd);
803 return 0;
804 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800805#endif /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800806}
807
808static int send_shellcommand(transport_type transport, char* serial, char* buf)
809{
810 int fd, ret;
811
812 for(;;) {
813 fd = adb_connect(buf);
814 if(fd >= 0)
815 break;
816 fprintf(stderr,"- waiting for device -\n");
817 adb_sleep_ms(1000);
818 do_cmd(transport, serial, "wait-for-device", 0);
819 }
820
821 read_and_dump(fd);
822 ret = adb_close(fd);
823 if (ret)
824 perror("close");
825
826 return ret;
827}
828
829static int logcat(transport_type transport, char* serial, int argc, char **argv)
830{
831 char buf[4096];
832
833 char *log_tags;
Jeff Sharkey824d1062014-06-10 11:31:24 -0700834 char *quoted;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800835
836 log_tags = getenv("ANDROID_LOG_TAGS");
Jeff Sharkey026d9622014-06-10 16:22:17 -0700837 quoted = escape_arg(log_tags == NULL ? "" : log_tags);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800838 snprintf(buf, sizeof(buf),
Jeff Sharkey026d9622014-06-10 16:22:17 -0700839 "shell:export ANDROID_LOG_TAGS=\"%s\"; exec logcat", quoted);
Jeff Sharkey824d1062014-06-10 11:31:24 -0700840 free(quoted);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800841
Jeff Sharkey824d1062014-06-10 11:31:24 -0700842 if (!strcmp(argv[0], "longcat")) {
843 strncat(buf, " -v long", sizeof(buf) - 1);
Christopher Tate7b9b5162011-11-30 13:00:33 -0800844 }
845
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800846 argc -= 1;
847 argv += 1;
848 while(argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -0700849 quoted = escape_arg(*argv++);
Jeff Sharkey824d1062014-06-10 11:31:24 -0700850 strncat(buf, " ", sizeof(buf) - 1);
851 strncat(buf, quoted, sizeof(buf) - 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800852 free(quoted);
853 }
854
855 send_shellcommand(transport, serial, buf);
856 return 0;
857}
858
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700859static int mkdirs(const char *path)
Christopher Tate1e9f2392011-12-08 19:04:34 -0800860{
861 int ret;
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700862 char *x = (char *)path + 1;
Christopher Tate1e9f2392011-12-08 19:04:34 -0800863
864 for(;;) {
865 x = adb_dirstart(x);
866 if(x == 0) return 0;
867 *x = 0;
868 ret = adb_mkdir(path, 0775);
869 *x = OS_PATH_SEPARATOR;
870 if((ret < 0) && (errno != EEXIST)) {
871 return ret;
872 }
873 x++;
874 }
875 return 0;
876}
877
Christopher Tate73779122011-04-21 12:53:28 -0700878static int backup(int argc, char** argv) {
879 char buf[4096];
Christopher Tate1e9f2392011-12-08 19:04:34 -0800880 char default_name[32];
881 const char* filename = strcpy(default_name, "./backup.ab");
Christopher Tate73779122011-04-21 12:53:28 -0700882 int fd, outFd;
Christopher Tatefba22972011-06-01 17:56:23 -0700883 int i, j;
Christopher Tate73779122011-04-21 12:53:28 -0700884
Christopher Tatefba22972011-06-01 17:56:23 -0700885 /* find, extract, and use any -f argument */
886 for (i = 1; i < argc; i++) {
887 if (!strcmp("-f", argv[i])) {
888 if (i == argc-1) {
889 fprintf(stderr, "adb: -f passed with no filename\n");
890 return usage();
891 }
892 filename = argv[i+1];
893 for (j = i+2; j <= argc; ) {
894 argv[i++] = argv[j++];
895 }
896 argc -= 2;
897 argv[argc] = NULL;
898 }
Christopher Tate73779122011-04-21 12:53:28 -0700899 }
900
Christopher Tatecf4f16a2011-08-22 17:12:08 -0700901 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
902 if (argc < 2) return usage();
903
Christopher Tate1e9f2392011-12-08 19:04:34 -0800904 adb_unlink(filename);
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700905 mkdirs(filename);
Christopher Tate1e9f2392011-12-08 19:04:34 -0800906 outFd = adb_creat(filename, 0640);
Christopher Tate73779122011-04-21 12:53:28 -0700907 if (outFd < 0) {
908 fprintf(stderr, "adb: unable to open file %s\n", filename);
909 return -1;
910 }
911
912 snprintf(buf, sizeof(buf), "backup");
913 for (argc--, argv++; argc; argc--, argv++) {
914 strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
915 strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
916 }
917
918 D("backup. filename=%s buf=%s\n", filename, buf);
919 fd = adb_connect(buf);
920 if (fd < 0) {
921 fprintf(stderr, "adb: unable to connect for backup\n");
922 adb_close(outFd);
923 return -1;
924 }
925
Christopher Tate9c829102012-01-06 15:43:03 -0800926 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tate73779122011-04-21 12:53:28 -0700927 copy_to_file(fd, outFd);
928
929 adb_close(fd);
930 adb_close(outFd);
931 return 0;
932}
933
Christopher Tatecf5379b2011-05-17 15:52:54 -0700934static int restore(int argc, char** argv) {
935 const char* filename;
936 int fd, tarFd;
937
938 if (argc != 2) return usage();
939
940 filename = argv[1];
941 tarFd = adb_open(filename, O_RDONLY);
942 if (tarFd < 0) {
943 fprintf(stderr, "adb: unable to open file %s\n", filename);
944 return -1;
945 }
946
947 fd = adb_connect("restore:");
948 if (fd < 0) {
Brian Carlstromcad81322013-10-18 13:58:48 -0700949 fprintf(stderr, "adb: unable to connect for restore\n");
Christopher Tatecf5379b2011-05-17 15:52:54 -0700950 adb_close(tarFd);
951 return -1;
952 }
953
Christopher Tate9c829102012-01-06 15:43:03 -0800954 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tatecf5379b2011-05-17 15:52:54 -0700955 copy_to_file(tarFd, fd);
956
957 adb_close(fd);
958 adb_close(tarFd);
959 return 0;
960}
961
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800962#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
963static int top_works(const char *top)
964{
965 if (top != NULL && adb_is_absolute_host_path(top)) {
966 char path_buf[PATH_MAX];
967 snprintf(path_buf, sizeof(path_buf),
968 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
969 return access(path_buf, F_OK) == 0;
970 }
971 return 0;
972}
973
974static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
975{
976 strcpy(path_buf, indir);
977 while (1) {
978 if (top_works(path_buf)) {
979 return path_buf;
980 }
981 char *s = adb_dirstop(path_buf);
982 if (s != NULL) {
983 *s = '\0';
984 } else {
985 path_buf[0] = '\0';
986 return NULL;
987 }
988 }
989}
990
991static char *find_top(char path_buf[PATH_MAX])
992{
993 char *top = getenv("ANDROID_BUILD_TOP");
994 if (top != NULL && top[0] != '\0') {
995 if (!top_works(top)) {
996 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
997 return NULL;
998 }
999 } else {
1000 top = getenv("TOP");
1001 if (top != NULL && top[0] != '\0') {
1002 if (!top_works(top)) {
1003 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
1004 return NULL;
1005 }
1006 } else {
1007 top = NULL;
1008 }
1009 }
1010
1011 if (top != NULL) {
1012 /* The environment pointed to a top directory that works.
1013 */
1014 strcpy(path_buf, top);
1015 return path_buf;
1016 }
1017
1018 /* The environment didn't help. Walk up the tree from the CWD
1019 * to see if we can find the top.
1020 */
1021 char dir[PATH_MAX];
1022 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
1023 if (top == NULL) {
1024 /* If the CWD isn't under a good-looking top, see if the
1025 * executable is.
1026 */
Alexey Tarasov857f17a2009-10-22 02:55:00 +11001027 get_my_path(dir, PATH_MAX);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001028 top = find_top_from(dir, path_buf);
1029 }
1030 return top;
1031}
1032
1033/* <hint> may be:
1034 * - A simple product name
1035 * e.g., "sooner"
1036TODO: debug? sooner-debug, sooner:debug?
1037 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1038 * e.g., "out/target/product/sooner"
1039 * - An absolute path to the PRODUCT_OUT dir
1040 * e.g., "/src/device/out/target/product/sooner"
1041 *
1042 * Given <hint>, try to construct an absolute path to the
1043 * ANDROID_PRODUCT_OUT dir.
1044 */
1045static const char *find_product_out_path(const char *hint)
1046{
1047 static char path_buf[PATH_MAX];
1048
1049 if (hint == NULL || hint[0] == '\0') {
1050 return NULL;
1051 }
1052
1053 /* If it's already absolute, don't bother doing any work.
1054 */
1055 if (adb_is_absolute_host_path(hint)) {
1056 strcpy(path_buf, hint);
1057 return path_buf;
1058 }
1059
1060 /* If there are any slashes in it, assume it's a relative path;
1061 * make it absolute.
1062 */
1063 if (adb_dirstart(hint) != NULL) {
1064 if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
1065 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
1066 return NULL;
1067 }
1068 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
1069 fprintf(stderr, "adb: Couldn't assemble path\n");
1070 return NULL;
1071 }
1072 strcat(path_buf, OS_PATH_SEPARATOR_STR);
1073 strcat(path_buf, hint);
1074 return path_buf;
1075 }
1076
1077 /* It's a string without any slashes. Try to do something with it.
1078 *
1079 * Try to find the root of the build tree, and build a PRODUCT_OUT
1080 * path from there.
1081 */
1082 char top_buf[PATH_MAX];
1083 const char *top = find_top(top_buf);
1084 if (top == NULL) {
1085 fprintf(stderr, "adb: Couldn't find top of build tree\n");
1086 return NULL;
1087 }
1088//TODO: if we have a way to indicate debug, look in out/debug/target/...
1089 snprintf(path_buf, sizeof(path_buf),
1090 "%s" OS_PATH_SEPARATOR_STR
1091 "out" OS_PATH_SEPARATOR_STR
1092 "target" OS_PATH_SEPARATOR_STR
1093 "product" OS_PATH_SEPARATOR_STR
1094 "%s", top_buf, hint);
1095 if (access(path_buf, F_OK) < 0) {
1096 fprintf(stderr, "adb: Couldn't find a product dir "
1097 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
1098 return NULL;
1099 }
1100 return path_buf;
1101}
1102
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001103static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
1104 int *show_progress, int *copy_attrs) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001105 *show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001106 *copy_attrs = 0;
Mark Lindner9f9d1452014-03-11 17:55:59 -07001107
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001108 while (narg > 0) {
1109 if (!strcmp(*arg, "-p")) {
1110 *show_progress = 1;
1111 } else if (!strcmp(*arg, "-a")) {
1112 *copy_attrs = 1;
1113 } else {
1114 break;
1115 }
Mark Lindner9f9d1452014-03-11 17:55:59 -07001116 ++arg;
1117 --narg;
1118 }
1119
1120 if (narg > 0) {
1121 *path1 = *arg;
1122 ++arg;
1123 --narg;
1124 }
1125
1126 if (narg > 0) {
1127 *path2 = *arg;
1128 }
1129}
1130
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001131int adb_commandline(int argc, char **argv)
1132{
1133 char buf[4096];
1134 int no_daemon = 0;
1135 int is_daemon = 0;
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001136 int is_server = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001137 int persist = 0;
1138 int r;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001139 transport_type ttype = kTransportAny;
1140 char* serial = NULL;
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001141 char* server_port_str = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001142
1143 /* If defined, this should be an absolute path to
1144 * the directory containing all of the various system images
1145 * for a particular product. If not defined, and the adb
1146 * command requires this information, then the user must
1147 * specify the path using "-p".
1148 */
1149 gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
1150 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
1151 gProductOutPath = NULL;
1152 }
1153 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1154
Nick Pellyaf2fe9b2009-05-07 12:48:03 -07001155 serial = getenv("ANDROID_SERIAL");
1156
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001157 /* Validate and assign the server port */
1158 server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
1159 int server_port = DEFAULT_ADB_PORT;
1160 if (server_port_str && strlen(server_port_str) > 0) {
1161 server_port = (int) strtol(server_port_str, NULL, 0);
Matt Gumbel411775c2012-11-14 10:16:17 -08001162 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001163 fprintf(stderr,
Matt Gumbel411775c2012-11-14 10:16:17 -08001164 "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n",
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001165 server_port_str);
1166 return usage();
1167 }
1168 }
1169
1170 /* modifiers and flags */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001171 while(argc > 0) {
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001172 if(!strcmp(argv[0],"server")) {
1173 is_server = 1;
1174 } else if(!strcmp(argv[0],"nodaemon")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001175 no_daemon = 1;
1176 } else if (!strcmp(argv[0], "fork-server")) {
1177 /* this is a special flag used only when the ADB client launches the ADB Server */
1178 is_daemon = 1;
1179 } else if(!strcmp(argv[0],"persist")) {
1180 persist = 1;
1181 } else if(!strncmp(argv[0], "-p", 2)) {
1182 const char *product = NULL;
1183 if (argv[0][2] == '\0') {
1184 if (argc < 2) return usage();
1185 product = argv[1];
1186 argc--;
1187 argv++;
1188 } else {
Vairavan Srinivasanadc39402012-08-04 16:40:50 -07001189 product = argv[0] + 2;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001190 }
1191 gProductOutPath = find_product_out_path(product);
1192 if (gProductOutPath == NULL) {
1193 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
1194 product);
1195 return usage();
1196 }
1197 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1198 if (isdigit(argv[0][2])) {
1199 serial = argv[0] + 2;
1200 } else {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001201 if(argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001202 serial = argv[1];
1203 argc--;
1204 argv++;
1205 }
1206 } else if (!strcmp(argv[0],"-d")) {
1207 ttype = kTransportUsb;
1208 } else if (!strcmp(argv[0],"-e")) {
1209 ttype = kTransportLocal;
Matt Gumbel411775c2012-11-14 10:16:17 -08001210 } else if (!strcmp(argv[0],"-a")) {
1211 gListenAll = 1;
1212 } else if(!strncmp(argv[0], "-H", 2)) {
1213 const char *hostname = NULL;
1214 if (argv[0][2] == '\0') {
1215 if (argc < 2) return usage();
1216 hostname = argv[1];
1217 argc--;
1218 argv++;
1219 } else {
1220 hostname = argv[0] + 2;
1221 }
1222 adb_set_tcp_name(hostname);
1223
1224 } else if(!strncmp(argv[0], "-P", 2)) {
1225 if (argv[0][2] == '\0') {
1226 if (argc < 2) return usage();
1227 server_port_str = argv[1];
1228 argc--;
1229 argv++;
1230 } else {
1231 server_port_str = argv[0] + 2;
1232 }
1233 if (strlen(server_port_str) > 0) {
1234 server_port = (int) strtol(server_port_str, NULL, 0);
1235 if (server_port <= 0 || server_port > 65535) {
1236 fprintf(stderr,
1237 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1238 server_port_str);
1239 return usage();
1240 }
1241 } else {
1242 fprintf(stderr,
1243 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1244 return usage();
1245 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001246 } else {
1247 /* out of recognized modifiers and flags */
1248 break;
1249 }
1250 argc--;
1251 argv++;
1252 }
1253
1254 adb_set_transport(ttype, serial);
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001255 adb_set_tcp_specifics(server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001256
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001257 if (is_server) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001258 if (no_daemon || is_daemon) {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001259 r = adb_main(is_daemon, server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001260 } else {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001261 r = launch_server(server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001262 }
1263 if(r) {
1264 fprintf(stderr,"* could not start server *\n");
1265 }
1266 return r;
1267 }
1268
1269top:
1270 if(argc == 0) {
1271 return usage();
1272 }
1273
1274 /* adb_connect() commands */
1275
1276 if(!strcmp(argv[0], "devices")) {
1277 char *tmp;
Scott Anderson6dfaf4b2012-04-20 11:21:14 -07001278 char *listopt;
1279 if (argc < 2)
1280 listopt = "";
1281 else if (argc == 2 && !strcmp(argv[1], "-l"))
1282 listopt = argv[1];
1283 else {
1284 fprintf(stderr, "Usage: adb devices [-l]\n");
1285 return 1;
1286 }
1287 snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001288 tmp = adb_query(buf);
1289 if(tmp) {
1290 printf("List of devices attached \n");
1291 printf("%s\n", tmp);
1292 return 0;
1293 } else {
1294 return 1;
1295 }
1296 }
1297
Mike Lockwood01c2c302010-05-24 10:44:35 -04001298 if(!strcmp(argv[0], "connect")) {
Mike Lockwood26b88e32009-08-24 15:58:40 -07001299 char *tmp;
1300 if (argc != 2) {
Mike Lockwood01c2c302010-05-24 10:44:35 -04001301 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwood26b88e32009-08-24 15:58:40 -07001302 return 1;
1303 }
Mike Lockwood01c2c302010-05-24 10:44:35 -04001304 snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
1305 tmp = adb_query(buf);
1306 if(tmp) {
1307 printf("%s\n", tmp);
1308 return 0;
1309 } else {
1310 return 1;
1311 }
1312 }
1313
1314 if(!strcmp(argv[0], "disconnect")) {
1315 char *tmp;
1316 if (argc > 2) {
1317 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1318 return 1;
1319 }
1320 if (argc == 2) {
1321 snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
1322 } else {
1323 snprintf(buf, sizeof buf, "host:disconnect:");
1324 }
Mike Lockwood26b88e32009-08-24 15:58:40 -07001325 tmp = adb_query(buf);
1326 if(tmp) {
1327 printf("%s\n", tmp);
1328 return 0;
1329 } else {
1330 return 1;
1331 }
1332 }
1333
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001334 if (!strcmp(argv[0], "emu")) {
1335 return adb_send_emulator_command(argc, argv);
1336 }
1337
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001338 if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001339 int r;
1340 int fd;
1341
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001342 char h = (argv[0][0] == 'h');
1343
1344 if (h) {
1345 printf("\x1b[41;33m");
1346 fflush(stdout);
1347 }
1348
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001349 if(argc < 2) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001350 D("starting interactive shell\n");
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001351 r = interactive_shell();
1352 if (h) {
1353 printf("\x1b[0m");
1354 fflush(stdout);
1355 }
1356 return r;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001357 }
1358
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001359 snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001360 argc -= 2;
1361 argv += 2;
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001362 while (argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001363 char *quoted = escape_arg(*argv++);
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001364 strncat(buf, " ", sizeof(buf) - 1);
1365 strncat(buf, quoted, sizeof(buf) - 1);
1366 free(quoted);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001367 }
1368
1369 for(;;) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001370 D("interactive shell loop. buff=%s\n", buf);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001371 fd = adb_connect(buf);
1372 if(fd >= 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001373 D("about to read_and_dump(fd=%d)\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001374 read_and_dump(fd);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001375 D("read_and_dump() done.\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001376 adb_close(fd);
1377 r = 0;
1378 } else {
1379 fprintf(stderr,"error: %s\n", adb_error());
1380 r = -1;
1381 }
1382
1383 if(persist) {
1384 fprintf(stderr,"\n- waiting for device -\n");
1385 adb_sleep_ms(1000);
1386 do_cmd(ttype, serial, "wait-for-device", 0);
1387 } else {
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001388 if (h) {
1389 printf("\x1b[0m");
1390 fflush(stdout);
1391 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001392 D("interactive shell loop. return r=%d\n", r);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001393 return r;
1394 }
1395 }
1396 }
1397
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001398 if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
1399 int exec_in = !strcmp(argv[0], "exec-in");
1400 int fd;
1401
1402 snprintf(buf, sizeof buf, "exec:%s", argv[1]);
1403 argc -= 2;
1404 argv += 2;
1405 while (argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001406 char *quoted = escape_arg(*argv++);
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001407 strncat(buf, " ", sizeof(buf) - 1);
1408 strncat(buf, quoted, sizeof(buf) - 1);
1409 free(quoted);
1410 }
1411
1412 fd = adb_connect(buf);
1413 if (fd < 0) {
1414 fprintf(stderr, "error: %s\n", adb_error());
1415 return -1;
1416 }
1417
1418 if (exec_in) {
1419 copy_to_file(STDIN_FILENO, fd);
1420 } else {
1421 copy_to_file(fd, STDOUT_FILENO);
1422 }
1423
1424 adb_close(fd);
1425 return 0;
1426 }
1427
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001428 if(!strcmp(argv[0], "kill-server")) {
1429 int fd;
1430 fd = _adb_connect("host:kill");
1431 if(fd == -1) {
1432 fprintf(stderr,"* server not running *\n");
1433 return 1;
1434 }
1435 return 0;
1436 }
1437
Doug Zongker6b217ed2012-01-09 14:54:53 -08001438 if(!strcmp(argv[0], "sideload")) {
1439 if(argc != 2) return usage();
Doug Zongkerbcad29f2014-06-26 15:35:36 -07001440 if (adb_sideload_host(argv[1])) {
Doug Zongker6b217ed2012-01-09 14:54:53 -08001441 return 1;
1442 } else {
1443 return 0;
1444 }
1445 }
1446
Mike Lockwood26b88e32009-08-24 15:58:40 -07001447 if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
Romain Guyf925d912009-12-14 14:42:17 -08001448 || !strcmp(argv[0], "reboot-bootloader")
Mike Lockwood26b88e32009-08-24 15:58:40 -07001449 || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
Paul Lawrence8ba2b022014-12-03 15:31:57 -08001450 || !strcmp(argv[0], "root") || !strcmp(argv[0], "disable-verity")
1451 || !strcmp(argv[0], "enable-verity")) {
Mike Lockwood26b88e32009-08-24 15:58:40 -07001452 char command[100];
Romain Guyf925d912009-12-14 14:42:17 -08001453 if (!strcmp(argv[0], "reboot-bootloader"))
1454 snprintf(command, sizeof(command), "reboot:bootloader");
1455 else if (argc > 1)
Mike Lockwood26b88e32009-08-24 15:58:40 -07001456 snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
Mike Lockwood12a35ea2009-08-04 20:37:51 -04001457 else
Mike Lockwood26b88e32009-08-24 15:58:40 -07001458 snprintf(command, sizeof(command), "%s:", argv[0]);
1459 int fd = adb_connect(command);
The Android Open Source Project9c753402009-03-13 13:04:37 -07001460 if(fd >= 0) {
1461 read_and_dump(fd);
1462 adb_close(fd);
1463 return 0;
1464 }
1465 fprintf(stderr,"error: %s\n", adb_error());
1466 return 1;
1467 }
1468
Mike Lockwood78589f32009-09-03 14:54:58 -04001469 if(!strcmp(argv[0], "bugreport")) {
Dan Egnor2857f312010-01-20 13:50:36 -08001470 if (argc != 1) return usage();
1471 do_cmd(ttype, serial, "shell", "bugreport", 0);
Mike Lockwood78589f32009-09-03 14:54:58 -04001472 return 0;
1473 }
1474
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001475 /* adb_command() wrapper commands */
1476
1477 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1478 char* service = argv[0];
1479 if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1480 if (ttype == kTransportUsb) {
1481 service = "wait-for-usb";
1482 } else if (ttype == kTransportLocal) {
1483 service = "wait-for-local";
1484 } else {
1485 service = "wait-for-any";
1486 }
1487 }
1488
1489 format_host_command(buf, sizeof buf, service, ttype, serial);
1490
1491 if (adb_command(buf)) {
1492 D("failure: %s *\n",adb_error());
1493 fprintf(stderr,"error: %s\n", adb_error());
1494 return 1;
1495 }
1496
1497 /* Allow a command to be run after wait-for-device,
1498 * e.g. 'adb wait-for-device shell'.
1499 */
1500 if(argc > 1) {
1501 argc--;
1502 argv++;
1503 goto top;
1504 }
1505 return 0;
1506 }
1507
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001508 if(!strcmp(argv[0], "forward") ||
1509 !strcmp(argv[0], "reverse"))
1510 {
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001511 char host_prefix[64];
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001512 char reverse = (char) !strcmp(argv[0], "reverse");
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001513 char remove = 0;
1514 char remove_all = 0;
1515 char list = 0;
1516 char no_rebind = 0;
1517
1518 // Parse options here.
1519 while (argc > 1 && argv[1][0] == '-') {
1520 if (!strcmp(argv[1], "--list"))
1521 list = 1;
1522 else if (!strcmp(argv[1], "--remove"))
1523 remove = 1;
1524 else if (!strcmp(argv[1], "--remove-all"))
1525 remove_all = 1;
1526 else if (!strcmp(argv[1], "--no-rebind"))
1527 no_rebind = 1;
1528 else {
1529 return usage();
1530 }
1531 argc--;
1532 argv++;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001533 }
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001534
1535 // Ensure we can only use one option at a time.
1536 if (list + remove + remove_all + no_rebind > 1) {
1537 return usage();
1538 }
1539
1540 // Determine the <host-prefix> for this command.
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001541 if (reverse) {
1542 snprintf(host_prefix, sizeof host_prefix, "reverse");
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001543 } else {
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001544 if (serial) {
1545 snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
1546 serial);
1547 } else if (ttype == kTransportUsb) {
1548 snprintf(host_prefix, sizeof host_prefix, "host-usb");
1549 } else if (ttype == kTransportLocal) {
1550 snprintf(host_prefix, sizeof host_prefix, "host-local");
1551 } else {
1552 snprintf(host_prefix, sizeof host_prefix, "host");
1553 }
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001554 }
1555
1556 // Implement forward --list
1557 if (list) {
1558 if (argc != 1)
1559 return usage();
1560 snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);
1561 char* forwards = adb_query(buf);
1562 if (forwards == NULL) {
1563 fprintf(stderr, "error: %s\n", adb_error());
1564 return 1;
1565 }
1566 printf("%s", forwards);
1567 free(forwards);
1568 return 0;
1569 }
1570
1571 // Implement forward --remove-all
1572 else if (remove_all) {
1573 if (argc != 1)
1574 return usage();
1575 snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);
1576 }
1577
1578 // Implement forward --remove <local>
1579 else if (remove) {
1580 if (argc != 2)
1581 return usage();
1582 snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);
1583 }
1584 // Or implement one of:
1585 // forward <local> <remote>
1586 // forward --no-rebind <local> <remote>
1587 else
1588 {
1589 if (argc != 3)
1590 return usage();
1591 const char* command = no_rebind ? "forward:norebind:" : "forward";
1592 snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
1593 }
1594
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001595 if(adb_command(buf)) {
1596 fprintf(stderr,"error: %s\n", adb_error());
1597 return 1;
1598 }
1599 return 0;
1600 }
1601
1602 /* do_sync_*() commands */
1603
1604 if(!strcmp(argv[0], "ls")) {
1605 if(argc != 2) return usage();
1606 return do_sync_ls(argv[1]);
1607 }
1608
1609 if(!strcmp(argv[0], "push")) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001610 int show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001611 int copy_attrs = 0; // unused
Mark Lindner9f9d1452014-03-11 17:55:59 -07001612 const char* lpath = NULL, *rpath = NULL;
1613
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001614 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001615
1616 if ((lpath != NULL) && (rpath != NULL)) {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001617 return do_sync_push(lpath, rpath, show_progress);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001618 }
1619
1620 return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001621 }
1622
1623 if(!strcmp(argv[0], "pull")) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001624 int show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001625 int copy_attrs = 0;
Mark Lindner9f9d1452014-03-11 17:55:59 -07001626 const char* rpath = NULL, *lpath = ".";
1627
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001628 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001629
1630 if (rpath != NULL) {
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001631 return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
Joe Onorato23595b02010-01-05 13:42:25 -08001632 }
Mark Lindner9f9d1452014-03-11 17:55:59 -07001633
1634 return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001635 }
1636
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001637 if (!strcmp(argv[0], "install")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001638 if (argc < 2) return usage();
1639 return install_app(ttype, serial, argc, argv);
1640 }
1641
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001642 if (!strcmp(argv[0], "install-multiple")) {
1643 if (argc < 2) return usage();
1644 return install_multiple_app(ttype, serial, argc, argv);
1645 }
1646
1647 if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001648 if (argc < 2) return usage();
1649 return uninstall_app(ttype, serial, argc, argv);
1650 }
1651
1652 if(!strcmp(argv[0], "sync")) {
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001653 char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath;
Anthony Newnamdd2db142010-02-22 08:36:49 -06001654 int listonly = 0;
1655
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001656 int ret;
1657 if(argc < 2) {
1658 /* No local path was specified. */
1659 srcarg = NULL;
Anthony Newnamdd2db142010-02-22 08:36:49 -06001660 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1661 listonly = 1;
1662 if (argc == 3) {
1663 srcarg = argv[2];
1664 } else {
1665 srcarg = NULL;
1666 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001667 } else if(argc == 2) {
1668 /* A local path or "android"/"data" arg was specified. */
1669 srcarg = argv[1];
1670 } else {
1671 return usage();
1672 }
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001673 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001674 if(ret != 0) return usage();
1675
1676 if(android_srcpath != NULL)
Anthony Newnamdd2db142010-02-22 08:36:49 -06001677 ret = do_sync_sync(android_srcpath, "/system", listonly);
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001678 if(ret == 0 && vendor_srcpath != NULL)
1679 ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001680 if(ret == 0 && data_srcpath != NULL)
Anthony Newnamdd2db142010-02-22 08:36:49 -06001681 ret = do_sync_sync(data_srcpath, "/data", listonly);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001682
1683 free(android_srcpath);
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001684 free(vendor_srcpath);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001685 free(data_srcpath);
1686 return ret;
1687 }
1688
1689 /* passthrough commands */
1690
1691 if(!strcmp(argv[0],"get-state") ||
Scott Anderson6dfaf4b2012-04-20 11:21:14 -07001692 !strcmp(argv[0],"get-serialno") ||
1693 !strcmp(argv[0],"get-devpath"))
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001694 {
1695 char *tmp;
1696
1697 format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1698 tmp = adb_query(buf);
1699 if(tmp) {
1700 printf("%s\n", tmp);
1701 return 0;
1702 } else {
1703 return 1;
1704 }
1705 }
1706
1707 /* other commands */
1708
1709 if(!strcmp(argv[0],"status-window")) {
1710 status_window(ttype, serial);
1711 return 0;
1712 }
1713
Christopher Tate7b9b5162011-11-30 13:00:33 -08001714 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001715 return logcat(ttype, serial, argc, argv);
1716 }
1717
1718 if(!strcmp(argv[0],"ppp")) {
1719 return ppp(argc, argv);
1720 }
1721
1722 if (!strcmp(argv[0], "start-server")) {
1723 return adb_connect("host:start-server");
1724 }
1725
Christopher Tate73779122011-04-21 12:53:28 -07001726 if (!strcmp(argv[0], "backup")) {
1727 return backup(argc, argv);
1728 }
1729
Christopher Tatecf5379b2011-05-17 15:52:54 -07001730 if (!strcmp(argv[0], "restore")) {
1731 return restore(argc, argv);
1732 }
1733
Nick Kralevich6183c962014-11-13 15:17:29 -08001734 if (!strcmp(argv[0], "keygen")) {
1735 if (argc < 2) return usage();
1736 return adb_auth_keygen(argv[1]);
1737 }
1738
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001739 if (!strcmp(argv[0], "jdwp")) {
1740 int fd = adb_connect("jdwp");
1741 if (fd >= 0) {
1742 read_and_dump(fd);
1743 adb_close(fd);
1744 return 0;
1745 } else {
1746 fprintf(stderr, "error: %s\n", adb_error());
1747 return -1;
1748 }
1749 }
1750
1751 /* "adb /?" is a common idiom under Windows */
1752 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1753 help();
1754 return 0;
1755 }
1756
1757 if(!strcmp(argv[0], "version")) {
1758 version(stdout);
1759 return 0;
1760 }
1761
1762 usage();
1763 return 1;
1764}
1765
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001766#define MAX_ARGV_LENGTH 16
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001767static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1768{
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001769 char *argv[MAX_ARGV_LENGTH];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001770 int argc;
1771 va_list ap;
1772
1773 va_start(ap, cmd);
1774 argc = 0;
1775
1776 if (serial) {
1777 argv[argc++] = "-s";
1778 argv[argc++] = serial;
1779 } else if (ttype == kTransportUsb) {
1780 argv[argc++] = "-d";
1781 } else if (ttype == kTransportLocal) {
1782 argv[argc++] = "-e";
1783 }
1784
1785 argv[argc++] = cmd;
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001786 while(argc < MAX_ARGV_LENGTH &&
1787 (argv[argc] = va_arg(ap, char*)) != 0) argc++;
1788 assert(argc < MAX_ARGV_LENGTH);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001789 va_end(ap);
1790
1791#if 0
1792 int n;
1793 fprintf(stderr,"argc = %d\n",argc);
1794 for(n = 0; n < argc; n++) {
1795 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1796 }
1797#endif
1798
1799 return adb_commandline(argc, argv);
1800}
1801
1802int find_sync_dirs(const char *srcarg,
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001803 char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001804{
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001805 char *android_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL;
1806 struct stat st;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001807
1808 if(srcarg == NULL) {
1809 android_srcdir = product_file("system");
1810 data_srcdir = product_file("data");
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001811 vendor_srcdir = product_file("vendor");
1812 /* Check if vendor partition exists */
1813 if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
1814 vendor_srcdir = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001815 } else {
1816 /* srcarg may be "data", "system" or NULL.
1817 * if srcarg is NULL, then both data and system are synced
1818 */
1819 if(strcmp(srcarg, "system") == 0) {
1820 android_srcdir = product_file("system");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001821 } else if(strcmp(srcarg, "data") == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001822 data_srcdir = product_file("data");
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001823 } else if(strcmp(srcarg, "vendor") == 0) {
1824 vendor_srcdir = product_file("vendor");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001825 } else {
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001826 /* It's not "system", "vendor", or "data".
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001827 */
1828 return 1;
1829 }
1830 }
1831
1832 if(android_srcdir_out != NULL)
1833 *android_srcdir_out = android_srcdir;
1834 else
1835 free(android_srcdir);
1836
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001837 if(vendor_srcdir_out != NULL)
1838 *vendor_srcdir_out = vendor_srcdir;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001839 else
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001840 free(vendor_srcdir);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001841
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001842 if(data_srcdir_out != NULL)
1843 *data_srcdir_out = data_srcdir;
1844 else
1845 free(data_srcdir);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001846 return 0;
1847}
1848
1849static int pm_command(transport_type transport, char* serial,
1850 int argc, char** argv)
1851{
1852 char buf[4096];
1853
1854 snprintf(buf, sizeof(buf), "shell:pm");
1855
1856 while(argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001857 char *quoted = escape_arg(*argv++);
Jeff Sharkey824d1062014-06-10 11:31:24 -07001858 strncat(buf, " ", sizeof(buf) - 1);
1859 strncat(buf, quoted, sizeof(buf) - 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001860 free(quoted);
1861 }
1862
1863 send_shellcommand(transport, serial, buf);
1864 return 0;
1865}
1866
1867int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1868{
1869 /* if the user choose the -k option, we refuse to do it until devices are
1870 out with the option to uninstall the remaining data somehow (adb/ui) */
1871 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1872 {
1873 printf(
1874 "The -k option uninstalls the application while retaining the data/cache.\n"
1875 "At the moment, there is no way to remove the remaining data.\n"
1876 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1877 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1878 return -1;
1879 }
1880
1881 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1882 return pm_command(transport, serial, argc, argv);
1883}
1884
1885static int delete_file(transport_type transport, char* serial, char* filename)
1886{
1887 char buf[4096];
1888 char* quoted;
1889
Jeff Sharkeyce474652014-09-09 12:38:30 -07001890 snprintf(buf, sizeof(buf), "shell:rm -f ");
Jeff Sharkey026d9622014-06-10 16:22:17 -07001891 quoted = escape_arg(filename);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001892 strncat(buf, quoted, sizeof(buf)-1);
1893 free(quoted);
1894
1895 send_shellcommand(transport, serial, buf);
1896 return 0;
1897}
1898
Kenny Root3802c992011-08-05 11:19:45 -07001899static const char* get_basename(const char* filename)
1900{
1901 const char* basename = adb_dirstop(filename);
1902 if (basename) {
1903 basename++;
1904 return basename;
1905 } else {
1906 return filename;
1907 }
1908}
1909
Kenny Root3802c992011-08-05 11:19:45 -07001910int install_app(transport_type transport, char* serial, int argc, char** argv)
1911{
1912 static const char *const DATA_DEST = "/data/local/tmp/%s";
1913 static const char *const SD_DEST = "/sdcard/tmp/%s";
1914 const char* where = DATA_DEST;
Kenny Root3802c992011-08-05 11:19:45 -07001915 int i;
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001916 struct stat sb;
Kenny Root3802c992011-08-05 11:19:45 -07001917
1918 for (i = 1; i < argc; i++) {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001919 if (!strcmp(argv[i], "-s")) {
Kenny Root3802c992011-08-05 11:19:45 -07001920 where = SD_DEST;
1921 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001922 }
1923
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001924 // Find last APK argument.
1925 // All other arguments passed through verbatim.
1926 int last_apk = -1;
1927 for (i = argc - 1; i >= 0; i--) {
1928 char* file = argv[i];
1929 char* dot = strrchr(file, '.');
1930 if (dot && !strcasecmp(dot, ".apk")) {
1931 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1932 fprintf(stderr, "Invalid APK file: %s\n", file);
1933 return -1;
1934 }
1935
1936 last_apk = i;
1937 break;
1938 }
Kenny Root3802c992011-08-05 11:19:45 -07001939 }
1940
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001941 if (last_apk == -1) {
1942 fprintf(stderr, "Missing APK file\n");
1943 return -1;
Kenny Root3802c992011-08-05 11:19:45 -07001944 }
1945
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001946 char* apk_file = argv[last_apk];
1947 char apk_dest[PATH_MAX];
Kenny Root3802c992011-08-05 11:19:45 -07001948 snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001949 int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */);
Kenny Root3802c992011-08-05 11:19:45 -07001950 if (err) {
Kenny Root58d5f222012-03-26 16:14:02 -07001951 goto cleanup_apk;
Kenny Root3802c992011-08-05 11:19:45 -07001952 } else {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001953 argv[last_apk] = apk_dest; /* destination name, not source location */
Kenny Root3802c992011-08-05 11:19:45 -07001954 }
1955
1956 pm_command(transport, serial, argc, argv);
1957
Kenny Root58d5f222012-03-26 16:14:02 -07001958cleanup_apk:
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001959 delete_file(transport, serial, apk_dest);
1960 return err;
1961}
1962
1963int install_multiple_app(transport_type transport, char* serial, int argc, char** argv)
1964{
1965 char buf[1024];
1966 int i;
1967 struct stat sb;
1968 unsigned long long total_size = 0;
1969
1970 // Find all APK arguments starting at end.
1971 // All other arguments passed through verbatim.
1972 int first_apk = -1;
1973 for (i = argc - 1; i >= 0; i--) {
1974 char* file = argv[i];
1975 char* dot = strrchr(file, '.');
1976 if (dot && !strcasecmp(dot, ".apk")) {
1977 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1978 fprintf(stderr, "Invalid APK file: %s\n", file);
1979 return -1;
1980 }
1981
1982 total_size += sb.st_size;
1983 first_apk = i;
1984 } else {
1985 break;
1986 }
Kenny Root3802c992011-08-05 11:19:45 -07001987 }
1988
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001989 if (first_apk == -1) {
1990 fprintf(stderr, "Missing APK file\n");
1991 return 1;
1992 }
Kenny Root3802c992011-08-05 11:19:45 -07001993
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001994 snprintf(buf, sizeof(buf), "exec:pm install-create -S %lld", total_size);
1995 for (i = 1; i < first_apk; i++) {
1996 char *quoted = escape_arg(argv[i]);
1997 strncat(buf, " ", sizeof(buf) - 1);
1998 strncat(buf, quoted, sizeof(buf) - 1);
1999 free(quoted);
2000 }
2001
2002 // Create install session
2003 int fd = adb_connect(buf);
2004 if (fd < 0) {
2005 fprintf(stderr, "Connect error for create: %s\n", adb_error());
2006 return -1;
2007 }
2008 read_status_line(fd, buf, sizeof(buf));
2009 adb_close(fd);
2010
2011 int session_id = -1;
2012 if (!strncmp("Success", buf, 7)) {
2013 char* start = strrchr(buf, '[');
2014 char* end = strrchr(buf, ']');
2015 if (start && end) {
2016 *end = '\0';
2017 session_id = strtol(start + 1, NULL, 10);
2018 }
2019 }
2020 if (session_id < 0) {
2021 fprintf(stderr, "Failed to create session\n");
Christopher Tate29721da2014-07-14 16:45:13 -07002022 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002023 return -1;
2024 }
2025
2026 // Valid session, now stream the APKs
2027 int success = 1;
2028 for (i = first_apk; i < argc; i++) {
2029 char* file = argv[i];
2030 if (stat(file, &sb) == -1) {
2031 fprintf(stderr, "Failed to stat %s\n", file);
2032 success = 0;
2033 goto finalize_session;
2034 }
2035
2036 snprintf(buf, sizeof(buf), "exec:pm install-write -S %lld %d %d_%s -",
Jeff Sharkey4a7ddb62014-07-14 13:57:54 -07002037 (long long int) sb.st_size, session_id, i, get_basename(file));
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002038
2039 int localFd = adb_open(file, O_RDONLY);
2040 if (localFd < 0) {
2041 fprintf(stderr, "Failed to open %s: %s\n", file, adb_error());
2042 success = 0;
2043 goto finalize_session;
2044 }
2045
2046 int remoteFd = adb_connect(buf);
2047 if (remoteFd < 0) {
2048 fprintf(stderr, "Connect error for write: %s\n", adb_error());
2049 adb_close(localFd);
2050 success = 0;
2051 goto finalize_session;
2052 }
2053
2054 copy_to_file(localFd, remoteFd);
2055 read_status_line(remoteFd, buf, sizeof(buf));
2056
2057 adb_close(localFd);
2058 adb_close(remoteFd);
2059
2060 if (strncmp("Success", buf, 7)) {
2061 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate29721da2014-07-14 16:45:13 -07002062 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002063 success = 0;
2064 goto finalize_session;
2065 }
2066 }
2067
2068finalize_session:
Jeff Sharkey01f6fbf2014-07-25 09:58:25 -07002069 // Commit session if we streamed everything okay; otherwise abandon
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002070 if (success) {
2071 snprintf(buf, sizeof(buf), "exec:pm install-commit %d", session_id);
2072 } else {
Jeff Sharkey01f6fbf2014-07-25 09:58:25 -07002073 snprintf(buf, sizeof(buf), "exec:pm install-abandon %d", session_id);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002074 }
2075
2076 fd = adb_connect(buf);
2077 if (fd < 0) {
2078 fprintf(stderr, "Connect error for finalize: %s\n", adb_error());
2079 return -1;
2080 }
2081 read_status_line(fd, buf, sizeof(buf));
2082 adb_close(fd);
2083
2084 if (!strncmp("Success", buf, 7)) {
Christopher Tate29721da2014-07-14 16:45:13 -07002085 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002086 return 0;
2087 } else {
2088 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate29721da2014-07-14 16:45:13 -07002089 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002090 return -1;
2091 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08002092}