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