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