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