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