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