commandline.c revision e037fd7e193ecccbb5c0888e49f6d58c224bc11d
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 root - restarts adb with root permissions\n" 151 "\n" 152 "networking:\n" 153 " adb ppp <tty> [parameters] - Run PPP over USB.\n" 154 " Note: you should not automatically start a PDP connection.\n" 155 " <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 918 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 929 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} 1262