blob: aa97eb45ab844f062dffdaefa63204cda296c163 [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"
Nick Kralevich6183c962014-11-13 15:17:29 -0800193 " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n"
194 " and the public key is stored in <file>.pub. Any existing files\n"
195 " are overwritten.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800196 " adb help - show this help message\n"
197 " adb version - show version num\n"
198 "\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800199 "scripting:\n"
200 " adb wait-for-device - block until device is online\n"
201 " adb start-server - ensure that there is a server running\n"
202 " adb kill-server - kill the server if it is running\n"
203 " adb get-state - prints: offline | bootloader | device\n"
204 " adb get-serialno - prints: <serial-number>\n"
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700205 " adb get-devpath - prints: <device-path>\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800206 " adb status-window - continuously print device status for a specified device\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700207 " adb remount - remounts the /system and /vendor (if present) partitions on the device read-write\n"
Mike Lockwood12a35ea2009-08-04 20:37:51 -0400208 " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
Romain Guyf925d912009-12-14 14:42:17 -0800209 " adb reboot-bootloader - reboots the device into the bootloader\n"
Mike Lockwood26b88e32009-08-24 15:58:40 -0700210 " adb root - restarts the adbd daemon with root permissions\n"
Romain Guyf925d912009-12-14 14:42:17 -0800211 " adb usb - restarts the adbd daemon listening on USB\n"
Mike Lockwood26b88e32009-08-24 15:58:40 -0700212 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800213 "\n"
214 "networking:\n"
215 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
Kenny Rootf8eb5782009-06-08 14:40:30 -0500216 " Note: you should not automatically start a PPP connection.\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800217 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
218 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
219 "\n"
220 "adb sync notes: adb sync [ <directory> ]\n"
221 " <localdir> can be interpreted in several ways:\n"
222 "\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700223 " - 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 -0800224 "\n"
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -0700225 " - If it is \"system\", \"vendor\" or \"data\", only the corresponding partition\n"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800226 " is updated.\n"
Tim1b29ed32010-02-16 20:18:29 +0000227 "\n"
228 "environmental variables:\n"
229 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
230 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
231 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
232 " 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 -0800233 );
234}
235
236int usage()
237{
238 help();
239 return 1;
240}
241
Yabin Cui6704a3c2014-11-17 14:48:25 -0800242#if defined(_WIN32)
243
244// Windows does not have <termio.h>.
245static void stdin_raw_init(int fd) {
246
247}
248
249static void stdin_raw_restore(int fd) {
250
251}
252
253#else
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800254static struct termios tio_save;
255
256static void stdin_raw_init(int fd)
257{
258 struct termios tio;
259
260 if(tcgetattr(fd, &tio)) return;
261 if(tcgetattr(fd, &tio_save)) return;
262
263 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
264
265 /* no timeout but request at least one character per read */
266 tio.c_cc[VTIME] = 0;
267 tio.c_cc[VMIN] = 1;
268
269 tcsetattr(fd, TCSANOW, &tio);
270 tcflush(fd, TCIFLUSH);
271}
272
273static void stdin_raw_restore(int fd)
274{
275 tcsetattr(fd, TCSANOW, &tio_save);
276 tcflush(fd, TCIFLUSH);
277}
278#endif
279
280static void read_and_dump(int fd)
281{
282 char buf[4096];
283 int len;
284
285 while(fd >= 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700286 D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800287 len = adb_read(fd, buf, 4096);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700288 D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800289 if(len == 0) {
290 break;
291 }
292
293 if(len < 0) {
294 if(errno == EINTR) continue;
295 break;
296 }
Mike Lockwood597ea9a2009-09-22 01:18:40 -0400297 fwrite(buf, 1, len, stdout);
298 fflush(stdout);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800299 }
300}
301
Jeff Sharkey0e0d2512014-06-09 17:30:57 -0700302static void read_status_line(int fd, char* buf, size_t count)
303{
304 count--;
305 while (count > 0) {
306 int len = adb_read(fd, buf, count);
307 if (len == 0) {
308 break;
309 } else if (len < 0) {
310 if (errno == EINTR) continue;
311 break;
312 }
313
314 buf += len;
315 count -= len;
316 }
317 *buf = '\0';
318}
319
Christopher Tate73779122011-04-21 12:53:28 -0700320static void copy_to_file(int inFd, int outFd) {
Christopher Tatea162e242011-06-10 11:38:37 -0700321 const size_t BUFSIZE = 32 * 1024;
322 char* buf = (char*) malloc(BUFSIZE);
Christopher Tate73779122011-04-21 12:53:28 -0700323 int len;
Christopher Tatefba22972011-06-01 17:56:23 -0700324 long total = 0;
Christopher Tate73779122011-04-21 12:53:28 -0700325
326 D("copy_to_file(%d -> %d)\n", inFd, outFd);
Yabin Cui6704a3c2014-11-17 14:48:25 -0800327
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700328 if (inFd == STDIN_FILENO) {
329 stdin_raw_init(STDIN_FILENO);
330 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800331
Christopher Tate73779122011-04-21 12:53:28 -0700332 for (;;) {
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700333 if (inFd == STDIN_FILENO) {
334 len = unix_read(inFd, buf, BUFSIZE);
335 } else {
336 len = adb_read(inFd, buf, BUFSIZE);
337 }
Christopher Tate73779122011-04-21 12:53:28 -0700338 if (len == 0) {
Christopher Tatea162e242011-06-10 11:38:37 -0700339 D("copy_to_file() : read 0 bytes; exiting\n");
Christopher Tate73779122011-04-21 12:53:28 -0700340 break;
341 }
342 if (len < 0) {
Christopher Tatea162e242011-06-10 11:38:37 -0700343 if (errno == EINTR) {
344 D("copy_to_file() : EINTR, retrying\n");
345 continue;
346 }
Christopher Tate73779122011-04-21 12:53:28 -0700347 D("copy_to_file() : error %d\n", errno);
348 break;
349 }
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700350 if (outFd == STDOUT_FILENO) {
351 fwrite(buf, 1, len, stdout);
352 fflush(stdout);
353 } else {
354 adb_write(outFd, buf, len);
355 }
Christopher Tatefba22972011-06-01 17:56:23 -0700356 total += len;
Christopher Tate73779122011-04-21 12:53:28 -0700357 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800358
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -0700359 if (inFd == STDIN_FILENO) {
360 stdin_raw_restore(STDIN_FILENO);
361 }
Yabin Cui6704a3c2014-11-17 14:48:25 -0800362
Christopher Tatefba22972011-06-01 17:56:23 -0700363 D("copy_to_file() finished after %lu bytes\n", total);
Christopher Tatea162e242011-06-10 11:38:37 -0700364 free(buf);
Christopher Tate73779122011-04-21 12:53:28 -0700365}
366
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800367static void *stdin_read_thread(void *x)
368{
369 int fd, fdi;
370 unsigned char buf[1024];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800371 int r, n;
372 int state = 0;
373
374 int *fds = (int*) x;
375 fd = fds[0];
376 fdi = fds[1];
377 free(fds);
378
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800379 for(;;) {
380 /* fdi is really the client's stdin, so use read, not adb_read here */
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700381 D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800382 r = unix_read(fdi, buf, 1024);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700383 D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800384 if(r == 0) break;
385 if(r < 0) {
386 if(errno == EINTR) continue;
387 break;
388 }
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400389 for(n = 0; n < r; n++){
390 switch(buf[n]) {
391 case '\n':
392 state = 1;
393 break;
394 case '\r':
395 state = 1;
396 break;
397 case '~':
398 if(state == 1) state++;
399 break;
400 case '.':
401 if(state == 2) {
402 fprintf(stderr,"\n* disconnect *\n");
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400403 stdin_raw_restore(fdi);
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400404 exit(0);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800405 }
Mike Lockwood18ab0d62010-05-25 13:40:15 -0400406 default:
407 state = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800408 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800409 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800410 r = adb_write(fd, buf, r);
411 if(r <= 0) {
412 break;
413 }
414 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800415 return 0;
416}
417
418int interactive_shell(void)
419{
420 adb_thread_t thr;
421 int fdi, fd;
422 int *fds;
423
424 fd = adb_connect("shell:");
425 if(fd < 0) {
426 fprintf(stderr,"error: %s\n", adb_error());
427 return 1;
428 }
429 fdi = 0; //dup(0);
430
431 fds = malloc(sizeof(int) * 2);
432 fds[0] = fd;
433 fds[1] = fdi;
434
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800435 stdin_raw_init(fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800436 adb_thread_create(&thr, stdin_read_thread, fds);
437 read_and_dump(fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800438 stdin_raw_restore(fdi);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800439 return 0;
440}
441
442
443static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial)
444{
445 if (serial) {
446 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
447 } else {
448 const char* prefix = "host";
449 if (ttype == kTransportUsb)
450 prefix = "host-usb";
451 else if (ttype == kTransportLocal)
452 prefix = "host-local";
453
454 snprintf(buffer, buflen, "%s:%s", prefix, command);
455 }
456}
457
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100458int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
Doug Zongker6b217ed2012-01-09 14:54:53 -0800459 unsigned progress)
460{
461 char buf[4096];
462 unsigned total;
463 int fd;
464 const unsigned char *ptr;
465
466 sprintf(buf,"%s:%d", service, sz);
467 fd = adb_connect(buf);
468 if(fd < 0) {
469 fprintf(stderr,"error: %s\n", adb_error());
470 return -1;
471 }
472
473 int opt = CHUNK_SIZE;
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700474 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
Doug Zongker6b217ed2012-01-09 14:54:53 -0800475
476 total = sz;
477 ptr = data;
478
479 if(progress) {
480 char *x = strrchr(service, ':');
481 if(x) service = x + 1;
482 }
483
484 while(sz > 0) {
485 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
486 if(writex(fd, ptr, xfer)) {
487 adb_status(fd);
488 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
489 return -1;
490 }
491 sz -= xfer;
492 ptr += xfer;
493 if(progress) {
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100494 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
Doug Zongker6b217ed2012-01-09 14:54:53 -0800495 fflush(stdout);
496 }
497 }
498 if(progress) {
499 printf("\n");
500 }
501
502 if(readx(fd, buf, 4)){
503 fprintf(stderr,"* error reading response *\n");
504 adb_close(fd);
505 return -1;
506 }
507 if(memcmp(buf, "OKAY", 4)) {
508 buf[4] = 0;
509 fprintf(stderr,"* error response '%s' *\n", buf);
510 adb_close(fd);
511 return -1;
512 }
513
514 adb_close(fd);
515 return 0;
516}
517
518
519int adb_download(const char *service, const char *fn, unsigned progress)
520{
521 void *data;
522 unsigned sz;
523
524 data = load_file(fn, &sz);
525 if(data == 0) {
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100526 fprintf(stderr,"* cannot read '%s' *\n", fn);
Doug Zongker6b217ed2012-01-09 14:54:53 -0800527 return -1;
528 }
529
Magnus Erikssoncb30cc62013-03-05 07:37:32 +0100530 int status = adb_download_buffer(service, fn, data, sz, progress);
Doug Zongker6b217ed2012-01-09 14:54:53 -0800531 free(data);
532 return status;
533}
534
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700535#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
536
537/*
538 * The sideload-host protocol serves the data in a file (given on the
539 * command line) to the client, using a simple protocol:
540 *
541 * - The connect message includes the total number of bytes in the
542 * file and a block size chosen by us.
543 *
544 * - The other side sends the desired block number as eight decimal
545 * digits (eg "00000023" for block 23). Blocks are numbered from
546 * zero.
547 *
548 * - We send back the data of the requested block. The last block is
549 * likely to be partial; when the last block is requested we only
550 * send the part of the block that exists, it's not padded up to the
551 * block size.
552 *
553 * - When the other side sends "DONEDONE" instead of a block number,
554 * we hang up.
555 */
556int adb_sideload_host(const char* fn) {
557 uint8_t* data;
558 unsigned sz;
559 size_t xfer = 0;
560 int status;
561
562 printf("loading: '%s'", fn);
563 fflush(stdout);
564 data = load_file(fn, &sz);
565 if (data == 0) {
566 printf("\n");
567 fprintf(stderr, "* cannot read '%s' *\n", fn);
568 return -1;
569 }
570
571 char buf[100];
572 sprintf(buf, "sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE);
573 int fd = adb_connect(buf);
574 if (fd < 0) {
575 // Try falling back to the older sideload method. Maybe this
576 // is an older device that doesn't support sideload-host.
577 printf("\n");
578 status = adb_download_buffer("sideload", fn, data, sz, 1);
579 goto done;
580 }
581
582 int opt = SIDELOAD_HOST_BLOCK_SIZE;
583 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
584
585 int last_percent = -1;
Doug Zongkera27ee6c2014-07-07 15:28:43 -0700586 for (;;) {
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700587 if (readx(fd, buf, 8)) {
588 fprintf(stderr, "* failed to read command: %s\n", adb_error());
589 status = -1;
590 goto done;
591 }
592
593 if (strncmp("DONEDONE", buf, 8) == 0) {
594 status = 0;
595 break;
596 }
597
598 buf[8] = '\0';
599 int block = strtol(buf, NULL, 10);
600
601 size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
602 if (offset >= sz) {
603 fprintf(stderr, "* attempt to read past end: %s\n", adb_error());
604 status = -1;
605 goto done;
606 }
607 uint8_t* start = data + offset;
608 size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE;
609 size_t to_write = SIDELOAD_HOST_BLOCK_SIZE;
610 if (offset_end > sz) {
611 to_write = sz - offset;
612 }
613
614 if(writex(fd, start, to_write)) {
615 adb_status(fd);
616 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
617 status = -1;
618 goto done;
619 }
620 xfer += to_write;
621
622 // For normal OTA packages, we expect to transfer every byte
623 // twice, plus a bit of overhead (one read during
624 // verification, one read of each byte for installation, plus
625 // extra access to things like the zip central directory).
626 // This estimate of the completion becomes 100% when we've
627 // transferred ~2.13 (=100/47) times the package size.
628 int percent = (int)(xfer * 47LL / (sz ? sz : 1));
629 if (percent != last_percent) {
630 printf("\rserving: '%s' (~%d%%) ", fn, percent);
631 fflush(stdout);
632 last_percent = percent;
633 }
634 }
635
Colin Cross2328bea2014-07-07 14:12:41 -0700636 printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, "");
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700637
638 done:
639 if (fd >= 0) adb_close(fd);
640 free(data);
641 return status;
642}
643
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800644static void status_window(transport_type ttype, const char* serial)
645{
646 char command[4096];
647 char *state = 0;
648 char *laststate = 0;
649
650 /* silence stderr */
651#ifdef _WIN32
652 /* XXX: TODO */
653#else
654 int fd;
655 fd = unix_open("/dev/null", O_WRONLY);
656 dup2(fd, 2);
657 adb_close(fd);
658#endif
659
660 format_host_command(command, sizeof command, "get-state", ttype, serial);
661
662 for(;;) {
663 adb_sleep_ms(250);
664
665 if(state) {
666 free(state);
667 state = 0;
668 }
669
670 state = adb_query(command);
671
672 if(state) {
673 if(laststate && !strcmp(state,laststate)){
674 continue;
675 } else {
676 if(laststate) free(laststate);
677 laststate = strdup(state);
678 }
679 }
680
681 printf("%c[2J%c[2H", 27, 27);
682 printf("Android Debug Bridge\n");
683 printf("State: %s\n", state ? state : "offline");
684 fflush(stdout);
685 }
686}
687
Brian Carlstrom529fca82014-08-05 22:51:18 -0700688static int should_escape(const char c)
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700689{
690 return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
691}
692
693/* Duplicate and escape given argument. */
Jeff Sharkey026d9622014-06-10 16:22:17 -0700694static char *escape_arg(const char *s)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800695{
696 const char *ts;
697 size_t alloc_len;
698 char *ret;
699 char *dest;
700
Jeff Sharkey026d9622014-06-10 16:22:17 -0700701 alloc_len = 0;
Jeff Sharkey824d1062014-06-10 11:31:24 -0700702 for (ts = s; *ts != '\0'; ts++) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800703 alloc_len++;
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700704 if (should_escape(*ts)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800705 alloc_len++;
706 }
707 }
708
Jeff Sharkey026d9622014-06-10 16:22:17 -0700709 if (alloc_len == 0) {
710 // Preserve empty arguments
711 ret = (char *) malloc(3);
712 ret[0] = '\"';
713 ret[1] = '\"';
714 ret[2] = '\0';
715 return ret;
716 }
717
Jeff Sharkey824d1062014-06-10 11:31:24 -0700718 ret = (char *) malloc(alloc_len + 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800719 dest = ret;
720
Jeff Sharkey824d1062014-06-10 11:31:24 -0700721 for (ts = s; *ts != '\0'; ts++) {
Jeff Sharkeyde7cad82014-08-05 16:53:08 -0700722 if (should_escape(*ts)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800723 *dest++ = '\\';
724 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800725 *dest++ = *ts;
726 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800727 *dest++ = '\0';
728
729 return ret;
730}
731
732/**
733 * Run ppp in "notty" mode against a resource listed as the first parameter
734 * eg:
735 *
736 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
737 *
738 */
739int ppp(int argc, char **argv)
740{
Yabin Cui2fa43212014-11-11 09:24:11 -0800741#if defined(_WIN32)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800742 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
743 return -1;
744#else
745 char *adb_service_name;
746 pid_t pid;
747 int fd;
748
749 if (argc < 2) {
750 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
751 argv[0]);
752
753 return 1;
754 }
755
756 adb_service_name = argv[1];
757
758 fd = adb_connect(adb_service_name);
759
760 if(fd < 0) {
761 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
762 adb_service_name, adb_error());
763 return 1;
764 }
765
766 pid = fork();
767
768 if (pid < 0) {
769 perror("from fork()");
770 return 1;
771 } else if (pid == 0) {
772 int err;
773 int i;
774 const char **ppp_args;
775
776 // copy args
777 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
778 ppp_args[0] = "pppd";
779 for (i = 2 ; i < argc ; i++) {
780 //argv[2] and beyond become ppp_args[1] and beyond
781 ppp_args[i - 1] = argv[i];
782 }
783 ppp_args[i-1] = NULL;
784
785 // child side
786
787 dup2(fd, STDIN_FILENO);
788 dup2(fd, STDOUT_FILENO);
789 adb_close(STDERR_FILENO);
790 adb_close(fd);
791
792 err = execvp("pppd", (char * const *)ppp_args);
793
794 if (err < 0) {
795 perror("execing pppd");
796 }
797 exit(-1);
798 } else {
799 // parent side
800
801 adb_close(fd);
802 return 0;
803 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800804#endif /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800805}
806
807static int send_shellcommand(transport_type transport, char* serial, char* buf)
808{
809 int fd, ret;
810
811 for(;;) {
812 fd = adb_connect(buf);
813 if(fd >= 0)
814 break;
815 fprintf(stderr,"- waiting for device -\n");
816 adb_sleep_ms(1000);
817 do_cmd(transport, serial, "wait-for-device", 0);
818 }
819
820 read_and_dump(fd);
821 ret = adb_close(fd);
822 if (ret)
823 perror("close");
824
825 return ret;
826}
827
828static int logcat(transport_type transport, char* serial, int argc, char **argv)
829{
830 char buf[4096];
831
832 char *log_tags;
Jeff Sharkey824d1062014-06-10 11:31:24 -0700833 char *quoted;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800834
835 log_tags = getenv("ANDROID_LOG_TAGS");
Jeff Sharkey026d9622014-06-10 16:22:17 -0700836 quoted = escape_arg(log_tags == NULL ? "" : log_tags);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800837 snprintf(buf, sizeof(buf),
Jeff Sharkey026d9622014-06-10 16:22:17 -0700838 "shell:export ANDROID_LOG_TAGS=\"%s\"; exec logcat", quoted);
Jeff Sharkey824d1062014-06-10 11:31:24 -0700839 free(quoted);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800840
Jeff Sharkey824d1062014-06-10 11:31:24 -0700841 if (!strcmp(argv[0], "longcat")) {
842 strncat(buf, " -v long", sizeof(buf) - 1);
Christopher Tate7b9b5162011-11-30 13:00:33 -0800843 }
844
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800845 argc -= 1;
846 argv += 1;
847 while(argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -0700848 quoted = escape_arg(*argv++);
Jeff Sharkey824d1062014-06-10 11:31:24 -0700849 strncat(buf, " ", sizeof(buf) - 1);
850 strncat(buf, quoted, sizeof(buf) - 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800851 free(quoted);
852 }
853
854 send_shellcommand(transport, serial, buf);
855 return 0;
856}
857
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700858static int mkdirs(const char *path)
Christopher Tate1e9f2392011-12-08 19:04:34 -0800859{
860 int ret;
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700861 char *x = (char *)path + 1;
Christopher Tate1e9f2392011-12-08 19:04:34 -0800862
863 for(;;) {
864 x = adb_dirstart(x);
865 if(x == 0) return 0;
866 *x = 0;
867 ret = adb_mkdir(path, 0775);
868 *x = OS_PATH_SEPARATOR;
869 if((ret < 0) && (errno != EEXIST)) {
870 return ret;
871 }
872 x++;
873 }
874 return 0;
875}
876
Christopher Tate73779122011-04-21 12:53:28 -0700877static int backup(int argc, char** argv) {
878 char buf[4096];
Christopher Tate1e9f2392011-12-08 19:04:34 -0800879 char default_name[32];
880 const char* filename = strcpy(default_name, "./backup.ab");
Christopher Tate73779122011-04-21 12:53:28 -0700881 int fd, outFd;
Christopher Tatefba22972011-06-01 17:56:23 -0700882 int i, j;
Christopher Tate73779122011-04-21 12:53:28 -0700883
Christopher Tatefba22972011-06-01 17:56:23 -0700884 /* find, extract, and use any -f argument */
885 for (i = 1; i < argc; i++) {
886 if (!strcmp("-f", argv[i])) {
887 if (i == argc-1) {
888 fprintf(stderr, "adb: -f passed with no filename\n");
889 return usage();
890 }
891 filename = argv[i+1];
892 for (j = i+2; j <= argc; ) {
893 argv[i++] = argv[j++];
894 }
895 argc -= 2;
896 argv[argc] = NULL;
897 }
Christopher Tate73779122011-04-21 12:53:28 -0700898 }
899
Christopher Tatecf4f16a2011-08-22 17:12:08 -0700900 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
901 if (argc < 2) return usage();
902
Christopher Tate1e9f2392011-12-08 19:04:34 -0800903 adb_unlink(filename);
Mark Salyzyn63e39f22014-04-30 09:10:31 -0700904 mkdirs(filename);
Christopher Tate1e9f2392011-12-08 19:04:34 -0800905 outFd = adb_creat(filename, 0640);
Christopher Tate73779122011-04-21 12:53:28 -0700906 if (outFd < 0) {
907 fprintf(stderr, "adb: unable to open file %s\n", filename);
908 return -1;
909 }
910
911 snprintf(buf, sizeof(buf), "backup");
912 for (argc--, argv++; argc; argc--, argv++) {
913 strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
914 strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
915 }
916
917 D("backup. filename=%s buf=%s\n", filename, buf);
918 fd = adb_connect(buf);
919 if (fd < 0) {
920 fprintf(stderr, "adb: unable to connect for backup\n");
921 adb_close(outFd);
922 return -1;
923 }
924
Christopher Tate9c829102012-01-06 15:43:03 -0800925 printf("Now unlock your device and confirm the backup operation.\n");
Christopher Tate73779122011-04-21 12:53:28 -0700926 copy_to_file(fd, outFd);
927
928 adb_close(fd);
929 adb_close(outFd);
930 return 0;
931}
932
Christopher Tatecf5379b2011-05-17 15:52:54 -0700933static int restore(int argc, char** argv) {
934 const char* filename;
935 int fd, tarFd;
936
937 if (argc != 2) return usage();
938
939 filename = argv[1];
940 tarFd = adb_open(filename, O_RDONLY);
941 if (tarFd < 0) {
942 fprintf(stderr, "adb: unable to open file %s\n", filename);
943 return -1;
944 }
945
946 fd = adb_connect("restore:");
947 if (fd < 0) {
Brian Carlstromcad81322013-10-18 13:58:48 -0700948 fprintf(stderr, "adb: unable to connect for restore\n");
Christopher Tatecf5379b2011-05-17 15:52:54 -0700949 adb_close(tarFd);
950 return -1;
951 }
952
Christopher Tate9c829102012-01-06 15:43:03 -0800953 printf("Now unlock your device and confirm the restore operation.\n");
Christopher Tatecf5379b2011-05-17 15:52:54 -0700954 copy_to_file(tarFd, fd);
955
956 adb_close(fd);
957 adb_close(tarFd);
958 return 0;
959}
960
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800961#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
962static int top_works(const char *top)
963{
964 if (top != NULL && adb_is_absolute_host_path(top)) {
965 char path_buf[PATH_MAX];
966 snprintf(path_buf, sizeof(path_buf),
967 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
968 return access(path_buf, F_OK) == 0;
969 }
970 return 0;
971}
972
973static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
974{
975 strcpy(path_buf, indir);
976 while (1) {
977 if (top_works(path_buf)) {
978 return path_buf;
979 }
980 char *s = adb_dirstop(path_buf);
981 if (s != NULL) {
982 *s = '\0';
983 } else {
984 path_buf[0] = '\0';
985 return NULL;
986 }
987 }
988}
989
990static char *find_top(char path_buf[PATH_MAX])
991{
992 char *top = getenv("ANDROID_BUILD_TOP");
993 if (top != NULL && top[0] != '\0') {
994 if (!top_works(top)) {
995 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
996 return NULL;
997 }
998 } else {
999 top = getenv("TOP");
1000 if (top != NULL && top[0] != '\0') {
1001 if (!top_works(top)) {
1002 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
1003 return NULL;
1004 }
1005 } else {
1006 top = NULL;
1007 }
1008 }
1009
1010 if (top != NULL) {
1011 /* The environment pointed to a top directory that works.
1012 */
1013 strcpy(path_buf, top);
1014 return path_buf;
1015 }
1016
1017 /* The environment didn't help. Walk up the tree from the CWD
1018 * to see if we can find the top.
1019 */
1020 char dir[PATH_MAX];
1021 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
1022 if (top == NULL) {
1023 /* If the CWD isn't under a good-looking top, see if the
1024 * executable is.
1025 */
Alexey Tarasov857f17a2009-10-22 02:55:00 +11001026 get_my_path(dir, PATH_MAX);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001027 top = find_top_from(dir, path_buf);
1028 }
1029 return top;
1030}
1031
1032/* <hint> may be:
1033 * - A simple product name
1034 * e.g., "sooner"
1035TODO: debug? sooner-debug, sooner:debug?
1036 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
1037 * e.g., "out/target/product/sooner"
1038 * - An absolute path to the PRODUCT_OUT dir
1039 * e.g., "/src/device/out/target/product/sooner"
1040 *
1041 * Given <hint>, try to construct an absolute path to the
1042 * ANDROID_PRODUCT_OUT dir.
1043 */
1044static const char *find_product_out_path(const char *hint)
1045{
1046 static char path_buf[PATH_MAX];
1047
1048 if (hint == NULL || hint[0] == '\0') {
1049 return NULL;
1050 }
1051
1052 /* If it's already absolute, don't bother doing any work.
1053 */
1054 if (adb_is_absolute_host_path(hint)) {
1055 strcpy(path_buf, hint);
1056 return path_buf;
1057 }
1058
1059 /* If there are any slashes in it, assume it's a relative path;
1060 * make it absolute.
1061 */
1062 if (adb_dirstart(hint) != NULL) {
1063 if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
1064 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
1065 return NULL;
1066 }
1067 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
1068 fprintf(stderr, "adb: Couldn't assemble path\n");
1069 return NULL;
1070 }
1071 strcat(path_buf, OS_PATH_SEPARATOR_STR);
1072 strcat(path_buf, hint);
1073 return path_buf;
1074 }
1075
1076 /* It's a string without any slashes. Try to do something with it.
1077 *
1078 * Try to find the root of the build tree, and build a PRODUCT_OUT
1079 * path from there.
1080 */
1081 char top_buf[PATH_MAX];
1082 const char *top = find_top(top_buf);
1083 if (top == NULL) {
1084 fprintf(stderr, "adb: Couldn't find top of build tree\n");
1085 return NULL;
1086 }
1087//TODO: if we have a way to indicate debug, look in out/debug/target/...
1088 snprintf(path_buf, sizeof(path_buf),
1089 "%s" OS_PATH_SEPARATOR_STR
1090 "out" OS_PATH_SEPARATOR_STR
1091 "target" OS_PATH_SEPARATOR_STR
1092 "product" OS_PATH_SEPARATOR_STR
1093 "%s", top_buf, hint);
1094 if (access(path_buf, F_OK) < 0) {
1095 fprintf(stderr, "adb: Couldn't find a product dir "
1096 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
1097 return NULL;
1098 }
1099 return path_buf;
1100}
1101
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001102static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
1103 int *show_progress, int *copy_attrs) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001104 *show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001105 *copy_attrs = 0;
Mark Lindner9f9d1452014-03-11 17:55:59 -07001106
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001107 while (narg > 0) {
1108 if (!strcmp(*arg, "-p")) {
1109 *show_progress = 1;
1110 } else if (!strcmp(*arg, "-a")) {
1111 *copy_attrs = 1;
1112 } else {
1113 break;
1114 }
Mark Lindner9f9d1452014-03-11 17:55:59 -07001115 ++arg;
1116 --narg;
1117 }
1118
1119 if (narg > 0) {
1120 *path1 = *arg;
1121 ++arg;
1122 --narg;
1123 }
1124
1125 if (narg > 0) {
1126 *path2 = *arg;
1127 }
1128}
1129
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001130int adb_commandline(int argc, char **argv)
1131{
1132 char buf[4096];
1133 int no_daemon = 0;
1134 int is_daemon = 0;
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001135 int is_server = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001136 int persist = 0;
1137 int r;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001138 transport_type ttype = kTransportAny;
1139 char* serial = NULL;
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001140 char* server_port_str = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001141
1142 /* If defined, this should be an absolute path to
1143 * the directory containing all of the various system images
1144 * for a particular product. If not defined, and the adb
1145 * command requires this information, then the user must
1146 * specify the path using "-p".
1147 */
1148 gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
1149 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
1150 gProductOutPath = NULL;
1151 }
1152 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
1153
Nick Pellyaf2fe9b2009-05-07 12:48:03 -07001154 serial = getenv("ANDROID_SERIAL");
1155
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001156 /* Validate and assign the server port */
1157 server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
1158 int server_port = DEFAULT_ADB_PORT;
1159 if (server_port_str && strlen(server_port_str) > 0) {
1160 server_port = (int) strtol(server_port_str, NULL, 0);
Matt Gumbel411775c2012-11-14 10:16:17 -08001161 if (server_port <= 0 || server_port > 65535) {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001162 fprintf(stderr,
Matt Gumbel411775c2012-11-14 10:16:17 -08001163 "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 +01001164 server_port_str);
1165 return usage();
1166 }
1167 }
1168
1169 /* modifiers and flags */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001170 while(argc > 0) {
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001171 if(!strcmp(argv[0],"server")) {
1172 is_server = 1;
1173 } else if(!strcmp(argv[0],"nodaemon")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001174 no_daemon = 1;
1175 } else if (!strcmp(argv[0], "fork-server")) {
1176 /* this is a special flag used only when the ADB client launches the ADB Server */
1177 is_daemon = 1;
1178 } else if(!strcmp(argv[0],"persist")) {
1179 persist = 1;
1180 } else if(!strncmp(argv[0], "-p", 2)) {
1181 const char *product = NULL;
1182 if (argv[0][2] == '\0') {
1183 if (argc < 2) return usage();
1184 product = argv[1];
1185 argc--;
1186 argv++;
1187 } else {
Vairavan Srinivasanadc39402012-08-04 16:40:50 -07001188 product = argv[0] + 2;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001189 }
1190 gProductOutPath = find_product_out_path(product);
1191 if (gProductOutPath == NULL) {
1192 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
1193 product);
1194 return usage();
1195 }
1196 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
1197 if (isdigit(argv[0][2])) {
1198 serial = argv[0] + 2;
1199 } else {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001200 if(argc < 2 || argv[0][2] != '\0') return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001201 serial = argv[1];
1202 argc--;
1203 argv++;
1204 }
1205 } else if (!strcmp(argv[0],"-d")) {
1206 ttype = kTransportUsb;
1207 } else if (!strcmp(argv[0],"-e")) {
1208 ttype = kTransportLocal;
Matt Gumbel411775c2012-11-14 10:16:17 -08001209 } else if (!strcmp(argv[0],"-a")) {
1210 gListenAll = 1;
1211 } else if(!strncmp(argv[0], "-H", 2)) {
1212 const char *hostname = NULL;
1213 if (argv[0][2] == '\0') {
1214 if (argc < 2) return usage();
1215 hostname = argv[1];
1216 argc--;
1217 argv++;
1218 } else {
1219 hostname = argv[0] + 2;
1220 }
1221 adb_set_tcp_name(hostname);
1222
1223 } else if(!strncmp(argv[0], "-P", 2)) {
1224 if (argv[0][2] == '\0') {
1225 if (argc < 2) return usage();
1226 server_port_str = argv[1];
1227 argc--;
1228 argv++;
1229 } else {
1230 server_port_str = argv[0] + 2;
1231 }
1232 if (strlen(server_port_str) > 0) {
1233 server_port = (int) strtol(server_port_str, NULL, 0);
1234 if (server_port <= 0 || server_port > 65535) {
1235 fprintf(stderr,
1236 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1237 server_port_str);
1238 return usage();
1239 }
1240 } else {
1241 fprintf(stderr,
1242 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1243 return usage();
1244 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001245 } else {
1246 /* out of recognized modifiers and flags */
1247 break;
1248 }
1249 argc--;
1250 argv++;
1251 }
1252
1253 adb_set_transport(ttype, serial);
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001254 adb_set_tcp_specifics(server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001255
David 'Digit' Turner6826db62011-01-31 14:23:56 +01001256 if (is_server) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001257 if (no_daemon || is_daemon) {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001258 r = adb_main(is_daemon, server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001259 } else {
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +01001260 r = launch_server(server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001261 }
1262 if(r) {
1263 fprintf(stderr,"* could not start server *\n");
1264 }
1265 return r;
1266 }
1267
1268top:
1269 if(argc == 0) {
1270 return usage();
1271 }
1272
1273 /* adb_connect() commands */
1274
1275 if(!strcmp(argv[0], "devices")) {
1276 char *tmp;
Scott Anderson6dfaf4b2012-04-20 11:21:14 -07001277 char *listopt;
1278 if (argc < 2)
1279 listopt = "";
1280 else if (argc == 2 && !strcmp(argv[1], "-l"))
1281 listopt = argv[1];
1282 else {
1283 fprintf(stderr, "Usage: adb devices [-l]\n");
1284 return 1;
1285 }
1286 snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001287 tmp = adb_query(buf);
1288 if(tmp) {
1289 printf("List of devices attached \n");
1290 printf("%s\n", tmp);
1291 return 0;
1292 } else {
1293 return 1;
1294 }
1295 }
1296
Mike Lockwood01c2c302010-05-24 10:44:35 -04001297 if(!strcmp(argv[0], "connect")) {
Mike Lockwood26b88e32009-08-24 15:58:40 -07001298 char *tmp;
1299 if (argc != 2) {
Mike Lockwood01c2c302010-05-24 10:44:35 -04001300 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
Mike Lockwood26b88e32009-08-24 15:58:40 -07001301 return 1;
1302 }
Mike Lockwood01c2c302010-05-24 10:44:35 -04001303 snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
1304 tmp = adb_query(buf);
1305 if(tmp) {
1306 printf("%s\n", tmp);
1307 return 0;
1308 } else {
1309 return 1;
1310 }
1311 }
1312
1313 if(!strcmp(argv[0], "disconnect")) {
1314 char *tmp;
1315 if (argc > 2) {
1316 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1317 return 1;
1318 }
1319 if (argc == 2) {
1320 snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
1321 } else {
1322 snprintf(buf, sizeof buf, "host:disconnect:");
1323 }
Mike Lockwood26b88e32009-08-24 15:58:40 -07001324 tmp = adb_query(buf);
1325 if(tmp) {
1326 printf("%s\n", tmp);
1327 return 0;
1328 } else {
1329 return 1;
1330 }
1331 }
1332
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001333 if (!strcmp(argv[0], "emu")) {
1334 return adb_send_emulator_command(argc, argv);
1335 }
1336
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001337 if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001338 int r;
1339 int fd;
1340
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001341 char h = (argv[0][0] == 'h');
1342
1343 if (h) {
1344 printf("\x1b[41;33m");
1345 fflush(stdout);
1346 }
1347
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001348 if(argc < 2) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001349 D("starting interactive shell\n");
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001350 r = interactive_shell();
1351 if (h) {
1352 printf("\x1b[0m");
1353 fflush(stdout);
1354 }
1355 return r;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001356 }
1357
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001358 snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001359 argc -= 2;
1360 argv += 2;
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001361 while (argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001362 char *quoted = escape_arg(*argv++);
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001363 strncat(buf, " ", sizeof(buf) - 1);
1364 strncat(buf, quoted, sizeof(buf) - 1);
1365 free(quoted);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001366 }
1367
1368 for(;;) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001369 D("interactive shell loop. buff=%s\n", buf);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001370 fd = adb_connect(buf);
1371 if(fd >= 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001372 D("about to read_and_dump(fd=%d)\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001373 read_and_dump(fd);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001374 D("read_and_dump() done.\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001375 adb_close(fd);
1376 r = 0;
1377 } else {
1378 fprintf(stderr,"error: %s\n", adb_error());
1379 r = -1;
1380 }
1381
1382 if(persist) {
1383 fprintf(stderr,"\n- waiting for device -\n");
1384 adb_sleep_ms(1000);
1385 do_cmd(ttype, serial, "wait-for-device", 0);
1386 } else {
Daniel Sandlerd9bc2372010-08-19 01:10:18 -04001387 if (h) {
1388 printf("\x1b[0m");
1389 fflush(stdout);
1390 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -07001391 D("interactive shell loop. return r=%d\n", r);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001392 return r;
1393 }
1394 }
1395 }
1396
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001397 if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
1398 int exec_in = !strcmp(argv[0], "exec-in");
1399 int fd;
1400
1401 snprintf(buf, sizeof buf, "exec:%s", argv[1]);
1402 argc -= 2;
1403 argv += 2;
1404 while (argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001405 char *quoted = escape_arg(*argv++);
Jeff Sharkeyc52ec1a2014-05-26 18:30:43 -07001406 strncat(buf, " ", sizeof(buf) - 1);
1407 strncat(buf, quoted, sizeof(buf) - 1);
1408 free(quoted);
1409 }
1410
1411 fd = adb_connect(buf);
1412 if (fd < 0) {
1413 fprintf(stderr, "error: %s\n", adb_error());
1414 return -1;
1415 }
1416
1417 if (exec_in) {
1418 copy_to_file(STDIN_FILENO, fd);
1419 } else {
1420 copy_to_file(fd, STDOUT_FILENO);
1421 }
1422
1423 adb_close(fd);
1424 return 0;
1425 }
1426
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001427 if(!strcmp(argv[0], "kill-server")) {
1428 int fd;
1429 fd = _adb_connect("host:kill");
1430 if(fd == -1) {
1431 fprintf(stderr,"* server not running *\n");
1432 return 1;
1433 }
1434 return 0;
1435 }
1436
Doug Zongker6b217ed2012-01-09 14:54:53 -08001437 if(!strcmp(argv[0], "sideload")) {
1438 if(argc != 2) return usage();
Doug Zongkerbcad29f2014-06-26 15:35:36 -07001439 if (adb_sideload_host(argv[1])) {
Doug Zongker6b217ed2012-01-09 14:54:53 -08001440 return 1;
1441 } else {
1442 return 0;
1443 }
1444 }
1445
Mike Lockwood26b88e32009-08-24 15:58:40 -07001446 if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
Romain Guyf925d912009-12-14 14:42:17 -08001447 || !strcmp(argv[0], "reboot-bootloader")
Mike Lockwood26b88e32009-08-24 15:58:40 -07001448 || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
Mike Lockwood78589f32009-09-03 14:54:58 -04001449 || !strcmp(argv[0], "root")) {
Mike Lockwood26b88e32009-08-24 15:58:40 -07001450 char command[100];
Romain Guyf925d912009-12-14 14:42:17 -08001451 if (!strcmp(argv[0], "reboot-bootloader"))
1452 snprintf(command, sizeof(command), "reboot:bootloader");
1453 else if (argc > 1)
Mike Lockwood26b88e32009-08-24 15:58:40 -07001454 snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
Mike Lockwood12a35ea2009-08-04 20:37:51 -04001455 else
Mike Lockwood26b88e32009-08-24 15:58:40 -07001456 snprintf(command, sizeof(command), "%s:", argv[0]);
1457 int fd = adb_connect(command);
The Android Open Source Project9c753402009-03-13 13:04:37 -07001458 if(fd >= 0) {
1459 read_and_dump(fd);
1460 adb_close(fd);
1461 return 0;
1462 }
1463 fprintf(stderr,"error: %s\n", adb_error());
1464 return 1;
1465 }
1466
Mike Lockwood78589f32009-09-03 14:54:58 -04001467 if(!strcmp(argv[0], "bugreport")) {
Dan Egnor2857f312010-01-20 13:50:36 -08001468 if (argc != 1) return usage();
1469 do_cmd(ttype, serial, "shell", "bugreport", 0);
Mike Lockwood78589f32009-09-03 14:54:58 -04001470 return 0;
1471 }
1472
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001473 /* adb_command() wrapper commands */
1474
1475 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1476 char* service = argv[0];
1477 if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1478 if (ttype == kTransportUsb) {
1479 service = "wait-for-usb";
1480 } else if (ttype == kTransportLocal) {
1481 service = "wait-for-local";
1482 } else {
1483 service = "wait-for-any";
1484 }
1485 }
1486
1487 format_host_command(buf, sizeof buf, service, ttype, serial);
1488
1489 if (adb_command(buf)) {
1490 D("failure: %s *\n",adb_error());
1491 fprintf(stderr,"error: %s\n", adb_error());
1492 return 1;
1493 }
1494
1495 /* Allow a command to be run after wait-for-device,
1496 * e.g. 'adb wait-for-device shell'.
1497 */
1498 if(argc > 1) {
1499 argc--;
1500 argv++;
1501 goto top;
1502 }
1503 return 0;
1504 }
1505
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001506 if(!strcmp(argv[0], "forward") ||
1507 !strcmp(argv[0], "reverse"))
1508 {
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001509 char host_prefix[64];
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001510 char reverse = (char) !strcmp(argv[0], "reverse");
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001511 char remove = 0;
1512 char remove_all = 0;
1513 char list = 0;
1514 char no_rebind = 0;
1515
1516 // Parse options here.
1517 while (argc > 1 && argv[1][0] == '-') {
1518 if (!strcmp(argv[1], "--list"))
1519 list = 1;
1520 else if (!strcmp(argv[1], "--remove"))
1521 remove = 1;
1522 else if (!strcmp(argv[1], "--remove-all"))
1523 remove_all = 1;
1524 else if (!strcmp(argv[1], "--no-rebind"))
1525 no_rebind = 1;
1526 else {
1527 return usage();
1528 }
1529 argc--;
1530 argv++;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001531 }
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001532
1533 // Ensure we can only use one option at a time.
1534 if (list + remove + remove_all + no_rebind > 1) {
1535 return usage();
1536 }
1537
1538 // Determine the <host-prefix> for this command.
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001539 if (reverse) {
1540 snprintf(host_prefix, sizeof host_prefix, "reverse");
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001541 } else {
David 'Digit' Turner963a4492013-03-21 21:07:42 +01001542 if (serial) {
1543 snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
1544 serial);
1545 } else if (ttype == kTransportUsb) {
1546 snprintf(host_prefix, sizeof host_prefix, "host-usb");
1547 } else if (ttype == kTransportLocal) {
1548 snprintf(host_prefix, sizeof host_prefix, "host-local");
1549 } else {
1550 snprintf(host_prefix, sizeof host_prefix, "host");
1551 }
David 'Digit' Turner6c489802012-11-14 15:01:55 +01001552 }
1553
1554 // Implement forward --list
1555 if (list) {
1556 if (argc != 1)
1557 return usage();
1558 snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);
1559 char* forwards = adb_query(buf);
1560 if (forwards == NULL) {
1561 fprintf(stderr, "error: %s\n", adb_error());
1562 return 1;
1563 }
1564 printf("%s", forwards);
1565 free(forwards);
1566 return 0;
1567 }
1568
1569 // Implement forward --remove-all
1570 else if (remove_all) {
1571 if (argc != 1)
1572 return usage();
1573 snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);
1574 }
1575
1576 // Implement forward --remove <local>
1577 else if (remove) {
1578 if (argc != 2)
1579 return usage();
1580 snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);
1581 }
1582 // Or implement one of:
1583 // forward <local> <remote>
1584 // forward --no-rebind <local> <remote>
1585 else
1586 {
1587 if (argc != 3)
1588 return usage();
1589 const char* command = no_rebind ? "forward:norebind:" : "forward";
1590 snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
1591 }
1592
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001593 if(adb_command(buf)) {
1594 fprintf(stderr,"error: %s\n", adb_error());
1595 return 1;
1596 }
1597 return 0;
1598 }
1599
1600 /* do_sync_*() commands */
1601
1602 if(!strcmp(argv[0], "ls")) {
1603 if(argc != 2) return usage();
1604 return do_sync_ls(argv[1]);
1605 }
1606
1607 if(!strcmp(argv[0], "push")) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001608 int show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001609 int copy_attrs = 0; // unused
Mark Lindner9f9d1452014-03-11 17:55:59 -07001610 const char* lpath = NULL, *rpath = NULL;
1611
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001612 parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001613
1614 if ((lpath != NULL) && (rpath != NULL)) {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001615 return do_sync_push(lpath, rpath, show_progress);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001616 }
1617
1618 return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001619 }
1620
1621 if(!strcmp(argv[0], "pull")) {
Mark Lindner9f9d1452014-03-11 17:55:59 -07001622 int show_progress = 0;
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001623 int copy_attrs = 0;
Mark Lindner9f9d1452014-03-11 17:55:59 -07001624 const char* rpath = NULL, *lpath = ".";
1625
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001626 parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
Mark Lindner9f9d1452014-03-11 17:55:59 -07001627
1628 if (rpath != NULL) {
Lajos Molnar4e23e3c2013-04-19 12:41:09 -07001629 return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
Joe Onorato23595b02010-01-05 13:42:25 -08001630 }
Mark Lindner9f9d1452014-03-11 17:55:59 -07001631
1632 return usage();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001633 }
1634
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001635 if (!strcmp(argv[0], "install")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001636 if (argc < 2) return usage();
1637 return install_app(ttype, serial, argc, argv);
1638 }
1639
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001640 if (!strcmp(argv[0], "install-multiple")) {
1641 if (argc < 2) return usage();
1642 return install_multiple_app(ttype, serial, argc, argv);
1643 }
1644
1645 if (!strcmp(argv[0], "uninstall")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001646 if (argc < 2) return usage();
1647 return uninstall_app(ttype, serial, argc, argv);
1648 }
1649
1650 if(!strcmp(argv[0], "sync")) {
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001651 char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath;
Anthony Newnamdd2db142010-02-22 08:36:49 -06001652 int listonly = 0;
1653
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001654 int ret;
1655 if(argc < 2) {
1656 /* No local path was specified. */
1657 srcarg = NULL;
Anthony Newnamdd2db142010-02-22 08:36:49 -06001658 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1659 listonly = 1;
1660 if (argc == 3) {
1661 srcarg = argv[2];
1662 } else {
1663 srcarg = NULL;
1664 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001665 } else if(argc == 2) {
1666 /* A local path or "android"/"data" arg was specified. */
1667 srcarg = argv[1];
1668 } else {
1669 return usage();
1670 }
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001671 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001672 if(ret != 0) return usage();
1673
1674 if(android_srcpath != NULL)
Anthony Newnamdd2db142010-02-22 08:36:49 -06001675 ret = do_sync_sync(android_srcpath, "/system", listonly);
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001676 if(ret == 0 && vendor_srcpath != NULL)
1677 ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001678 if(ret == 0 && data_srcpath != NULL)
Anthony Newnamdd2db142010-02-22 08:36:49 -06001679 ret = do_sync_sync(data_srcpath, "/data", listonly);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001680
1681 free(android_srcpath);
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001682 free(vendor_srcpath);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001683 free(data_srcpath);
1684 return ret;
1685 }
1686
1687 /* passthrough commands */
1688
1689 if(!strcmp(argv[0],"get-state") ||
Scott Anderson6dfaf4b2012-04-20 11:21:14 -07001690 !strcmp(argv[0],"get-serialno") ||
1691 !strcmp(argv[0],"get-devpath"))
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001692 {
1693 char *tmp;
1694
1695 format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1696 tmp = adb_query(buf);
1697 if(tmp) {
1698 printf("%s\n", tmp);
1699 return 0;
1700 } else {
1701 return 1;
1702 }
1703 }
1704
1705 /* other commands */
1706
1707 if(!strcmp(argv[0],"status-window")) {
1708 status_window(ttype, serial);
1709 return 0;
1710 }
1711
Christopher Tate7b9b5162011-11-30 13:00:33 -08001712 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001713 return logcat(ttype, serial, argc, argv);
1714 }
1715
1716 if(!strcmp(argv[0],"ppp")) {
1717 return ppp(argc, argv);
1718 }
1719
1720 if (!strcmp(argv[0], "start-server")) {
1721 return adb_connect("host:start-server");
1722 }
1723
Christopher Tate73779122011-04-21 12:53:28 -07001724 if (!strcmp(argv[0], "backup")) {
1725 return backup(argc, argv);
1726 }
1727
Christopher Tatecf5379b2011-05-17 15:52:54 -07001728 if (!strcmp(argv[0], "restore")) {
1729 return restore(argc, argv);
1730 }
1731
Nick Kralevich6183c962014-11-13 15:17:29 -08001732 if (!strcmp(argv[0], "keygen")) {
1733 if (argc < 2) return usage();
1734 return adb_auth_keygen(argv[1]);
1735 }
1736
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001737 if (!strcmp(argv[0], "jdwp")) {
1738 int fd = adb_connect("jdwp");
1739 if (fd >= 0) {
1740 read_and_dump(fd);
1741 adb_close(fd);
1742 return 0;
1743 } else {
1744 fprintf(stderr, "error: %s\n", adb_error());
1745 return -1;
1746 }
1747 }
1748
1749 /* "adb /?" is a common idiom under Windows */
1750 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1751 help();
1752 return 0;
1753 }
1754
1755 if(!strcmp(argv[0], "version")) {
1756 version(stdout);
1757 return 0;
1758 }
1759
1760 usage();
1761 return 1;
1762}
1763
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001764#define MAX_ARGV_LENGTH 16
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001765static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1766{
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001767 char *argv[MAX_ARGV_LENGTH];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001768 int argc;
1769 va_list ap;
1770
1771 va_start(ap, cmd);
1772 argc = 0;
1773
1774 if (serial) {
1775 argv[argc++] = "-s";
1776 argv[argc++] = serial;
1777 } else if (ttype == kTransportUsb) {
1778 argv[argc++] = "-d";
1779 } else if (ttype == kTransportLocal) {
1780 argv[argc++] = "-e";
1781 }
1782
1783 argv[argc++] = cmd;
Alexander Ivchenko9bdc70d2014-08-06 14:51:40 +04001784 while(argc < MAX_ARGV_LENGTH &&
1785 (argv[argc] = va_arg(ap, char*)) != 0) argc++;
1786 assert(argc < MAX_ARGV_LENGTH);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001787 va_end(ap);
1788
1789#if 0
1790 int n;
1791 fprintf(stderr,"argc = %d\n",argc);
1792 for(n = 0; n < argc; n++) {
1793 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1794 }
1795#endif
1796
1797 return adb_commandline(argc, argv);
1798}
1799
1800int find_sync_dirs(const char *srcarg,
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001801 char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001802{
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001803 char *android_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL;
1804 struct stat st;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001805
1806 if(srcarg == NULL) {
1807 android_srcdir = product_file("system");
1808 data_srcdir = product_file("data");
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001809 vendor_srcdir = product_file("vendor");
1810 /* Check if vendor partition exists */
1811 if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
1812 vendor_srcdir = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001813 } else {
1814 /* srcarg may be "data", "system" or NULL.
1815 * if srcarg is NULL, then both data and system are synced
1816 */
1817 if(strcmp(srcarg, "system") == 0) {
1818 android_srcdir = product_file("system");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001819 } else if(strcmp(srcarg, "data") == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001820 data_srcdir = product_file("data");
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001821 } else if(strcmp(srcarg, "vendor") == 0) {
1822 vendor_srcdir = product_file("vendor");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001823 } else {
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001824 /* It's not "system", "vendor", or "data".
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001825 */
1826 return 1;
1827 }
1828 }
1829
1830 if(android_srcdir_out != NULL)
1831 *android_srcdir_out = android_srcdir;
1832 else
1833 free(android_srcdir);
1834
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001835 if(vendor_srcdir_out != NULL)
1836 *vendor_srcdir_out = vendor_srcdir;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001837 else
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001838 free(vendor_srcdir);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001839
Daniel Rosenberge9a1c9c2014-06-30 20:29:40 -07001840 if(data_srcdir_out != NULL)
1841 *data_srcdir_out = data_srcdir;
1842 else
1843 free(data_srcdir);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001844 return 0;
1845}
1846
1847static int pm_command(transport_type transport, char* serial,
1848 int argc, char** argv)
1849{
1850 char buf[4096];
1851
1852 snprintf(buf, sizeof(buf), "shell:pm");
1853
1854 while(argc-- > 0) {
Jeff Sharkey026d9622014-06-10 16:22:17 -07001855 char *quoted = escape_arg(*argv++);
Jeff Sharkey824d1062014-06-10 11:31:24 -07001856 strncat(buf, " ", sizeof(buf) - 1);
1857 strncat(buf, quoted, sizeof(buf) - 1);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001858 free(quoted);
1859 }
1860
1861 send_shellcommand(transport, serial, buf);
1862 return 0;
1863}
1864
1865int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1866{
1867 /* if the user choose the -k option, we refuse to do it until devices are
1868 out with the option to uninstall the remaining data somehow (adb/ui) */
1869 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1870 {
1871 printf(
1872 "The -k option uninstalls the application while retaining the data/cache.\n"
1873 "At the moment, there is no way to remove the remaining data.\n"
1874 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1875 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1876 return -1;
1877 }
1878
1879 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1880 return pm_command(transport, serial, argc, argv);
1881}
1882
1883static int delete_file(transport_type transport, char* serial, char* filename)
1884{
1885 char buf[4096];
1886 char* quoted;
1887
Jeff Sharkeyce474652014-09-09 12:38:30 -07001888 snprintf(buf, sizeof(buf), "shell:rm -f ");
Jeff Sharkey026d9622014-06-10 16:22:17 -07001889 quoted = escape_arg(filename);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001890 strncat(buf, quoted, sizeof(buf)-1);
1891 free(quoted);
1892
1893 send_shellcommand(transport, serial, buf);
1894 return 0;
1895}
1896
Kenny Root3802c992011-08-05 11:19:45 -07001897static const char* get_basename(const char* filename)
1898{
1899 const char* basename = adb_dirstop(filename);
1900 if (basename) {
1901 basename++;
1902 return basename;
1903 } else {
1904 return filename;
1905 }
1906}
1907
Kenny Root3802c992011-08-05 11:19:45 -07001908int install_app(transport_type transport, char* serial, int argc, char** argv)
1909{
1910 static const char *const DATA_DEST = "/data/local/tmp/%s";
1911 static const char *const SD_DEST = "/sdcard/tmp/%s";
1912 const char* where = DATA_DEST;
Kenny Root3802c992011-08-05 11:19:45 -07001913 int i;
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001914 struct stat sb;
Kenny Root3802c992011-08-05 11:19:45 -07001915
1916 for (i = 1; i < argc; i++) {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001917 if (!strcmp(argv[i], "-s")) {
Kenny Root3802c992011-08-05 11:19:45 -07001918 where = SD_DEST;
1919 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001920 }
1921
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001922 // Find last APK argument.
1923 // All other arguments passed through verbatim.
1924 int last_apk = -1;
1925 for (i = argc - 1; i >= 0; i--) {
1926 char* file = argv[i];
1927 char* dot = strrchr(file, '.');
1928 if (dot && !strcasecmp(dot, ".apk")) {
1929 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1930 fprintf(stderr, "Invalid APK file: %s\n", file);
1931 return -1;
1932 }
1933
1934 last_apk = i;
1935 break;
1936 }
Kenny Root3802c992011-08-05 11:19:45 -07001937 }
1938
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001939 if (last_apk == -1) {
1940 fprintf(stderr, "Missing APK file\n");
1941 return -1;
Kenny Root3802c992011-08-05 11:19:45 -07001942 }
1943
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001944 char* apk_file = argv[last_apk];
1945 char apk_dest[PATH_MAX];
Kenny Root3802c992011-08-05 11:19:45 -07001946 snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001947 int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */);
Kenny Root3802c992011-08-05 11:19:45 -07001948 if (err) {
Kenny Root58d5f222012-03-26 16:14:02 -07001949 goto cleanup_apk;
Kenny Root3802c992011-08-05 11:19:45 -07001950 } else {
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001951 argv[last_apk] = apk_dest; /* destination name, not source location */
Kenny Root3802c992011-08-05 11:19:45 -07001952 }
1953
1954 pm_command(transport, serial, argc, argv);
1955
Kenny Root58d5f222012-03-26 16:14:02 -07001956cleanup_apk:
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001957 delete_file(transport, serial, apk_dest);
1958 return err;
1959}
1960
1961int install_multiple_app(transport_type transport, char* serial, int argc, char** argv)
1962{
1963 char buf[1024];
1964 int i;
1965 struct stat sb;
1966 unsigned long long total_size = 0;
1967
1968 // Find all APK arguments starting at end.
1969 // All other arguments passed through verbatim.
1970 int first_apk = -1;
1971 for (i = argc - 1; i >= 0; i--) {
1972 char* file = argv[i];
1973 char* dot = strrchr(file, '.');
1974 if (dot && !strcasecmp(dot, ".apk")) {
1975 if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
1976 fprintf(stderr, "Invalid APK file: %s\n", file);
1977 return -1;
1978 }
1979
1980 total_size += sb.st_size;
1981 first_apk = i;
1982 } else {
1983 break;
1984 }
Kenny Root3802c992011-08-05 11:19:45 -07001985 }
1986
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001987 if (first_apk == -1) {
1988 fprintf(stderr, "Missing APK file\n");
1989 return 1;
1990 }
Kenny Root3802c992011-08-05 11:19:45 -07001991
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07001992 snprintf(buf, sizeof(buf), "exec:pm install-create -S %lld", total_size);
1993 for (i = 1; i < first_apk; i++) {
1994 char *quoted = escape_arg(argv[i]);
1995 strncat(buf, " ", sizeof(buf) - 1);
1996 strncat(buf, quoted, sizeof(buf) - 1);
1997 free(quoted);
1998 }
1999
2000 // Create install session
2001 int fd = adb_connect(buf);
2002 if (fd < 0) {
2003 fprintf(stderr, "Connect error for create: %s\n", adb_error());
2004 return -1;
2005 }
2006 read_status_line(fd, buf, sizeof(buf));
2007 adb_close(fd);
2008
2009 int session_id = -1;
2010 if (!strncmp("Success", buf, 7)) {
2011 char* start = strrchr(buf, '[');
2012 char* end = strrchr(buf, ']');
2013 if (start && end) {
2014 *end = '\0';
2015 session_id = strtol(start + 1, NULL, 10);
2016 }
2017 }
2018 if (session_id < 0) {
2019 fprintf(stderr, "Failed to create session\n");
Christopher Tate29721da2014-07-14 16:45:13 -07002020 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002021 return -1;
2022 }
2023
2024 // Valid session, now stream the APKs
2025 int success = 1;
2026 for (i = first_apk; i < argc; i++) {
2027 char* file = argv[i];
2028 if (stat(file, &sb) == -1) {
2029 fprintf(stderr, "Failed to stat %s\n", file);
2030 success = 0;
2031 goto finalize_session;
2032 }
2033
2034 snprintf(buf, sizeof(buf), "exec:pm install-write -S %lld %d %d_%s -",
Jeff Sharkey4a7ddb62014-07-14 13:57:54 -07002035 (long long int) sb.st_size, session_id, i, get_basename(file));
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002036
2037 int localFd = adb_open(file, O_RDONLY);
2038 if (localFd < 0) {
2039 fprintf(stderr, "Failed to open %s: %s\n", file, adb_error());
2040 success = 0;
2041 goto finalize_session;
2042 }
2043
2044 int remoteFd = adb_connect(buf);
2045 if (remoteFd < 0) {
2046 fprintf(stderr, "Connect error for write: %s\n", adb_error());
2047 adb_close(localFd);
2048 success = 0;
2049 goto finalize_session;
2050 }
2051
2052 copy_to_file(localFd, remoteFd);
2053 read_status_line(remoteFd, buf, sizeof(buf));
2054
2055 adb_close(localFd);
2056 adb_close(remoteFd);
2057
2058 if (strncmp("Success", buf, 7)) {
2059 fprintf(stderr, "Failed to write %s\n", file);
Christopher Tate29721da2014-07-14 16:45:13 -07002060 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002061 success = 0;
2062 goto finalize_session;
2063 }
2064 }
2065
2066finalize_session:
Jeff Sharkey01f6fbf2014-07-25 09:58:25 -07002067 // Commit session if we streamed everything okay; otherwise abandon
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002068 if (success) {
2069 snprintf(buf, sizeof(buf), "exec:pm install-commit %d", session_id);
2070 } else {
Jeff Sharkey01f6fbf2014-07-25 09:58:25 -07002071 snprintf(buf, sizeof(buf), "exec:pm install-abandon %d", session_id);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002072 }
2073
2074 fd = adb_connect(buf);
2075 if (fd < 0) {
2076 fprintf(stderr, "Connect error for finalize: %s\n", adb_error());
2077 return -1;
2078 }
2079 read_status_line(fd, buf, sizeof(buf));
2080 adb_close(fd);
2081
2082 if (!strncmp("Success", buf, 7)) {
Christopher Tate29721da2014-07-14 16:45:13 -07002083 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002084 return 0;
2085 } else {
2086 fprintf(stderr, "Failed to finalize session\n");
Christopher Tate29721da2014-07-14 16:45:13 -07002087 fputs(buf, stderr);
Jeff Sharkey0e0d2512014-06-09 17:30:57 -07002088 return -1;
2089 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08002090}