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