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