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