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