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