blob: be596ce55c0a53902ee7a17b6d711ec36bd88a37 [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>
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include <unistd.h>
22#include <limits.h>
23#include <stdarg.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <ctype.h>
27#include <assert.h>
28
29#include "sysdeps.h"
30
31#ifdef HAVE_TERMIO_H
32#include <termios.h>
33#endif
34
35#define TRACE_TAG TRACE_ADB
36#include "adb.h"
37#include "adb_client.h"
38#include "file_sync_service.h"
39
40#ifdef SH_HISTORY
41#include "shlist.h"
42#include "history.h"
43#endif
44
45enum {
46 IGNORE_DATA,
47 WIPE_DATA,
48 FLASH_DATA
49};
50
51static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
52
53void get_my_path(char s[PATH_MAX]);
54int find_sync_dirs(const char *srcarg,
55 char **android_srcdir_out, char **data_srcdir_out);
56int install_app(transport_type transport, char* serial, int argc, char** argv);
57int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
58
59static const char *gProductOutPath = NULL;
60
61static char *product_file(const char *extra)
62{
63 int n;
64 char *x;
65
66 if (gProductOutPath == NULL) {
67 fprintf(stderr, "adb: Product directory not specified; "
68 "use -p or define ANDROID_PRODUCT_OUT\n");
69 exit(1);
70 }
71
72 n = strlen(gProductOutPath) + strlen(extra) + 2;
73 x = malloc(n);
74 if (x == 0) {
75 fprintf(stderr, "adb: Out of memory (product_file())\n");
76 exit(1);
77 }
78
79 snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
80 return x;
81}
82
83void version(FILE * out) {
84 fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
85 ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
86}
87
88void help()
89{
90 version(stderr);
91
92 fprintf(stderr,
93 "\n"
94 " -d - directs command to the only connected USB device\n"
95 " returns an error if more than one USB device is present.\n"
96 " -e - directs command to the only running emulator.\n"
97 " returns an error if more than one emulator is running.\n"
98 " -s <serial number> - directs command to the USB device or emulator with\n"
99 " the given serial number\n"
100 " -p <product name or path> - simple product name like 'sooner', or\n"
101 " a relative/absolute path to a product\n"
102 " out directory like 'out/target/product/sooner'.\n"
103 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
104 " environment variable is used, which must\n"
105 " be an absolute path.\n"
106 " devices - list all connected devices\n"
107 "\n"
108 "device commands:\n"
109 " adb push <local> <remote> - copy file/dir to device\n"
110 " adb pull <remote> <local> - copy file/dir from device\n"
111 " adb sync [ <directory> ] - copy host->device only if changed\n"
112 " (see 'adb help all')\n"
113 " adb shell - run remote shell interactively\n"
114 " adb shell <command> - run remote shell command\n"
115 " adb emu <command> - run emulator console command\n"
116 " adb logcat [ <filter-spec> ] - View device log\n"
117 " adb forward <local> <remote> - forward socket connections\n"
118 " forward specs are one of: \n"
119 " tcp:<port>\n"
120 " localabstract:<unix domain socket name>\n"
121 " localreserved:<unix domain socket name>\n"
122 " localfilesystem:<unix domain socket name>\n"
123 " dev:<character device name>\n"
124 " jdwp:<process pid> (remote only)\n"
125 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
126 " adb install [-l] [-r] <file> - push this package file to the device and install it\n"
127 " ('-l' means forward-lock the app)\n"
128 " ('-r' means reinstall the app, keeping its data)\n"
129 " adb uninstall [-k] <package> - remove this app package from the device\n"
130 " ('-k' means keep the data and cache directories)\n"
131 " adb bugreport - return all information from the device\n"
132 " that should be included in a bug report.\n"
133 "\n"
134 " adb help - show this help message\n"
135 " adb version - show version num\n"
136 "\n"
137 "DATAOPTS:\n"
138 " (no option) - don't touch the data partition\n"
139 " -w - wipe the data partition\n"
140 " -d - flash the data partition\n"
141 "\n"
142 "scripting:\n"
143 " adb wait-for-device - block until device is online\n"
144 " adb start-server - ensure that there is a server running\n"
145 " adb kill-server - kill the server if it is running\n"
146 " adb get-state - prints: offline | bootloader | device\n"
147 " adb get-serialno - prints: <serial-number>\n"
148 " adb status-window - continuously print device status for a specified device\n"
149 " adb remount - remounts the /system partition on the device read-write\n"
150 "\n"
151 "networking:\n"
152 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
153 " Note: you should not automatically start a PDP connection.\n"
154 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
155 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
156 "\n"
157 "adb sync notes: adb sync [ <directory> ]\n"
158 " <localdir> can be interpreted in several ways:\n"
159 "\n"
160 " - If <directory> is not specified, both /system and /data partitions will be updated.\n"
161 "\n"
162 " - If it is \"system\" or \"data\", only the corresponding partition\n"
163 " is updated.\n"
164 );
165}
166
167int usage()
168{
169 help();
170 return 1;
171}
172
173#ifdef HAVE_TERMIO_H
174static struct termios tio_save;
175
176static void stdin_raw_init(int fd)
177{
178 struct termios tio;
179
180 if(tcgetattr(fd, &tio)) return;
181 if(tcgetattr(fd, &tio_save)) return;
182
183 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
184
185 /* no timeout but request at least one character per read */
186 tio.c_cc[VTIME] = 0;
187 tio.c_cc[VMIN] = 1;
188
189 tcsetattr(fd, TCSANOW, &tio);
190 tcflush(fd, TCIFLUSH);
191}
192
193static void stdin_raw_restore(int fd)
194{
195 tcsetattr(fd, TCSANOW, &tio_save);
196 tcflush(fd, TCIFLUSH);
197}
198#endif
199
200static void read_and_dump(int fd)
201{
202 char buf[4096];
203 int len;
204
205 while(fd >= 0) {
206 len = adb_read(fd, buf, 4096);
207 if(len == 0) {
208 break;
209 }
210
211 if(len < 0) {
212 if(errno == EINTR) continue;
213 break;
214 }
215 /* we want to output to stdout, so no adb_write here !! */
216 unix_write(1, buf, len);
217 }
218}
219
220#ifdef SH_HISTORY
221int shItemCmp( void *val, void *idata )
222{
223 return( (strcmp( val, idata ) == 0) );
224}
225#endif
226
227static void *stdin_read_thread(void *x)
228{
229 int fd, fdi;
230 unsigned char buf[1024];
231#ifdef SH_HISTORY
232 unsigned char realbuf[1024], *buf_ptr;
233 SHLIST history;
234 SHLIST *item = &history;
235 int cmdlen = 0, ins_flag = 0;
236#endif
237 int r, n;
238 int state = 0;
239
240 int *fds = (int*) x;
241 fd = fds[0];
242 fdi = fds[1];
243 free(fds);
244
245#ifdef SH_HISTORY
246 shListInitList( &history );
247#endif
248 for(;;) {
249 /* fdi is really the client's stdin, so use read, not adb_read here */
250 r = unix_read(fdi, buf, 1024);
251 if(r == 0) break;
252 if(r < 0) {
253 if(errno == EINTR) continue;
254 break;
255 }
256#ifdef SH_HISTORY
257 if( (r == 3) && /* Arrow processing */
258 (memcmp( (void *)buf, SH_ARROW_ANY, 2 ) == 0) ) {
259 switch( buf[2] ) {
260 case SH_ARROW_UP:
261 item = shListGetNextItem( &history, item );
262 break;
263 case SH_ARROW_DOWN:
264 item = shListGetPrevItem( &history, item );
265 break;
266 default:
267 item = NULL;
268 break;
269 }
270 memset( buf, SH_DEL_CHAR, cmdlen );
271 if( item != NULL ) {
272 n = snprintf( (char *)(&buf[cmdlen]), sizeof buf - cmdlen, "%s", (char *)(item->data) );
273 memcpy( realbuf, item->data, n );
274 }
275 else { /* Clean buffer */
276 item = &history;
277 n = 0;
278 }
279 r = n + cmdlen;
280 cmdlen = n;
281 ins_flag = 0;
282 if( r == 0 )
283 continue;
284 }
285 else {
286#endif
287 for(n = 0; n < r; n++){
288 switch(buf[n]) {
289 case '\n':
290#ifdef SH_HISTORY
291 if( ins_flag && (SH_BLANK_CHAR <= realbuf[0]) ) {
292 buf_ptr = malloc(cmdlen + 1);
293 if( buf_ptr != NULL ) {
294 memcpy( buf_ptr, realbuf, cmdlen );
295 buf_ptr[cmdlen] = '\0';
296 if( (item = shListFindItem( &history, (void *)buf_ptr, shItemCmp )) == NULL ) {
297 shListInsFirstItem( &history, (void *)buf_ptr );
298 item = &history;
299 }
300 }
301 }
302 cmdlen = 0;
303 ins_flag = 0;
304#endif
305 state = 1;
306 break;
307 case '\r':
308 state = 1;
309 break;
310 case '~':
311 if(state == 1) state++;
312 break;
313 case '.':
314 if(state == 2) {
315 fprintf(stderr,"\n* disconnect *\n");
316 #ifdef HAVE_TERMIO_H
317 stdin_raw_restore(fdi);
318 #endif
319 exit(0);
320 }
321 default:
322#ifdef SH_HISTORY
323 if( buf[n] == SH_DEL_CHAR ) {
324 if( cmdlen > 0 )
325 cmdlen--;
326 }
327 else {
328 realbuf[cmdlen] = buf[n];
329 cmdlen++;
330 }
331 ins_flag = 1;
332#endif
333 state = 0;
334 }
335 }
336#ifdef SH_HISTORY
337 }
338#endif
339 r = adb_write(fd, buf, r);
340 if(r <= 0) {
341 break;
342 }
343 }
344#ifdef SH_HISTORY
345 shListDelAllItems( &history, (shListFree)free );
346#endif
347 return 0;
348}
349
350int interactive_shell(void)
351{
352 adb_thread_t thr;
353 int fdi, fd;
354 int *fds;
355
356 fd = adb_connect("shell:");
357 if(fd < 0) {
358 fprintf(stderr,"error: %s\n", adb_error());
359 return 1;
360 }
361 fdi = 0; //dup(0);
362
363 fds = malloc(sizeof(int) * 2);
364 fds[0] = fd;
365 fds[1] = fdi;
366
367#ifdef HAVE_TERMIO_H
368 stdin_raw_init(fdi);
369#endif
370 adb_thread_create(&thr, stdin_read_thread, fds);
371 read_and_dump(fd);
372#ifdef HAVE_TERMIO_H
373 stdin_raw_restore(fdi);
374#endif
375 return 0;
376}
377
378
379static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial)
380{
381 if (serial) {
382 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
383 } else {
384 const char* prefix = "host";
385 if (ttype == kTransportUsb)
386 prefix = "host-usb";
387 else if (ttype == kTransportLocal)
388 prefix = "host-local";
389
390 snprintf(buffer, buflen, "%s:%s", prefix, command);
391 }
392}
393
394static void status_window(transport_type ttype, const char* serial)
395{
396 char command[4096];
397 char *state = 0;
398 char *laststate = 0;
399
400 /* silence stderr */
401#ifdef _WIN32
402 /* XXX: TODO */
403#else
404 int fd;
405 fd = unix_open("/dev/null", O_WRONLY);
406 dup2(fd, 2);
407 adb_close(fd);
408#endif
409
410 format_host_command(command, sizeof command, "get-state", ttype, serial);
411
412 for(;;) {
413 adb_sleep_ms(250);
414
415 if(state) {
416 free(state);
417 state = 0;
418 }
419
420 state = adb_query(command);
421
422 if(state) {
423 if(laststate && !strcmp(state,laststate)){
424 continue;
425 } else {
426 if(laststate) free(laststate);
427 laststate = strdup(state);
428 }
429 }
430
431 printf("%c[2J%c[2H", 27, 27);
432 printf("Android Debug Bridge\n");
433 printf("State: %s\n", state ? state : "offline");
434 fflush(stdout);
435 }
436}
437
438/** duplicate string and quote all \ " ( ) chars + space character. */
439static char *
440dupAndQuote(const char *s)
441{
442 const char *ts;
443 size_t alloc_len;
444 char *ret;
445 char *dest;
446
447 ts = s;
448
449 alloc_len = 0;
450
451 for( ;*ts != '\0'; ts++) {
452 alloc_len++;
453 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
454 alloc_len++;
455 }
456 }
457
458 ret = (char *)malloc(alloc_len + 1);
459
460 ts = s;
461 dest = ret;
462
463 for ( ;*ts != '\0'; ts++) {
464 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
465 *dest++ = '\\';
466 }
467
468 *dest++ = *ts;
469 }
470
471 *dest++ = '\0';
472
473 return ret;
474}
475
476/**
477 * Run ppp in "notty" mode against a resource listed as the first parameter
478 * eg:
479 *
480 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
481 *
482 */
483int ppp(int argc, char **argv)
484{
485#ifdef HAVE_WIN32_PROC
486 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
487 return -1;
488#else
489 char *adb_service_name;
490 pid_t pid;
491 int fd;
492
493 if (argc < 2) {
494 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
495 argv[0]);
496
497 return 1;
498 }
499
500 adb_service_name = argv[1];
501
502 fd = adb_connect(adb_service_name);
503
504 if(fd < 0) {
505 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
506 adb_service_name, adb_error());
507 return 1;
508 }
509
510 pid = fork();
511
512 if (pid < 0) {
513 perror("from fork()");
514 return 1;
515 } else if (pid == 0) {
516 int err;
517 int i;
518 const char **ppp_args;
519
520 // copy args
521 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
522 ppp_args[0] = "pppd";
523 for (i = 2 ; i < argc ; i++) {
524 //argv[2] and beyond become ppp_args[1] and beyond
525 ppp_args[i - 1] = argv[i];
526 }
527 ppp_args[i-1] = NULL;
528
529 // child side
530
531 dup2(fd, STDIN_FILENO);
532 dup2(fd, STDOUT_FILENO);
533 adb_close(STDERR_FILENO);
534 adb_close(fd);
535
536 err = execvp("pppd", (char * const *)ppp_args);
537
538 if (err < 0) {
539 perror("execing pppd");
540 }
541 exit(-1);
542 } else {
543 // parent side
544
545 adb_close(fd);
546 return 0;
547 }
548#endif /* !HAVE_WIN32_PROC */
549}
550
551static int send_shellcommand(transport_type transport, char* serial, char* buf)
552{
553 int fd, ret;
554
555 for(;;) {
556 fd = adb_connect(buf);
557 if(fd >= 0)
558 break;
559 fprintf(stderr,"- waiting for device -\n");
560 adb_sleep_ms(1000);
561 do_cmd(transport, serial, "wait-for-device", 0);
562 }
563
564 read_and_dump(fd);
565 ret = adb_close(fd);
566 if (ret)
567 perror("close");
568
569 return ret;
570}
571
572static int logcat(transport_type transport, char* serial, int argc, char **argv)
573{
574 char buf[4096];
575
576 char *log_tags;
577 char *quoted_log_tags;
578
579 log_tags = getenv("ANDROID_LOG_TAGS");
580 quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
581
582 snprintf(buf, sizeof(buf),
583 "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
584 quoted_log_tags);
585
586 free(quoted_log_tags);
587
588 argc -= 1;
589 argv += 1;
590 while(argc-- > 0) {
591 char *quoted;
592
593 quoted = dupAndQuote (*argv++);
594
595 strncat(buf, " ", sizeof(buf)-1);
596 strncat(buf, quoted, sizeof(buf)-1);
597 free(quoted);
598 }
599
600 send_shellcommand(transport, serial, buf);
601 return 0;
602}
603
604#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
605static int top_works(const char *top)
606{
607 if (top != NULL && adb_is_absolute_host_path(top)) {
608 char path_buf[PATH_MAX];
609 snprintf(path_buf, sizeof(path_buf),
610 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
611 return access(path_buf, F_OK) == 0;
612 }
613 return 0;
614}
615
616static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
617{
618 strcpy(path_buf, indir);
619 while (1) {
620 if (top_works(path_buf)) {
621 return path_buf;
622 }
623 char *s = adb_dirstop(path_buf);
624 if (s != NULL) {
625 *s = '\0';
626 } else {
627 path_buf[0] = '\0';
628 return NULL;
629 }
630 }
631}
632
633static char *find_top(char path_buf[PATH_MAX])
634{
635 char *top = getenv("ANDROID_BUILD_TOP");
636 if (top != NULL && top[0] != '\0') {
637 if (!top_works(top)) {
638 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
639 return NULL;
640 }
641 } else {
642 top = getenv("TOP");
643 if (top != NULL && top[0] != '\0') {
644 if (!top_works(top)) {
645 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
646 return NULL;
647 }
648 } else {
649 top = NULL;
650 }
651 }
652
653 if (top != NULL) {
654 /* The environment pointed to a top directory that works.
655 */
656 strcpy(path_buf, top);
657 return path_buf;
658 }
659
660 /* The environment didn't help. Walk up the tree from the CWD
661 * to see if we can find the top.
662 */
663 char dir[PATH_MAX];
664 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
665 if (top == NULL) {
666 /* If the CWD isn't under a good-looking top, see if the
667 * executable is.
668 */
669 get_my_path(dir);
670 top = find_top_from(dir, path_buf);
671 }
672 return top;
673}
674
675/* <hint> may be:
676 * - A simple product name
677 * e.g., "sooner"
678TODO: debug? sooner-debug, sooner:debug?
679 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
680 * e.g., "out/target/product/sooner"
681 * - An absolute path to the PRODUCT_OUT dir
682 * e.g., "/src/device/out/target/product/sooner"
683 *
684 * Given <hint>, try to construct an absolute path to the
685 * ANDROID_PRODUCT_OUT dir.
686 */
687static const char *find_product_out_path(const char *hint)
688{
689 static char path_buf[PATH_MAX];
690
691 if (hint == NULL || hint[0] == '\0') {
692 return NULL;
693 }
694
695 /* If it's already absolute, don't bother doing any work.
696 */
697 if (adb_is_absolute_host_path(hint)) {
698 strcpy(path_buf, hint);
699 return path_buf;
700 }
701
702 /* If there are any slashes in it, assume it's a relative path;
703 * make it absolute.
704 */
705 if (adb_dirstart(hint) != NULL) {
706 if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
707 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
708 return NULL;
709 }
710 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
711 fprintf(stderr, "adb: Couldn't assemble path\n");
712 return NULL;
713 }
714 strcat(path_buf, OS_PATH_SEPARATOR_STR);
715 strcat(path_buf, hint);
716 return path_buf;
717 }
718
719 /* It's a string without any slashes. Try to do something with it.
720 *
721 * Try to find the root of the build tree, and build a PRODUCT_OUT
722 * path from there.
723 */
724 char top_buf[PATH_MAX];
725 const char *top = find_top(top_buf);
726 if (top == NULL) {
727 fprintf(stderr, "adb: Couldn't find top of build tree\n");
728 return NULL;
729 }
730//TODO: if we have a way to indicate debug, look in out/debug/target/...
731 snprintf(path_buf, sizeof(path_buf),
732 "%s" OS_PATH_SEPARATOR_STR
733 "out" OS_PATH_SEPARATOR_STR
734 "target" OS_PATH_SEPARATOR_STR
735 "product" OS_PATH_SEPARATOR_STR
736 "%s", top_buf, hint);
737 if (access(path_buf, F_OK) < 0) {
738 fprintf(stderr, "adb: Couldn't find a product dir "
739 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
740 return NULL;
741 }
742 return path_buf;
743}
744
745int adb_commandline(int argc, char **argv)
746{
747 char buf[4096];
748 int no_daemon = 0;
749 int is_daemon = 0;
750 int persist = 0;
751 int r;
752 int quote;
753 transport_type ttype = kTransportAny;
754 char* serial = NULL;
755
756 /* If defined, this should be an absolute path to
757 * the directory containing all of the various system images
758 * for a particular product. If not defined, and the adb
759 * command requires this information, then the user must
760 * specify the path using "-p".
761 */
762 gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
763 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
764 gProductOutPath = NULL;
765 }
766 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
767
768 /* modifiers and flags */
769 while(argc > 0) {
770 if(!strcmp(argv[0],"nodaemon")) {
771 no_daemon = 1;
772 } else if (!strcmp(argv[0], "fork-server")) {
773 /* this is a special flag used only when the ADB client launches the ADB Server */
774 is_daemon = 1;
775 } else if(!strcmp(argv[0],"persist")) {
776 persist = 1;
777 } else if(!strncmp(argv[0], "-p", 2)) {
778 const char *product = NULL;
779 if (argv[0][2] == '\0') {
780 if (argc < 2) return usage();
781 product = argv[1];
782 argc--;
783 argv++;
784 } else {
785 product = argv[1] + 2;
786 }
787 gProductOutPath = find_product_out_path(product);
788 if (gProductOutPath == NULL) {
789 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
790 product);
791 return usage();
792 }
793 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
794 if (isdigit(argv[0][2])) {
795 serial = argv[0] + 2;
796 } else {
797 if(argc < 2) return usage();
798 serial = argv[1];
799 argc--;
800 argv++;
801 }
802 } else if (!strcmp(argv[0],"-d")) {
803 ttype = kTransportUsb;
804 } else if (!strcmp(argv[0],"-e")) {
805 ttype = kTransportLocal;
806 } else {
807 /* out of recognized modifiers and flags */
808 break;
809 }
810 argc--;
811 argv++;
812 }
813
814 adb_set_transport(ttype, serial);
815
816 if ((argc > 0) && (!strcmp(argv[0],"server"))) {
817 if (no_daemon || is_daemon) {
818 r = adb_main(is_daemon);
819 } else {
820 r = launch_server();
821 }
822 if(r) {
823 fprintf(stderr,"* could not start server *\n");
824 }
825 return r;
826 }
827
828top:
829 if(argc == 0) {
830 return usage();
831 }
832
833 /* adb_connect() commands */
834
835 if(!strcmp(argv[0], "devices")) {
836 char *tmp;
837 snprintf(buf, sizeof buf, "host:%s", argv[0]);
838 tmp = adb_query(buf);
839 if(tmp) {
840 printf("List of devices attached \n");
841 printf("%s\n", tmp);
842 return 0;
843 } else {
844 return 1;
845 }
846 }
847
848 if (!strcmp(argv[0], "emu")) {
849 return adb_send_emulator_command(argc, argv);
850 }
851
852 if(!strcmp(argv[0], "shell")) {
853 int r;
854 int fd;
855
856 if(argc < 2) {
857 return interactive_shell();
858 }
859
860 snprintf(buf, sizeof buf, "shell:%s", argv[1]);
861 argc -= 2;
862 argv += 2;
863 while(argc-- > 0) {
864 strcat(buf, " ");
865
866 /* quote empty strings and strings with spaces */
867 quote = (**argv == 0 || strchr(*argv, ' '));
868 if (quote)
869 strcat(buf, "\"");
870 strcat(buf, *argv++);
871 if (quote)
872 strcat(buf, "\"");
873 }
874
875 for(;;) {
876 fd = adb_connect(buf);
877 if(fd >= 0) {
878 read_and_dump(fd);
879 adb_close(fd);
880 r = 0;
881 } else {
882 fprintf(stderr,"error: %s\n", adb_error());
883 r = -1;
884 }
885
886 if(persist) {
887 fprintf(stderr,"\n- waiting for device -\n");
888 adb_sleep_ms(1000);
889 do_cmd(ttype, serial, "wait-for-device", 0);
890 } else {
891 return r;
892 }
893 }
894 }
895
896 if(!strcmp(argv[0], "kill-server")) {
897 int fd;
898 fd = _adb_connect("host:kill");
899 if(fd == -1) {
900 fprintf(stderr,"* server not running *\n");
901 return 1;
902 }
903 return 0;
904 }
905
906 if(!strcmp(argv[0], "remount")) {
907 int fd = adb_connect("remount:");
908 if(fd >= 0) {
909 read_and_dump(fd);
910 adb_close(fd);
911 return 0;
912 }
913 fprintf(stderr,"error: %s\n", adb_error());
914 return 1;
915 }
916
917 if(!strcmp(argv[0], "bugreport")) {
918 if (argc != 1) {
919 return 1;
920 }
921 do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
922 return 0;
923 }
924
925 /* adb_command() wrapper commands */
926
927 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
928 char* service = argv[0];
929 if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
930 if (ttype == kTransportUsb) {
931 service = "wait-for-usb";
932 } else if (ttype == kTransportLocal) {
933 service = "wait-for-local";
934 } else {
935 service = "wait-for-any";
936 }
937 }
938
939 format_host_command(buf, sizeof buf, service, ttype, serial);
940
941 if (adb_command(buf)) {
942 D("failure: %s *\n",adb_error());
943 fprintf(stderr,"error: %s\n", adb_error());
944 return 1;
945 }
946
947 /* Allow a command to be run after wait-for-device,
948 * e.g. 'adb wait-for-device shell'.
949 */
950 if(argc > 1) {
951 argc--;
952 argv++;
953 goto top;
954 }
955 return 0;
956 }
957
958 if(!strcmp(argv[0], "forward")) {
959 if(argc != 3) return usage();
960 if (serial) {
961 snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,argv[1],argv[2]);
962 } else {
963 snprintf(buf, sizeof buf, "host:forward:%s;%s",argv[1],argv[2]);
964 }
965 if(adb_command(buf)) {
966 fprintf(stderr,"error: %s\n", adb_error());
967 return 1;
968 }
969 return 0;
970 }
971
972 /* do_sync_*() commands */
973
974 if(!strcmp(argv[0], "ls")) {
975 if(argc != 2) return usage();
976 return do_sync_ls(argv[1]);
977 }
978
979 if(!strcmp(argv[0], "push")) {
980 if(argc != 3) return usage();
981 return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
982 }
983
984 if(!strcmp(argv[0], "pull")) {
985 if(argc != 3) return usage();
986 return do_sync_pull(argv[1], argv[2]);
987 }
988
989 if(!strcmp(argv[0], "install")) {
990 if (argc < 2) return usage();
991 return install_app(ttype, serial, argc, argv);
992 }
993
994 if(!strcmp(argv[0], "uninstall")) {
995 if (argc < 2) return usage();
996 return uninstall_app(ttype, serial, argc, argv);
997 }
998
999 if(!strcmp(argv[0], "sync")) {
1000 char *srcarg, *android_srcpath, *data_srcpath;
1001 int ret;
1002 if(argc < 2) {
1003 /* No local path was specified. */
1004 srcarg = NULL;
1005 } else if(argc == 2) {
1006 /* A local path or "android"/"data" arg was specified. */
1007 srcarg = argv[1];
1008 } else {
1009 return usage();
1010 }
1011 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1012 if(ret != 0) return usage();
1013
1014 if(android_srcpath != NULL)
1015 ret = do_sync_sync(android_srcpath, "/system");
1016 if(ret == 0 && data_srcpath != NULL)
1017 ret = do_sync_sync(data_srcpath, "/data");
1018
1019 free(android_srcpath);
1020 free(data_srcpath);
1021 return ret;
1022 }
1023
1024 /* passthrough commands */
1025
1026 if(!strcmp(argv[0],"get-state") ||
1027 !strcmp(argv[0],"get-serialno"))
1028 {
1029 char *tmp;
1030
1031 format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1032 tmp = adb_query(buf);
1033 if(tmp) {
1034 printf("%s\n", tmp);
1035 return 0;
1036 } else {
1037 return 1;
1038 }
1039 }
1040
1041 /* other commands */
1042
1043 if(!strcmp(argv[0],"status-window")) {
1044 status_window(ttype, serial);
1045 return 0;
1046 }
1047
1048 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1049 return logcat(ttype, serial, argc, argv);
1050 }
1051
1052 if(!strcmp(argv[0],"ppp")) {
1053 return ppp(argc, argv);
1054 }
1055
1056 if (!strcmp(argv[0], "start-server")) {
1057 return adb_connect("host:start-server");
1058 }
1059
1060 if (!strcmp(argv[0], "jdwp")) {
1061 int fd = adb_connect("jdwp");
1062 if (fd >= 0) {
1063 read_and_dump(fd);
1064 adb_close(fd);
1065 return 0;
1066 } else {
1067 fprintf(stderr, "error: %s\n", adb_error());
1068 return -1;
1069 }
1070 }
1071
1072 /* "adb /?" is a common idiom under Windows */
1073 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1074 help();
1075 return 0;
1076 }
1077
1078 if(!strcmp(argv[0], "version")) {
1079 version(stdout);
1080 return 0;
1081 }
1082
1083 usage();
1084 return 1;
1085}
1086
1087static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1088{
1089 char *argv[16];
1090 int argc;
1091 va_list ap;
1092
1093 va_start(ap, cmd);
1094 argc = 0;
1095
1096 if (serial) {
1097 argv[argc++] = "-s";
1098 argv[argc++] = serial;
1099 } else if (ttype == kTransportUsb) {
1100 argv[argc++] = "-d";
1101 } else if (ttype == kTransportLocal) {
1102 argv[argc++] = "-e";
1103 }
1104
1105 argv[argc++] = cmd;
1106 while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1107 va_end(ap);
1108
1109#if 0
1110 int n;
1111 fprintf(stderr,"argc = %d\n",argc);
1112 for(n = 0; n < argc; n++) {
1113 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1114 }
1115#endif
1116
1117 return adb_commandline(argc, argv);
1118}
1119
1120int find_sync_dirs(const char *srcarg,
1121 char **android_srcdir_out, char **data_srcdir_out)
1122{
1123 char *android_srcdir, *data_srcdir;
1124
1125 if(srcarg == NULL) {
1126 android_srcdir = product_file("system");
1127 data_srcdir = product_file("data");
1128 } else {
1129 /* srcarg may be "data", "system" or NULL.
1130 * if srcarg is NULL, then both data and system are synced
1131 */
1132 if(strcmp(srcarg, "system") == 0) {
1133 android_srcdir = product_file("system");
1134 data_srcdir = NULL;
1135 } else if(strcmp(srcarg, "data") == 0) {
1136 android_srcdir = NULL;
1137 data_srcdir = product_file("data");
1138 } else {
1139 /* It's not "system" or "data".
1140 */
1141 return 1;
1142 }
1143 }
1144
1145 if(android_srcdir_out != NULL)
1146 *android_srcdir_out = android_srcdir;
1147 else
1148 free(android_srcdir);
1149
1150 if(data_srcdir_out != NULL)
1151 *data_srcdir_out = data_srcdir;
1152 else
1153 free(data_srcdir);
1154
1155 return 0;
1156}
1157
1158static int pm_command(transport_type transport, char* serial,
1159 int argc, char** argv)
1160{
1161 char buf[4096];
1162
1163 snprintf(buf, sizeof(buf), "shell:pm");
1164
1165 while(argc-- > 0) {
1166 char *quoted;
1167
1168 quoted = dupAndQuote(*argv++);
1169
1170 strncat(buf, " ", sizeof(buf)-1);
1171 strncat(buf, quoted, sizeof(buf)-1);
1172 free(quoted);
1173 }
1174
1175 send_shellcommand(transport, serial, buf);
1176 return 0;
1177}
1178
1179int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1180{
1181 /* if the user choose the -k option, we refuse to do it until devices are
1182 out with the option to uninstall the remaining data somehow (adb/ui) */
1183 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1184 {
1185 printf(
1186 "The -k option uninstalls the application while retaining the data/cache.\n"
1187 "At the moment, there is no way to remove the remaining data.\n"
1188 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1189 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1190 return -1;
1191 }
1192
1193 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1194 return pm_command(transport, serial, argc, argv);
1195}
1196
1197static int delete_file(transport_type transport, char* serial, char* filename)
1198{
1199 char buf[4096];
1200 char* quoted;
1201
1202 snprintf(buf, sizeof(buf), "shell:rm ");
1203 quoted = dupAndQuote(filename);
1204 strncat(buf, quoted, sizeof(buf)-1);
1205 free(quoted);
1206
1207 send_shellcommand(transport, serial, buf);
1208 return 0;
1209}
1210
1211int install_app(transport_type transport, char* serial, int argc, char** argv)
1212{
1213 struct stat st;
1214 int err;
1215 const char *const WHERE = "/data/local/tmp/%s";
1216 char to[PATH_MAX];
1217 char* filename = argv[argc - 1];
1218 const char* p;
1219
1220 p = adb_dirstop(filename);
1221 if (p) {
1222 p++;
1223 snprintf(to, sizeof to, WHERE, p);
1224 } else {
1225 snprintf(to, sizeof to, WHERE, filename);
1226 }
1227 if (p[0] == '\0') {
1228 }
1229
1230 err = stat(filename, &st);
1231 if (err != 0) {
1232 fprintf(stderr, "can't find '%s' to install\n", filename);
1233 return 1;
1234 }
1235 if (!S_ISREG(st.st_mode)) {
1236 fprintf(stderr, "can't install '%s' because it's not a file\n",
1237 filename);
1238 return 1;
1239 }
1240
1241 if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) {
1242 /* file in place; tell the Package Manager to install it */
1243 argv[argc - 1] = to; /* destination name, not source location */
1244 pm_command(transport, serial, argc, argv);
1245 delete_file(transport, serial, to);
1246 }
1247
1248 return err;
1249}