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