commandline.c revision 8071a4bdb6e437baa4efcb8cf777d4caeaf069e4
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 == 2) { 1026 return do_sync_pull(argv[1], "."); 1027 } else if (argc == 3) { 1028 return do_sync_pull(argv[1], argv[2]); 1029 } else { 1030 return usage(); 1031 } 1032 } 1033 1034 if(!strcmp(argv[0], "install")) { 1035 if (argc < 2) return usage(); 1036 return install_app(ttype, serial, argc, argv); 1037 } 1038 1039 if(!strcmp(argv[0], "uninstall")) { 1040 if (argc < 2) return usage(); 1041 return uninstall_app(ttype, serial, argc, argv); 1042 } 1043 1044 if(!strcmp(argv[0], "sync")) { 1045 char *srcarg, *android_srcpath, *data_srcpath; 1046 int ret; 1047 if(argc < 2) { 1048 /* No local path was specified. */ 1049 srcarg = NULL; 1050 } else if(argc == 2) { 1051 /* A local path or "android"/"data" arg was specified. */ 1052 srcarg = argv[1]; 1053 } else { 1054 return usage(); 1055 } 1056 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath); 1057 if(ret != 0) return usage(); 1058 1059 if(android_srcpath != NULL) 1060 ret = do_sync_sync(android_srcpath, "/system"); 1061 if(ret == 0 && data_srcpath != NULL) 1062 ret = do_sync_sync(data_srcpath, "/data"); 1063 1064 free(android_srcpath); 1065 free(data_srcpath); 1066 return ret; 1067 } 1068 1069 /* passthrough commands */ 1070 1071 if(!strcmp(argv[0],"get-state") || 1072 !strcmp(argv[0],"get-serialno")) 1073 { 1074 char *tmp; 1075 1076 format_host_command(buf, sizeof buf, argv[0], ttype, serial); 1077 tmp = adb_query(buf); 1078 if(tmp) { 1079 printf("%s\n", tmp); 1080 return 0; 1081 } else { 1082 return 1; 1083 } 1084 } 1085 1086 /* other commands */ 1087 1088 if(!strcmp(argv[0],"status-window")) { 1089 status_window(ttype, serial); 1090 return 0; 1091 } 1092 1093 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) { 1094 return logcat(ttype, serial, argc, argv); 1095 } 1096 1097 if(!strcmp(argv[0],"ppp")) { 1098 return ppp(argc, argv); 1099 } 1100 1101 if (!strcmp(argv[0], "start-server")) { 1102 return adb_connect("host:start-server"); 1103 } 1104 1105 if (!strcmp(argv[0], "jdwp")) { 1106 int fd = adb_connect("jdwp"); 1107 if (fd >= 0) { 1108 read_and_dump(fd); 1109 adb_close(fd); 1110 return 0; 1111 } else { 1112 fprintf(stderr, "error: %s\n", adb_error()); 1113 return -1; 1114 } 1115 } 1116 1117 /* "adb /?" is a common idiom under Windows */ 1118 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) { 1119 help(); 1120 return 0; 1121 } 1122 1123 if(!strcmp(argv[0], "version")) { 1124 version(stdout); 1125 return 0; 1126 } 1127 1128 usage(); 1129 return 1; 1130} 1131 1132static int do_cmd(transport_type ttype, char* serial, char *cmd, ...) 1133{ 1134 char *argv[16]; 1135 int argc; 1136 va_list ap; 1137 1138 va_start(ap, cmd); 1139 argc = 0; 1140 1141 if (serial) { 1142 argv[argc++] = "-s"; 1143 argv[argc++] = serial; 1144 } else if (ttype == kTransportUsb) { 1145 argv[argc++] = "-d"; 1146 } else if (ttype == kTransportLocal) { 1147 argv[argc++] = "-e"; 1148 } 1149 1150 argv[argc++] = cmd; 1151 while((argv[argc] = va_arg(ap, char*)) != 0) argc++; 1152 va_end(ap); 1153 1154#if 0 1155 int n; 1156 fprintf(stderr,"argc = %d\n",argc); 1157 for(n = 0; n < argc; n++) { 1158 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]); 1159 } 1160#endif 1161 1162 return adb_commandline(argc, argv); 1163} 1164 1165int find_sync_dirs(const char *srcarg, 1166 char **android_srcdir_out, char **data_srcdir_out) 1167{ 1168 char *android_srcdir, *data_srcdir; 1169 1170 if(srcarg == NULL) { 1171 android_srcdir = product_file("system"); 1172 data_srcdir = product_file("data"); 1173 } else { 1174 /* srcarg may be "data", "system" or NULL. 1175 * if srcarg is NULL, then both data and system are synced 1176 */ 1177 if(strcmp(srcarg, "system") == 0) { 1178 android_srcdir = product_file("system"); 1179 data_srcdir = NULL; 1180 } else if(strcmp(srcarg, "data") == 0) { 1181 android_srcdir = NULL; 1182 data_srcdir = product_file("data"); 1183 } else { 1184 /* It's not "system" or "data". 1185 */ 1186 return 1; 1187 } 1188 } 1189 1190 if(android_srcdir_out != NULL) 1191 *android_srcdir_out = android_srcdir; 1192 else 1193 free(android_srcdir); 1194 1195 if(data_srcdir_out != NULL) 1196 *data_srcdir_out = data_srcdir; 1197 else 1198 free(data_srcdir); 1199 1200 return 0; 1201} 1202 1203static int pm_command(transport_type transport, char* serial, 1204 int argc, char** argv) 1205{ 1206 char buf[4096]; 1207 1208 snprintf(buf, sizeof(buf), "shell:pm"); 1209 1210 while(argc-- > 0) { 1211 char *quoted; 1212 1213 quoted = dupAndQuote(*argv++); 1214 1215 strncat(buf, " ", sizeof(buf)-1); 1216 strncat(buf, quoted, sizeof(buf)-1); 1217 free(quoted); 1218 } 1219 1220 send_shellcommand(transport, serial, buf); 1221 return 0; 1222} 1223 1224int uninstall_app(transport_type transport, char* serial, int argc, char** argv) 1225{ 1226 /* if the user choose the -k option, we refuse to do it until devices are 1227 out with the option to uninstall the remaining data somehow (adb/ui) */ 1228 if (argc == 3 && strcmp(argv[1], "-k") == 0) 1229 { 1230 printf( 1231 "The -k option uninstalls the application while retaining the data/cache.\n" 1232 "At the moment, there is no way to remove the remaining data.\n" 1233 "You will have to reinstall the application with the same signature, and fully uninstall it.\n" 1234 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]); 1235 return -1; 1236 } 1237 1238 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */ 1239 return pm_command(transport, serial, argc, argv); 1240} 1241 1242static int delete_file(transport_type transport, char* serial, char* filename) 1243{ 1244 char buf[4096]; 1245 char* quoted; 1246 1247 snprintf(buf, sizeof(buf), "shell:rm "); 1248 quoted = dupAndQuote(filename); 1249 strncat(buf, quoted, sizeof(buf)-1); 1250 free(quoted); 1251 1252 send_shellcommand(transport, serial, buf); 1253 return 0; 1254} 1255 1256int install_app(transport_type transport, char* serial, int argc, char** argv) 1257{ 1258 struct stat st; 1259 int err; 1260 const char *const WHERE = "/data/local/tmp/%s"; 1261 char to[PATH_MAX]; 1262 char* filename = argv[argc - 1]; 1263 const char* p; 1264 1265 p = adb_dirstop(filename); 1266 if (p) { 1267 p++; 1268 snprintf(to, sizeof to, WHERE, p); 1269 } else { 1270 snprintf(to, sizeof to, WHERE, filename); 1271 } 1272 if (p[0] == '\0') { 1273 } 1274 1275 err = stat(filename, &st); 1276 if (err != 0) { 1277 fprintf(stderr, "can't find '%s' to install\n", filename); 1278 return 1; 1279 } 1280 if (!S_ISREG(st.st_mode)) { 1281 fprintf(stderr, "can't install '%s' because it's not a file\n", 1282 filename); 1283 return 1; 1284 } 1285 1286 if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) { 1287 /* file in place; tell the Package Manager to install it */ 1288 argv[argc - 1] = to; /* destination name, not source location */ 1289 pm_command(transport, serial, argc, argv); 1290 delete_file(transport, serial, to); 1291 } 1292 1293 return err; 1294} 1295