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