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