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