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