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