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 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...); 41 42 void get_my_path(char *s, size_t maxLen); 43 int find_sync_dirs(const char *srcarg, 44 char **android_srcdir_out, char **data_srcdir_out); 45 int install_app(transport_type transport, char* serial, int argc, char** argv); 46 int uninstall_app(transport_type transport, char* serial, int argc, char** argv); 47 48 static const char *gProductOutPath = NULL; 49 extern int gListenAll; 50 51 static char *product_file(const char *extra) 52 { 53 int n; 54 char *x; 55 56 if (gProductOutPath == NULL) { 57 fprintf(stderr, "adb: Product directory not specified; " 58 "use -p or define ANDROID_PRODUCT_OUT\n"); 59 exit(1); 60 } 61 62 n = strlen(gProductOutPath) + strlen(extra) + 2; 63 x = malloc(n); 64 if (x == 0) { 65 fprintf(stderr, "adb: Out of memory (product_file())\n"); 66 exit(1); 67 } 68 69 snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra); 70 return x; 71 } 72 73 void version(FILE * out) { 74 fprintf(out, "Android Debug Bridge version %d.%d.%d\n", 75 ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION); 76 } 77 78 void help() 79 { 80 version(stderr); 81 82 fprintf(stderr, 83 "\n" 84 " -a - directs adb to listen on all interfaces for a connection\n" 85 " -d - directs command to the only connected USB device\n" 86 " returns an error if more than one USB device is present.\n" 87 " -e - directs command to the only running emulator.\n" 88 " returns an error if more than one emulator is running.\n" 89 " -s <specific device> - directs command to the device or emulator with the given\n" 90 " serial number or qualifier. Overrides ANDROID_SERIAL\n" 91 " environment variable.\n" 92 " -p <product name or path> - simple product name like 'sooner', or\n" 93 " a relative/absolute path to a product\n" 94 " out directory like 'out/target/product/sooner'.\n" 95 " If -p is not specified, the ANDROID_PRODUCT_OUT\n" 96 " environment variable is used, which must\n" 97 " be an absolute path.\n" 98 " -H - Name of adb server host (default: localhost)\n" 99 " -P - Port of adb server (default: 5037)\n" 100 " devices [-l] - list all connected devices\n" 101 " ('-l' will also list device qualifiers)\n" 102 " connect <host>[:<port>] - connect to a device via TCP/IP\n" 103 " Port 5555 is used by default if no port number is specified.\n" 104 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n" 105 " Port 5555 is used by default if no port number is specified.\n" 106 " Using this command with no additional arguments\n" 107 " will disconnect from all connected TCP/IP devices.\n" 108 "\n" 109 "device commands:\n" 110 " adb push <local> <remote> - copy file/dir to device\n" 111 " adb pull <remote> [<local>] - copy file/dir from device\n" 112 " adb sync [ <directory> ] - copy host->device only if changed\n" 113 " (-l means list but don't copy)\n" 114 " (see 'adb help all')\n" 115 " adb shell - run remote shell interactively\n" 116 " adb shell <command> - run remote shell command\n" 117 " adb emu <command> - run emulator console command\n" 118 " adb logcat [ <filter-spec> ] - View device log\n" 119 " adb forward --list - list all forward socket connections.\n" 120 " the format is a list of lines with the following format:\n" 121 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n" 122 " adb forward <local> <remote> - forward socket connections\n" 123 " forward specs are one of: \n" 124 " tcp:<port>\n" 125 " localabstract:<unix domain socket name>\n" 126 " localreserved:<unix domain socket name>\n" 127 " localfilesystem:<unix domain socket name>\n" 128 " dev:<character device name>\n" 129 " jdwp:<process pid> (remote only)\n" 130 " adb forward --no-rebind <local> <remote>\n" 131 " - same as 'adb forward <local> <remote>' but fails\n" 132 " if <local> is already forwarded\n" 133 " adb forward --remove <local> - remove a specific forward socket connection\n" 134 " adb forward --remove-all - remove all forward socket connections\n" 135 " adb jdwp - list PIDs of processes hosting a JDWP transport\n" 136 " adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n" 137 " - push this package file to the device and install it\n" 138 " ('-l' means forward-lock the app)\n" 139 " ('-r' means reinstall the app, keeping its data)\n" 140 " ('-s' means install on SD card instead of internal storage)\n" 141 " ('--algo', '--key', and '--iv' mean the file is encrypted already)\n" 142 " adb uninstall [-k] <package> - remove this app package from the device\n" 143 " ('-k' means keep the data and cache directories)\n" 144 " adb bugreport - return all information from the device\n" 145 " that should be included in a bug report.\n" 146 "\n" 147 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n" 148 " - write an archive of the device's data to <file>.\n" 149 " If no -f option is supplied then the data is written\n" 150 " to \"backup.ab\" in the current directory.\n" 151 " (-apk|-noapk enable/disable backup of the .apks themselves\n" 152 " in the archive; the default is noapk.)\n" 153 " (-obb|-noobb enable/disable backup of any installed apk expansion\n" 154 " (aka .obb) files associated with each application; the default\n" 155 " is noobb.)\n" 156 " (-shared|-noshared enable/disable backup of the device's\n" 157 " shared storage / SD card contents; the default is noshared.)\n" 158 " (-all means to back up all installed applications)\n" 159 " (-system|-nosystem toggles whether -all automatically includes\n" 160 " system applications; the default is to include system apps)\n" 161 " (<packages...> is the list of applications to be backed up. If\n" 162 " the -all or -shared flags are passed, then the package\n" 163 " list is optional. Applications explicitly given on the\n" 164 " command line will be included even if -nosystem would\n" 165 " ordinarily cause them to be omitted.)\n" 166 "\n" 167 " adb restore <file> - restore device contents from the <file> backup archive\n" 168 "\n" 169 " adb help - show this help message\n" 170 " adb version - show version num\n" 171 "\n" 172 "scripting:\n" 173 " adb wait-for-device - block until device is online\n" 174 " adb start-server - ensure that there is a server running\n" 175 " adb kill-server - kill the server if it is running\n" 176 " adb get-state - prints: offline | bootloader | device\n" 177 " adb get-serialno - prints: <serial-number>\n" 178 " adb get-devpath - prints: <device-path>\n" 179 " adb status-window - continuously print device status for a specified device\n" 180 " adb remount - remounts the /system partition on the device read-write\n" 181 " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n" 182 " adb reboot-bootloader - reboots the device into the bootloader\n" 183 " adb root - restarts the adbd daemon with root permissions\n" 184 " adb usb - restarts the adbd daemon listening on USB\n" 185 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port" 186 "\n" 187 "networking:\n" 188 " adb ppp <tty> [parameters] - Run PPP over USB.\n" 189 " Note: you should not automatically start a PPP connection.\n" 190 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n" 191 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n" 192 "\n" 193 "adb sync notes: adb sync [ <directory> ]\n" 194 " <localdir> can be interpreted in several ways:\n" 195 "\n" 196 " - If <directory> is not specified, both /system and /data partitions will be updated.\n" 197 "\n" 198 " - If it is \"system\" or \"data\", only the corresponding partition\n" 199 " is updated.\n" 200 "\n" 201 "environmental variables:\n" 202 " ADB_TRACE - Print debug information. A comma separated list of the following values\n" 203 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n" 204 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n" 205 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n" 206 ); 207 } 208 209 int usage() 210 { 211 help(); 212 return 1; 213 } 214 215 #ifdef HAVE_TERMIO_H 216 static struct termios tio_save; 217 218 static void stdin_raw_init(int fd) 219 { 220 struct termios tio; 221 222 if(tcgetattr(fd, &tio)) return; 223 if(tcgetattr(fd, &tio_save)) return; 224 225 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */ 226 227 /* no timeout but request at least one character per read */ 228 tio.c_cc[VTIME] = 0; 229 tio.c_cc[VMIN] = 1; 230 231 tcsetattr(fd, TCSANOW, &tio); 232 tcflush(fd, TCIFLUSH); 233 } 234 235 static void stdin_raw_restore(int fd) 236 { 237 tcsetattr(fd, TCSANOW, &tio_save); 238 tcflush(fd, TCIFLUSH); 239 } 240 #endif 241 242 static void read_and_dump(int fd) 243 { 244 char buf[4096]; 245 int len; 246 247 while(fd >= 0) { 248 D("read_and_dump(): pre adb_read(fd=%d)\n", fd); 249 len = adb_read(fd, buf, 4096); 250 D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len); 251 if(len == 0) { 252 break; 253 } 254 255 if(len < 0) { 256 if(errno == EINTR) continue; 257 break; 258 } 259 fwrite(buf, 1, len, stdout); 260 fflush(stdout); 261 } 262 } 263 264 static void copy_to_file(int inFd, int outFd) { 265 const size_t BUFSIZE = 32 * 1024; 266 char* buf = (char*) malloc(BUFSIZE); 267 int len; 268 long total = 0; 269 270 D("copy_to_file(%d -> %d)\n", inFd, outFd); 271 for (;;) { 272 len = adb_read(inFd, buf, BUFSIZE); 273 if (len == 0) { 274 D("copy_to_file() : read 0 bytes; exiting\n"); 275 break; 276 } 277 if (len < 0) { 278 if (errno == EINTR) { 279 D("copy_to_file() : EINTR, retrying\n"); 280 continue; 281 } 282 D("copy_to_file() : error %d\n", errno); 283 break; 284 } 285 adb_write(outFd, buf, len); 286 total += len; 287 } 288 D("copy_to_file() finished after %lu bytes\n", total); 289 free(buf); 290 } 291 292 static void *stdin_read_thread(void *x) 293 { 294 int fd, fdi; 295 unsigned char buf[1024]; 296 int r, n; 297 int state = 0; 298 299 int *fds = (int*) x; 300 fd = fds[0]; 301 fdi = fds[1]; 302 free(fds); 303 304 for(;;) { 305 /* fdi is really the client's stdin, so use read, not adb_read here */ 306 D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi); 307 r = unix_read(fdi, buf, 1024); 308 D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi); 309 if(r == 0) break; 310 if(r < 0) { 311 if(errno == EINTR) continue; 312 break; 313 } 314 for(n = 0; n < r; n++){ 315 switch(buf[n]) { 316 case '\n': 317 state = 1; 318 break; 319 case '\r': 320 state = 1; 321 break; 322 case '~': 323 if(state == 1) state++; 324 break; 325 case '.': 326 if(state == 2) { 327 fprintf(stderr,"\n* disconnect *\n"); 328 #ifdef HAVE_TERMIO_H 329 stdin_raw_restore(fdi); 330 #endif 331 exit(0); 332 } 333 default: 334 state = 0; 335 } 336 } 337 r = adb_write(fd, buf, r); 338 if(r <= 0) { 339 break; 340 } 341 } 342 return 0; 343 } 344 345 int interactive_shell(void) 346 { 347 adb_thread_t thr; 348 int fdi, fd; 349 int *fds; 350 351 fd = adb_connect("shell:"); 352 if(fd < 0) { 353 fprintf(stderr,"error: %s\n", adb_error()); 354 return 1; 355 } 356 fdi = 0; //dup(0); 357 358 fds = malloc(sizeof(int) * 2); 359 fds[0] = fd; 360 fds[1] = fdi; 361 362 #ifdef HAVE_TERMIO_H 363 stdin_raw_init(fdi); 364 #endif 365 adb_thread_create(&thr, stdin_read_thread, fds); 366 read_and_dump(fd); 367 #ifdef HAVE_TERMIO_H 368 stdin_raw_restore(fdi); 369 #endif 370 return 0; 371 } 372 373 374 static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial) 375 { 376 if (serial) { 377 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command); 378 } else { 379 const char* prefix = "host"; 380 if (ttype == kTransportUsb) 381 prefix = "host-usb"; 382 else if (ttype == kTransportLocal) 383 prefix = "host-local"; 384 385 snprintf(buffer, buflen, "%s:%s", prefix, command); 386 } 387 } 388 389 int adb_download_buffer(const char *service, const char *fn, const void* data, int sz, 390 unsigned progress) 391 { 392 char buf[4096]; 393 unsigned total; 394 int fd; 395 const unsigned char *ptr; 396 397 sprintf(buf,"%s:%d", service, sz); 398 fd = adb_connect(buf); 399 if(fd < 0) { 400 fprintf(stderr,"error: %s\n", adb_error()); 401 return -1; 402 } 403 404 int opt = CHUNK_SIZE; 405 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)); 406 407 total = sz; 408 ptr = data; 409 410 if(progress) { 411 char *x = strrchr(service, ':'); 412 if(x) service = x + 1; 413 } 414 415 while(sz > 0) { 416 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz; 417 if(writex(fd, ptr, xfer)) { 418 adb_status(fd); 419 fprintf(stderr,"* failed to write data '%s' *\n", adb_error()); 420 return -1; 421 } 422 sz -= xfer; 423 ptr += xfer; 424 if(progress) { 425 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total)))); 426 fflush(stdout); 427 } 428 } 429 if(progress) { 430 printf("\n"); 431 } 432 433 if(readx(fd, buf, 4)){ 434 fprintf(stderr,"* error reading response *\n"); 435 adb_close(fd); 436 return -1; 437 } 438 if(memcmp(buf, "OKAY", 4)) { 439 buf[4] = 0; 440 fprintf(stderr,"* error response '%s' *\n", buf); 441 adb_close(fd); 442 return -1; 443 } 444 445 adb_close(fd); 446 return 0; 447 } 448 449 450 int adb_download(const char *service, const char *fn, unsigned progress) 451 { 452 void *data; 453 unsigned sz; 454 455 data = load_file(fn, &sz); 456 if(data == 0) { 457 fprintf(stderr,"* cannot read '%s' *\n", fn); 458 return -1; 459 } 460 461 int status = adb_download_buffer(service, fn, data, sz, progress); 462 free(data); 463 return status; 464 } 465 466 static void status_window(transport_type ttype, const char* serial) 467 { 468 char command[4096]; 469 char *state = 0; 470 char *laststate = 0; 471 472 /* silence stderr */ 473 #ifdef _WIN32 474 /* XXX: TODO */ 475 #else 476 int fd; 477 fd = unix_open("/dev/null", O_WRONLY); 478 dup2(fd, 2); 479 adb_close(fd); 480 #endif 481 482 format_host_command(command, sizeof command, "get-state", ttype, serial); 483 484 for(;;) { 485 adb_sleep_ms(250); 486 487 if(state) { 488 free(state); 489 state = 0; 490 } 491 492 state = adb_query(command); 493 494 if(state) { 495 if(laststate && !strcmp(state,laststate)){ 496 continue; 497 } else { 498 if(laststate) free(laststate); 499 laststate = strdup(state); 500 } 501 } 502 503 printf("%c[2J%c[2H", 27, 27); 504 printf("Android Debug Bridge\n"); 505 printf("State: %s\n", state ? state : "offline"); 506 fflush(stdout); 507 } 508 } 509 510 /** duplicate string and quote all \ " ( ) chars + space character. */ 511 static char * 512 dupAndQuote(const char *s) 513 { 514 const char *ts; 515 size_t alloc_len; 516 char *ret; 517 char *dest; 518 519 ts = s; 520 521 alloc_len = 0; 522 523 for( ;*ts != '\0'; ts++) { 524 alloc_len++; 525 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { 526 alloc_len++; 527 } 528 } 529 530 ret = (char *)malloc(alloc_len + 1); 531 532 ts = s; 533 dest = ret; 534 535 for ( ;*ts != '\0'; ts++) { 536 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { 537 *dest++ = '\\'; 538 } 539 540 *dest++ = *ts; 541 } 542 543 *dest++ = '\0'; 544 545 return ret; 546 } 547 548 /** 549 * Run ppp in "notty" mode against a resource listed as the first parameter 550 * eg: 551 * 552 * ppp dev:/dev/omap_csmi_tty0 <ppp options> 553 * 554 */ 555 int ppp(int argc, char **argv) 556 { 557 #ifdef HAVE_WIN32_PROC 558 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]); 559 return -1; 560 #else 561 char *adb_service_name; 562 pid_t pid; 563 int fd; 564 565 if (argc < 2) { 566 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n", 567 argv[0]); 568 569 return 1; 570 } 571 572 adb_service_name = argv[1]; 573 574 fd = adb_connect(adb_service_name); 575 576 if(fd < 0) { 577 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n", 578 adb_service_name, adb_error()); 579 return 1; 580 } 581 582 pid = fork(); 583 584 if (pid < 0) { 585 perror("from fork()"); 586 return 1; 587 } else if (pid == 0) { 588 int err; 589 int i; 590 const char **ppp_args; 591 592 // copy args 593 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1); 594 ppp_args[0] = "pppd"; 595 for (i = 2 ; i < argc ; i++) { 596 //argv[2] and beyond become ppp_args[1] and beyond 597 ppp_args[i - 1] = argv[i]; 598 } 599 ppp_args[i-1] = NULL; 600 601 // child side 602 603 dup2(fd, STDIN_FILENO); 604 dup2(fd, STDOUT_FILENO); 605 adb_close(STDERR_FILENO); 606 adb_close(fd); 607 608 err = execvp("pppd", (char * const *)ppp_args); 609 610 if (err < 0) { 611 perror("execing pppd"); 612 } 613 exit(-1); 614 } else { 615 // parent side 616 617 adb_close(fd); 618 return 0; 619 } 620 #endif /* !HAVE_WIN32_PROC */ 621 } 622 623 static int send_shellcommand(transport_type transport, char* serial, char* buf) 624 { 625 int fd, ret; 626 627 for(;;) { 628 fd = adb_connect(buf); 629 if(fd >= 0) 630 break; 631 fprintf(stderr,"- waiting for device -\n"); 632 adb_sleep_ms(1000); 633 do_cmd(transport, serial, "wait-for-device", 0); 634 } 635 636 read_and_dump(fd); 637 ret = adb_close(fd); 638 if (ret) 639 perror("close"); 640 641 return ret; 642 } 643 644 static int logcat(transport_type transport, char* serial, int argc, char **argv) 645 { 646 char buf[4096]; 647 648 char *log_tags; 649 char *quoted_log_tags; 650 651 log_tags = getenv("ANDROID_LOG_TAGS"); 652 quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags); 653 654 snprintf(buf, sizeof(buf), 655 "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat", 656 quoted_log_tags); 657 658 free(quoted_log_tags); 659 660 if (!strcmp(argv[0],"longcat")) { 661 strncat(buf, " -v long", sizeof(buf)-1); 662 } 663 664 argc -= 1; 665 argv += 1; 666 while(argc-- > 0) { 667 char *quoted; 668 669 quoted = dupAndQuote (*argv++); 670 671 strncat(buf, " ", sizeof(buf)-1); 672 strncat(buf, quoted, sizeof(buf)-1); 673 free(quoted); 674 } 675 676 send_shellcommand(transport, serial, buf); 677 return 0; 678 } 679 680 static int mkdirs(char *path) 681 { 682 int ret; 683 char *x = path + 1; 684 685 for(;;) { 686 x = adb_dirstart(x); 687 if(x == 0) return 0; 688 *x = 0; 689 ret = adb_mkdir(path, 0775); 690 *x = OS_PATH_SEPARATOR; 691 if((ret < 0) && (errno != EEXIST)) { 692 return ret; 693 } 694 x++; 695 } 696 return 0; 697 } 698 699 static int backup(int argc, char** argv) { 700 char buf[4096]; 701 char default_name[32]; 702 const char* filename = strcpy(default_name, "./backup.ab"); 703 int fd, outFd; 704 int i, j; 705 706 /* find, extract, and use any -f argument */ 707 for (i = 1; i < argc; i++) { 708 if (!strcmp("-f", argv[i])) { 709 if (i == argc-1) { 710 fprintf(stderr, "adb: -f passed with no filename\n"); 711 return usage(); 712 } 713 filename = argv[i+1]; 714 for (j = i+2; j <= argc; ) { 715 argv[i++] = argv[j++]; 716 } 717 argc -= 2; 718 argv[argc] = NULL; 719 } 720 } 721 722 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */ 723 if (argc < 2) return usage(); 724 725 adb_unlink(filename); 726 mkdirs((char *)filename); 727 outFd = adb_creat(filename, 0640); 728 if (outFd < 0) { 729 fprintf(stderr, "adb: unable to open file %s\n", filename); 730 return -1; 731 } 732 733 snprintf(buf, sizeof(buf), "backup"); 734 for (argc--, argv++; argc; argc--, argv++) { 735 strncat(buf, ":", sizeof(buf) - strlen(buf) - 1); 736 strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1); 737 } 738 739 D("backup. filename=%s buf=%s\n", filename, buf); 740 fd = adb_connect(buf); 741 if (fd < 0) { 742 fprintf(stderr, "adb: unable to connect for backup\n"); 743 adb_close(outFd); 744 return -1; 745 } 746 747 printf("Now unlock your device and confirm the backup operation.\n"); 748 copy_to_file(fd, outFd); 749 750 adb_close(fd); 751 adb_close(outFd); 752 return 0; 753 } 754 755 static int restore(int argc, char** argv) { 756 const char* filename; 757 int fd, tarFd; 758 759 if (argc != 2) return usage(); 760 761 filename = argv[1]; 762 tarFd = adb_open(filename, O_RDONLY); 763 if (tarFd < 0) { 764 fprintf(stderr, "adb: unable to open file %s\n", filename); 765 return -1; 766 } 767 768 fd = adb_connect("restore:"); 769 if (fd < 0) { 770 fprintf(stderr, "adb: unable to connect for backup\n"); 771 adb_close(tarFd); 772 return -1; 773 } 774 775 printf("Now unlock your device and confirm the restore operation.\n"); 776 copy_to_file(tarFd, fd); 777 778 adb_close(fd); 779 adb_close(tarFd); 780 return 0; 781 } 782 783 #define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make" 784 static int top_works(const char *top) 785 { 786 if (top != NULL && adb_is_absolute_host_path(top)) { 787 char path_buf[PATH_MAX]; 788 snprintf(path_buf, sizeof(path_buf), 789 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top); 790 return access(path_buf, F_OK) == 0; 791 } 792 return 0; 793 } 794 795 static char *find_top_from(const char *indir, char path_buf[PATH_MAX]) 796 { 797 strcpy(path_buf, indir); 798 while (1) { 799 if (top_works(path_buf)) { 800 return path_buf; 801 } 802 char *s = adb_dirstop(path_buf); 803 if (s != NULL) { 804 *s = '\0'; 805 } else { 806 path_buf[0] = '\0'; 807 return NULL; 808 } 809 } 810 } 811 812 static char *find_top(char path_buf[PATH_MAX]) 813 { 814 char *top = getenv("ANDROID_BUILD_TOP"); 815 if (top != NULL && top[0] != '\0') { 816 if (!top_works(top)) { 817 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top); 818 return NULL; 819 } 820 } else { 821 top = getenv("TOP"); 822 if (top != NULL && top[0] != '\0') { 823 if (!top_works(top)) { 824 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top); 825 return NULL; 826 } 827 } else { 828 top = NULL; 829 } 830 } 831 832 if (top != NULL) { 833 /* The environment pointed to a top directory that works. 834 */ 835 strcpy(path_buf, top); 836 return path_buf; 837 } 838 839 /* The environment didn't help. Walk up the tree from the CWD 840 * to see if we can find the top. 841 */ 842 char dir[PATH_MAX]; 843 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf); 844 if (top == NULL) { 845 /* If the CWD isn't under a good-looking top, see if the 846 * executable is. 847 */ 848 get_my_path(dir, PATH_MAX); 849 top = find_top_from(dir, path_buf); 850 } 851 return top; 852 } 853 854 /* <hint> may be: 855 * - A simple product name 856 * e.g., "sooner" 857 TODO: debug? sooner-debug, sooner:debug? 858 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir 859 * e.g., "out/target/product/sooner" 860 * - An absolute path to the PRODUCT_OUT dir 861 * e.g., "/src/device/out/target/product/sooner" 862 * 863 * Given <hint>, try to construct an absolute path to the 864 * ANDROID_PRODUCT_OUT dir. 865 */ 866 static const char *find_product_out_path(const char *hint) 867 { 868 static char path_buf[PATH_MAX]; 869 870 if (hint == NULL || hint[0] == '\0') { 871 return NULL; 872 } 873 874 /* If it's already absolute, don't bother doing any work. 875 */ 876 if (adb_is_absolute_host_path(hint)) { 877 strcpy(path_buf, hint); 878 return path_buf; 879 } 880 881 /* If there are any slashes in it, assume it's a relative path; 882 * make it absolute. 883 */ 884 if (adb_dirstart(hint) != NULL) { 885 if (getcwd(path_buf, sizeof(path_buf)) == NULL) { 886 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno)); 887 return NULL; 888 } 889 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) { 890 fprintf(stderr, "adb: Couldn't assemble path\n"); 891 return NULL; 892 } 893 strcat(path_buf, OS_PATH_SEPARATOR_STR); 894 strcat(path_buf, hint); 895 return path_buf; 896 } 897 898 /* It's a string without any slashes. Try to do something with it. 899 * 900 * Try to find the root of the build tree, and build a PRODUCT_OUT 901 * path from there. 902 */ 903 char top_buf[PATH_MAX]; 904 const char *top = find_top(top_buf); 905 if (top == NULL) { 906 fprintf(stderr, "adb: Couldn't find top of build tree\n"); 907 return NULL; 908 } 909 //TODO: if we have a way to indicate debug, look in out/debug/target/... 910 snprintf(path_buf, sizeof(path_buf), 911 "%s" OS_PATH_SEPARATOR_STR 912 "out" OS_PATH_SEPARATOR_STR 913 "target" OS_PATH_SEPARATOR_STR 914 "product" OS_PATH_SEPARATOR_STR 915 "%s", top_buf, hint); 916 if (access(path_buf, F_OK) < 0) { 917 fprintf(stderr, "adb: Couldn't find a product dir " 918 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf); 919 return NULL; 920 } 921 return path_buf; 922 } 923 924 int adb_commandline(int argc, char **argv) 925 { 926 char buf[4096]; 927 int no_daemon = 0; 928 int is_daemon = 0; 929 int is_server = 0; 930 int persist = 0; 931 int r; 932 int quote; 933 transport_type ttype = kTransportAny; 934 char* serial = NULL; 935 char* server_port_str = NULL; 936 937 /* If defined, this should be an absolute path to 938 * the directory containing all of the various system images 939 * for a particular product. If not defined, and the adb 940 * command requires this information, then the user must 941 * specify the path using "-p". 942 */ 943 gProductOutPath = getenv("ANDROID_PRODUCT_OUT"); 944 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') { 945 gProductOutPath = NULL; 946 } 947 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint 948 949 serial = getenv("ANDROID_SERIAL"); 950 951 /* Validate and assign the server port */ 952 server_port_str = getenv("ANDROID_ADB_SERVER_PORT"); 953 int server_port = DEFAULT_ADB_PORT; 954 if (server_port_str && strlen(server_port_str) > 0) { 955 server_port = (int) strtol(server_port_str, NULL, 0); 956 if (server_port <= 0 || server_port > 65535) { 957 fprintf(stderr, 958 "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n", 959 server_port_str); 960 return usage(); 961 } 962 } 963 964 /* modifiers and flags */ 965 while(argc > 0) { 966 if(!strcmp(argv[0],"server")) { 967 is_server = 1; 968 } else if(!strcmp(argv[0],"nodaemon")) { 969 no_daemon = 1; 970 } else if (!strcmp(argv[0], "fork-server")) { 971 /* this is a special flag used only when the ADB client launches the ADB Server */ 972 is_daemon = 1; 973 } else if(!strcmp(argv[0],"persist")) { 974 persist = 1; 975 } else if(!strncmp(argv[0], "-p", 2)) { 976 const char *product = NULL; 977 if (argv[0][2] == '\0') { 978 if (argc < 2) return usage(); 979 product = argv[1]; 980 argc--; 981 argv++; 982 } else { 983 product = argv[0] + 2; 984 } 985 gProductOutPath = find_product_out_path(product); 986 if (gProductOutPath == NULL) { 987 fprintf(stderr, "adb: could not resolve \"-p %s\"\n", 988 product); 989 return usage(); 990 } 991 } else if (argv[0][0]=='-' && argv[0][1]=='s') { 992 if (isdigit(argv[0][2])) { 993 serial = argv[0] + 2; 994 } else { 995 if(argc < 2 || argv[0][2] != '\0') return usage(); 996 serial = argv[1]; 997 argc--; 998 argv++; 999 } 1000 } else if (!strcmp(argv[0],"-d")) { 1001 ttype = kTransportUsb; 1002 } else if (!strcmp(argv[0],"-e")) { 1003 ttype = kTransportLocal; 1004 } else if (!strcmp(argv[0],"-a")) { 1005 gListenAll = 1; 1006 } else if(!strncmp(argv[0], "-H", 2)) { 1007 const char *hostname = NULL; 1008 if (argv[0][2] == '\0') { 1009 if (argc < 2) return usage(); 1010 hostname = argv[1]; 1011 argc--; 1012 argv++; 1013 } else { 1014 hostname = argv[0] + 2; 1015 } 1016 adb_set_tcp_name(hostname); 1017 1018 } else if(!strncmp(argv[0], "-P", 2)) { 1019 if (argv[0][2] == '\0') { 1020 if (argc < 2) return usage(); 1021 server_port_str = argv[1]; 1022 argc--; 1023 argv++; 1024 } else { 1025 server_port_str = argv[0] + 2; 1026 } 1027 if (strlen(server_port_str) > 0) { 1028 server_port = (int) strtol(server_port_str, NULL, 0); 1029 if (server_port <= 0 || server_port > 65535) { 1030 fprintf(stderr, 1031 "adb: port number must be a positive number less than 65536. Got \"%s\"\n", 1032 server_port_str); 1033 return usage(); 1034 } 1035 } else { 1036 fprintf(stderr, 1037 "adb: port number must be a positive number less than 65536. Got empty string.\n"); 1038 return usage(); 1039 } 1040 } else { 1041 /* out of recognized modifiers and flags */ 1042 break; 1043 } 1044 argc--; 1045 argv++; 1046 } 1047 1048 adb_set_transport(ttype, serial); 1049 adb_set_tcp_specifics(server_port); 1050 1051 if (is_server) { 1052 if (no_daemon || is_daemon) { 1053 r = adb_main(is_daemon, server_port); 1054 } else { 1055 r = launch_server(server_port); 1056 } 1057 if(r) { 1058 fprintf(stderr,"* could not start server *\n"); 1059 } 1060 return r; 1061 } 1062 1063 top: 1064 if(argc == 0) { 1065 return usage(); 1066 } 1067 1068 /* adb_connect() commands */ 1069 1070 if(!strcmp(argv[0], "devices")) { 1071 char *tmp; 1072 char *listopt; 1073 if (argc < 2) 1074 listopt = ""; 1075 else if (argc == 2 && !strcmp(argv[1], "-l")) 1076 listopt = argv[1]; 1077 else { 1078 fprintf(stderr, "Usage: adb devices [-l]\n"); 1079 return 1; 1080 } 1081 snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt); 1082 tmp = adb_query(buf); 1083 if(tmp) { 1084 printf("List of devices attached \n"); 1085 printf("%s\n", tmp); 1086 return 0; 1087 } else { 1088 return 1; 1089 } 1090 } 1091 1092 if(!strcmp(argv[0], "connect")) { 1093 char *tmp; 1094 if (argc != 2) { 1095 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n"); 1096 return 1; 1097 } 1098 snprintf(buf, sizeof buf, "host:connect:%s", argv[1]); 1099 tmp = adb_query(buf); 1100 if(tmp) { 1101 printf("%s\n", tmp); 1102 return 0; 1103 } else { 1104 return 1; 1105 } 1106 } 1107 1108 if(!strcmp(argv[0], "disconnect")) { 1109 char *tmp; 1110 if (argc > 2) { 1111 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n"); 1112 return 1; 1113 } 1114 if (argc == 2) { 1115 snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]); 1116 } else { 1117 snprintf(buf, sizeof buf, "host:disconnect:"); 1118 } 1119 tmp = adb_query(buf); 1120 if(tmp) { 1121 printf("%s\n", tmp); 1122 return 0; 1123 } else { 1124 return 1; 1125 } 1126 } 1127 1128 if (!strcmp(argv[0], "emu")) { 1129 return adb_send_emulator_command(argc, argv); 1130 } 1131 1132 if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) { 1133 int r; 1134 int fd; 1135 1136 char h = (argv[0][0] == 'h'); 1137 1138 if (h) { 1139 printf("\x1b[41;33m"); 1140 fflush(stdout); 1141 } 1142 1143 if(argc < 2) { 1144 D("starting interactive shell\n"); 1145 r = interactive_shell(); 1146 if (h) { 1147 printf("\x1b[0m"); 1148 fflush(stdout); 1149 } 1150 return r; 1151 } 1152 1153 snprintf(buf, sizeof buf, "shell:%s", argv[1]); 1154 argc -= 2; 1155 argv += 2; 1156 while(argc-- > 0) { 1157 strcat(buf, " "); 1158 1159 /* quote empty strings and strings with spaces */ 1160 quote = (**argv == 0 || strchr(*argv, ' ')); 1161 if (quote) 1162 strcat(buf, "\""); 1163 strcat(buf, *argv++); 1164 if (quote) 1165 strcat(buf, "\""); 1166 } 1167 1168 for(;;) { 1169 D("interactive shell loop. buff=%s\n", buf); 1170 fd = adb_connect(buf); 1171 if(fd >= 0) { 1172 D("about to read_and_dump(fd=%d)\n", fd); 1173 read_and_dump(fd); 1174 D("read_and_dump() done.\n"); 1175 adb_close(fd); 1176 r = 0; 1177 } else { 1178 fprintf(stderr,"error: %s\n", adb_error()); 1179 r = -1; 1180 } 1181 1182 if(persist) { 1183 fprintf(stderr,"\n- waiting for device -\n"); 1184 adb_sleep_ms(1000); 1185 do_cmd(ttype, serial, "wait-for-device", 0); 1186 } else { 1187 if (h) { 1188 printf("\x1b[0m"); 1189 fflush(stdout); 1190 } 1191 D("interactive shell loop. return r=%d\n", r); 1192 return r; 1193 } 1194 } 1195 } 1196 1197 if(!strcmp(argv[0], "kill-server")) { 1198 int fd; 1199 fd = _adb_connect("host:kill"); 1200 if(fd == -1) { 1201 fprintf(stderr,"* server not running *\n"); 1202 return 1; 1203 } 1204 return 0; 1205 } 1206 1207 if(!strcmp(argv[0], "sideload")) { 1208 if(argc != 2) return usage(); 1209 if(adb_download("sideload", argv[1], 1)) { 1210 return 1; 1211 } else { 1212 return 0; 1213 } 1214 } 1215 1216 if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot") 1217 || !strcmp(argv[0], "reboot-bootloader") 1218 || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb") 1219 || !strcmp(argv[0], "root")) { 1220 char command[100]; 1221 if (!strcmp(argv[0], "reboot-bootloader")) 1222 snprintf(command, sizeof(command), "reboot:bootloader"); 1223 else if (argc > 1) 1224 snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]); 1225 else 1226 snprintf(command, sizeof(command), "%s:", argv[0]); 1227 int fd = adb_connect(command); 1228 if(fd >= 0) { 1229 read_and_dump(fd); 1230 adb_close(fd); 1231 return 0; 1232 } 1233 fprintf(stderr,"error: %s\n", adb_error()); 1234 return 1; 1235 } 1236 1237 if(!strcmp(argv[0], "bugreport")) { 1238 if (argc != 1) return usage(); 1239 do_cmd(ttype, serial, "shell", "bugreport", 0); 1240 return 0; 1241 } 1242 1243 /* adb_command() wrapper commands */ 1244 1245 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) { 1246 char* service = argv[0]; 1247 if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) { 1248 if (ttype == kTransportUsb) { 1249 service = "wait-for-usb"; 1250 } else if (ttype == kTransportLocal) { 1251 service = "wait-for-local"; 1252 } else { 1253 service = "wait-for-any"; 1254 } 1255 } 1256 1257 format_host_command(buf, sizeof buf, service, ttype, serial); 1258 1259 if (adb_command(buf)) { 1260 D("failure: %s *\n",adb_error()); 1261 fprintf(stderr,"error: %s\n", adb_error()); 1262 return 1; 1263 } 1264 1265 /* Allow a command to be run after wait-for-device, 1266 * e.g. 'adb wait-for-device shell'. 1267 */ 1268 if(argc > 1) { 1269 argc--; 1270 argv++; 1271 goto top; 1272 } 1273 return 0; 1274 } 1275 1276 if(!strcmp(argv[0], "forward")) { 1277 char host_prefix[64]; 1278 char remove = 0; 1279 char remove_all = 0; 1280 char list = 0; 1281 char no_rebind = 0; 1282 1283 // Parse options here. 1284 while (argc > 1 && argv[1][0] == '-') { 1285 if (!strcmp(argv[1], "--list")) 1286 list = 1; 1287 else if (!strcmp(argv[1], "--remove")) 1288 remove = 1; 1289 else if (!strcmp(argv[1], "--remove-all")) 1290 remove_all = 1; 1291 else if (!strcmp(argv[1], "--no-rebind")) 1292 no_rebind = 1; 1293 else { 1294 return usage(); 1295 } 1296 argc--; 1297 argv++; 1298 } 1299 1300 // Ensure we can only use one option at a time. 1301 if (list + remove + remove_all + no_rebind > 1) { 1302 return usage(); 1303 } 1304 1305 // Determine the <host-prefix> for this command. 1306 if (serial) { 1307 snprintf(host_prefix, sizeof host_prefix, "host-serial:%s", 1308 serial); 1309 } else if (ttype == kTransportUsb) { 1310 snprintf(host_prefix, sizeof host_prefix, "host-usb"); 1311 } else if (ttype == kTransportLocal) { 1312 snprintf(host_prefix, sizeof host_prefix, "host-local"); 1313 } else { 1314 snprintf(host_prefix, sizeof host_prefix, "host"); 1315 } 1316 1317 // Implement forward --list 1318 if (list) { 1319 if (argc != 1) 1320 return usage(); 1321 snprintf(buf, sizeof buf, "%s:list-forward", host_prefix); 1322 char* forwards = adb_query(buf); 1323 if (forwards == NULL) { 1324 fprintf(stderr, "error: %s\n", adb_error()); 1325 return 1; 1326 } 1327 printf("%s", forwards); 1328 free(forwards); 1329 return 0; 1330 } 1331 1332 // Implement forward --remove-all 1333 else if (remove_all) { 1334 if (argc != 1) 1335 return usage(); 1336 snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix); 1337 } 1338 1339 // Implement forward --remove <local> 1340 else if (remove) { 1341 if (argc != 2) 1342 return usage(); 1343 snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]); 1344 } 1345 // Or implement one of: 1346 // forward <local> <remote> 1347 // forward --no-rebind <local> <remote> 1348 else 1349 { 1350 if (argc != 3) 1351 return usage(); 1352 const char* command = no_rebind ? "forward:norebind:" : "forward"; 1353 snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]); 1354 } 1355 1356 if(adb_command(buf)) { 1357 fprintf(stderr,"error: %s\n", adb_error()); 1358 return 1; 1359 } 1360 return 0; 1361 } 1362 1363 /* do_sync_*() commands */ 1364 1365 if(!strcmp(argv[0], "ls")) { 1366 if(argc != 2) return usage(); 1367 return do_sync_ls(argv[1]); 1368 } 1369 1370 if(!strcmp(argv[0], "push")) { 1371 if(argc != 3) return usage(); 1372 return do_sync_push(argv[1], argv[2], 0 /* no verify APK */); 1373 } 1374 1375 if(!strcmp(argv[0], "pull")) { 1376 if (argc == 2) { 1377 return do_sync_pull(argv[1], "."); 1378 } else if (argc == 3) { 1379 return do_sync_pull(argv[1], argv[2]); 1380 } else { 1381 return usage(); 1382 } 1383 } 1384 1385 if(!strcmp(argv[0], "install")) { 1386 if (argc < 2) return usage(); 1387 return install_app(ttype, serial, argc, argv); 1388 } 1389 1390 if(!strcmp(argv[0], "uninstall")) { 1391 if (argc < 2) return usage(); 1392 return uninstall_app(ttype, serial, argc, argv); 1393 } 1394 1395 if(!strcmp(argv[0], "sync")) { 1396 char *srcarg, *android_srcpath, *data_srcpath; 1397 int listonly = 0; 1398 1399 int ret; 1400 if(argc < 2) { 1401 /* No local path was specified. */ 1402 srcarg = NULL; 1403 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) { 1404 listonly = 1; 1405 if (argc == 3) { 1406 srcarg = argv[2]; 1407 } else { 1408 srcarg = NULL; 1409 } 1410 } else if(argc == 2) { 1411 /* A local path or "android"/"data" arg was specified. */ 1412 srcarg = argv[1]; 1413 } else { 1414 return usage(); 1415 } 1416 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath); 1417 if(ret != 0) return usage(); 1418 1419 if(android_srcpath != NULL) 1420 ret = do_sync_sync(android_srcpath, "/system", listonly); 1421 if(ret == 0 && data_srcpath != NULL) 1422 ret = do_sync_sync(data_srcpath, "/data", listonly); 1423 1424 free(android_srcpath); 1425 free(data_srcpath); 1426 return ret; 1427 } 1428 1429 /* passthrough commands */ 1430 1431 if(!strcmp(argv[0],"get-state") || 1432 !strcmp(argv[0],"get-serialno") || 1433 !strcmp(argv[0],"get-devpath")) 1434 { 1435 char *tmp; 1436 1437 format_host_command(buf, sizeof buf, argv[0], ttype, serial); 1438 tmp = adb_query(buf); 1439 if(tmp) { 1440 printf("%s\n", tmp); 1441 return 0; 1442 } else { 1443 return 1; 1444 } 1445 } 1446 1447 /* other commands */ 1448 1449 if(!strcmp(argv[0],"status-window")) { 1450 status_window(ttype, serial); 1451 return 0; 1452 } 1453 1454 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) { 1455 return logcat(ttype, serial, argc, argv); 1456 } 1457 1458 if(!strcmp(argv[0],"ppp")) { 1459 return ppp(argc, argv); 1460 } 1461 1462 if (!strcmp(argv[0], "start-server")) { 1463 return adb_connect("host:start-server"); 1464 } 1465 1466 if (!strcmp(argv[0], "backup")) { 1467 return backup(argc, argv); 1468 } 1469 1470 if (!strcmp(argv[0], "restore")) { 1471 return restore(argc, argv); 1472 } 1473 1474 if (!strcmp(argv[0], "jdwp")) { 1475 int fd = adb_connect("jdwp"); 1476 if (fd >= 0) { 1477 read_and_dump(fd); 1478 adb_close(fd); 1479 return 0; 1480 } else { 1481 fprintf(stderr, "error: %s\n", adb_error()); 1482 return -1; 1483 } 1484 } 1485 1486 /* "adb /?" is a common idiom under Windows */ 1487 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) { 1488 help(); 1489 return 0; 1490 } 1491 1492 if(!strcmp(argv[0], "version")) { 1493 version(stdout); 1494 return 0; 1495 } 1496 1497 usage(); 1498 return 1; 1499 } 1500 1501 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...) 1502 { 1503 char *argv[16]; 1504 int argc; 1505 va_list ap; 1506 1507 va_start(ap, cmd); 1508 argc = 0; 1509 1510 if (serial) { 1511 argv[argc++] = "-s"; 1512 argv[argc++] = serial; 1513 } else if (ttype == kTransportUsb) { 1514 argv[argc++] = "-d"; 1515 } else if (ttype == kTransportLocal) { 1516 argv[argc++] = "-e"; 1517 } 1518 1519 argv[argc++] = cmd; 1520 while((argv[argc] = va_arg(ap, char*)) != 0) argc++; 1521 va_end(ap); 1522 1523 #if 0 1524 int n; 1525 fprintf(stderr,"argc = %d\n",argc); 1526 for(n = 0; n < argc; n++) { 1527 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]); 1528 } 1529 #endif 1530 1531 return adb_commandline(argc, argv); 1532 } 1533 1534 int find_sync_dirs(const char *srcarg, 1535 char **android_srcdir_out, char **data_srcdir_out) 1536 { 1537 char *android_srcdir, *data_srcdir; 1538 1539 if(srcarg == NULL) { 1540 android_srcdir = product_file("system"); 1541 data_srcdir = product_file("data"); 1542 } else { 1543 /* srcarg may be "data", "system" or NULL. 1544 * if srcarg is NULL, then both data and system are synced 1545 */ 1546 if(strcmp(srcarg, "system") == 0) { 1547 android_srcdir = product_file("system"); 1548 data_srcdir = NULL; 1549 } else if(strcmp(srcarg, "data") == 0) { 1550 android_srcdir = NULL; 1551 data_srcdir = product_file("data"); 1552 } else { 1553 /* It's not "system" or "data". 1554 */ 1555 return 1; 1556 } 1557 } 1558 1559 if(android_srcdir_out != NULL) 1560 *android_srcdir_out = android_srcdir; 1561 else 1562 free(android_srcdir); 1563 1564 if(data_srcdir_out != NULL) 1565 *data_srcdir_out = data_srcdir; 1566 else 1567 free(data_srcdir); 1568 1569 return 0; 1570 } 1571 1572 static int pm_command(transport_type transport, char* serial, 1573 int argc, char** argv) 1574 { 1575 char buf[4096]; 1576 1577 snprintf(buf, sizeof(buf), "shell:pm"); 1578 1579 while(argc-- > 0) { 1580 char *quoted; 1581 1582 quoted = dupAndQuote(*argv++); 1583 1584 strncat(buf, " ", sizeof(buf)-1); 1585 strncat(buf, quoted, sizeof(buf)-1); 1586 free(quoted); 1587 } 1588 1589 send_shellcommand(transport, serial, buf); 1590 return 0; 1591 } 1592 1593 int uninstall_app(transport_type transport, char* serial, int argc, char** argv) 1594 { 1595 /* if the user choose the -k option, we refuse to do it until devices are 1596 out with the option to uninstall the remaining data somehow (adb/ui) */ 1597 if (argc == 3 && strcmp(argv[1], "-k") == 0) 1598 { 1599 printf( 1600 "The -k option uninstalls the application while retaining the data/cache.\n" 1601 "At the moment, there is no way to remove the remaining data.\n" 1602 "You will have to reinstall the application with the same signature, and fully uninstall it.\n" 1603 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]); 1604 return -1; 1605 } 1606 1607 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */ 1608 return pm_command(transport, serial, argc, argv); 1609 } 1610 1611 static int delete_file(transport_type transport, char* serial, char* filename) 1612 { 1613 char buf[4096]; 1614 char* quoted; 1615 1616 snprintf(buf, sizeof(buf), "shell:rm "); 1617 quoted = dupAndQuote(filename); 1618 strncat(buf, quoted, sizeof(buf)-1); 1619 free(quoted); 1620 1621 send_shellcommand(transport, serial, buf); 1622 return 0; 1623 } 1624 1625 static const char* get_basename(const char* filename) 1626 { 1627 const char* basename = adb_dirstop(filename); 1628 if (basename) { 1629 basename++; 1630 return basename; 1631 } else { 1632 return filename; 1633 } 1634 } 1635 1636 static int check_file(const char* filename) 1637 { 1638 struct stat st; 1639 1640 if (filename == NULL) { 1641 return 0; 1642 } 1643 1644 if (stat(filename, &st) != 0) { 1645 fprintf(stderr, "can't find '%s' to install\n", filename); 1646 return 1; 1647 } 1648 1649 if (!S_ISREG(st.st_mode)) { 1650 fprintf(stderr, "can't install '%s' because it's not a file\n", filename); 1651 return 1; 1652 } 1653 1654 return 0; 1655 } 1656 1657 int install_app(transport_type transport, char* serial, int argc, char** argv) 1658 { 1659 static const char *const DATA_DEST = "/data/local/tmp/%s"; 1660 static const char *const SD_DEST = "/sdcard/tmp/%s"; 1661 const char* where = DATA_DEST; 1662 char apk_dest[PATH_MAX]; 1663 char verification_dest[PATH_MAX]; 1664 char* apk_file; 1665 char* verification_file = NULL; 1666 int file_arg = -1; 1667 int err; 1668 int i; 1669 int verify_apk = 1; 1670 1671 for (i = 1; i < argc; i++) { 1672 if (*argv[i] != '-') { 1673 file_arg = i; 1674 break; 1675 } else if (!strcmp(argv[i], "-i")) { 1676 // Skip the installer package name. 1677 i++; 1678 } else if (!strcmp(argv[i], "-s")) { 1679 where = SD_DEST; 1680 } else if (!strcmp(argv[i], "--algo")) { 1681 verify_apk = 0; 1682 i++; 1683 } else if (!strcmp(argv[i], "--iv")) { 1684 verify_apk = 0; 1685 i++; 1686 } else if (!strcmp(argv[i], "--key")) { 1687 verify_apk = 0; 1688 i++; 1689 } 1690 } 1691 1692 if (file_arg < 0) { 1693 fprintf(stderr, "can't find filename in arguments\n"); 1694 return 1; 1695 } else if (file_arg + 2 < argc) { 1696 fprintf(stderr, "too many files specified; only takes APK file and verifier file\n"); 1697 return 1; 1698 } 1699 1700 apk_file = argv[file_arg]; 1701 1702 if (file_arg != argc - 1) { 1703 verification_file = argv[file_arg + 1]; 1704 } 1705 1706 if (check_file(apk_file) || check_file(verification_file)) { 1707 return 1; 1708 } 1709 1710 snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file)); 1711 if (verification_file != NULL) { 1712 snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file)); 1713 1714 if (!strcmp(apk_dest, verification_dest)) { 1715 fprintf(stderr, "APK and verification file can't have the same name\n"); 1716 return 1; 1717 } 1718 } 1719 1720 err = do_sync_push(apk_file, apk_dest, verify_apk); 1721 if (err) { 1722 goto cleanup_apk; 1723 } else { 1724 argv[file_arg] = apk_dest; /* destination name, not source location */ 1725 } 1726 1727 if (verification_file != NULL) { 1728 err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */); 1729 if (err) { 1730 goto cleanup_apk; 1731 } else { 1732 argv[file_arg + 1] = verification_dest; /* destination name, not source location */ 1733 } 1734 } 1735 1736 pm_command(transport, serial, argc, argv); 1737 1738 cleanup_apk: 1739 if (verification_file != NULL) { 1740 delete_file(transport, serial, verification_dest); 1741 } 1742 1743 delete_file(transport, serial, apk_dest); 1744 1745 return err; 1746 } 1747