Home | History | Annotate | Download | only in adb
      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] <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 
    190 int usage()
    191 {
    192     help();
    193     return 1;
    194 }
    195 
    196 #ifdef HAVE_TERMIO_H
    197 static struct termios tio_save;
    198 
    199 static 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 
    216 static void stdin_raw_restore(int fd)
    217 {
    218     tcsetattr(fd, TCSANOW, &tio_save);
    219     tcflush(fd, TCIFLUSH);
    220 }
    221 #endif
    222 
    223 static 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 
    245 static 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 
    273 static 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 
    326 int 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 
    355 static 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 
    370 static void status_window(transport_type ttype, const char* serial)
    371 {
    372     char command[4096];
    373     char *state = 0;
    374     char *laststate = 0;
    375 
    376         /* silence stderr */
    377 #ifdef _WIN32
    378     /* XXX: TODO */
    379 #else
    380     int  fd;
    381     fd = unix_open("/dev/null", O_WRONLY);
    382     dup2(fd, 2);
    383     adb_close(fd);
    384 #endif
    385 
    386     format_host_command(command, sizeof command, "get-state", ttype, serial);
    387 
    388     for(;;) {
    389         adb_sleep_ms(250);
    390 
    391         if(state) {
    392             free(state);
    393             state = 0;
    394         }
    395 
    396         state = adb_query(command);
    397 
    398         if(state) {
    399             if(laststate && !strcmp(state,laststate)){
    400                 continue;
    401             } else {
    402                 if(laststate) free(laststate);
    403                 laststate = strdup(state);
    404             }
    405         }
    406 
    407         printf("%c[2J%c[2H", 27, 27);
    408         printf("Android Debug Bridge\n");
    409         printf("State: %s\n", state ? state : "offline");
    410         fflush(stdout);
    411     }
    412 }
    413 
    414 /** duplicate string and quote all \ " ( ) chars + space character. */
    415 static char *
    416 dupAndQuote(const char *s)
    417 {
    418     const char *ts;
    419     size_t alloc_len;
    420     char *ret;
    421     char *dest;
    422 
    423     ts = s;
    424 
    425     alloc_len = 0;
    426 
    427     for( ;*ts != '\0'; ts++) {
    428         alloc_len++;
    429         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
    430             alloc_len++;
    431         }
    432     }
    433 
    434     ret = (char *)malloc(alloc_len + 1);
    435 
    436     ts = s;
    437     dest = ret;
    438 
    439     for ( ;*ts != '\0'; ts++) {
    440         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
    441             *dest++ = '\\';
    442         }
    443 
    444         *dest++ = *ts;
    445     }
    446 
    447     *dest++ = '\0';
    448 
    449     return ret;
    450 }
    451 
    452 /**
    453  * Run ppp in "notty" mode against a resource listed as the first parameter
    454  * eg:
    455  *
    456  * ppp dev:/dev/omap_csmi_tty0 <ppp options>
    457  *
    458  */
    459 int ppp(int argc, char **argv)
    460 {
    461 #ifdef HAVE_WIN32_PROC
    462     fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
    463     return -1;
    464 #else
    465     char *adb_service_name;
    466     pid_t pid;
    467     int fd;
    468 
    469     if (argc < 2) {
    470         fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
    471                 argv[0]);
    472 
    473         return 1;
    474     }
    475 
    476     adb_service_name = argv[1];
    477 
    478     fd = adb_connect(adb_service_name);
    479 
    480     if(fd < 0) {
    481         fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
    482                 adb_service_name, adb_error());
    483         return 1;
    484     }
    485 
    486     pid = fork();
    487 
    488     if (pid < 0) {
    489         perror("from fork()");
    490         return 1;
    491     } else if (pid == 0) {
    492         int err;
    493         int i;
    494         const char **ppp_args;
    495 
    496         // copy args
    497         ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
    498         ppp_args[0] = "pppd";
    499         for (i = 2 ; i < argc ; i++) {
    500             //argv[2] and beyond become ppp_args[1] and beyond
    501             ppp_args[i - 1] = argv[i];
    502         }
    503         ppp_args[i-1] = NULL;
    504 
    505         // child side
    506 
    507         dup2(fd, STDIN_FILENO);
    508         dup2(fd, STDOUT_FILENO);
    509         adb_close(STDERR_FILENO);
    510         adb_close(fd);
    511 
    512         err = execvp("pppd", (char * const *)ppp_args);
    513 
    514         if (err < 0) {
    515             perror("execing pppd");
    516         }
    517         exit(-1);
    518     } else {
    519         // parent side
    520 
    521         adb_close(fd);
    522         return 0;
    523     }
    524 #endif /* !HAVE_WIN32_PROC */
    525 }
    526 
    527 static int send_shellcommand(transport_type transport, char* serial, char* buf)
    528 {
    529     int fd, ret;
    530 
    531     for(;;) {
    532         fd = adb_connect(buf);
    533         if(fd >= 0)
    534             break;
    535         fprintf(stderr,"- waiting for device -\n");
    536         adb_sleep_ms(1000);
    537         do_cmd(transport, serial, "wait-for-device", 0);
    538     }
    539 
    540     read_and_dump(fd);
    541     ret = adb_close(fd);
    542     if (ret)
    543         perror("close");
    544 
    545     return ret;
    546 }
    547 
    548 static int logcat(transport_type transport, char* serial, int argc, char **argv)
    549 {
    550     char buf[4096];
    551 
    552     char *log_tags;
    553     char *quoted_log_tags;
    554 
    555     log_tags = getenv("ANDROID_LOG_TAGS");
    556     quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
    557 
    558     snprintf(buf, sizeof(buf),
    559         "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
    560         quoted_log_tags);
    561 
    562     free(quoted_log_tags);
    563 
    564     argc -= 1;
    565     argv += 1;
    566     while(argc-- > 0) {
    567         char *quoted;
    568 
    569         quoted = dupAndQuote (*argv++);
    570 
    571         strncat(buf, " ", sizeof(buf)-1);
    572         strncat(buf, quoted, sizeof(buf)-1);
    573         free(quoted);
    574     }
    575 
    576     send_shellcommand(transport, serial, buf);
    577     return 0;
    578 }
    579 
    580 static int backup(int argc, char** argv) {
    581     char buf[4096];
    582     const char* filename = "./backup.ab";
    583     int fd, outFd;
    584     int i, j;
    585 
    586     /* find, extract, and use any -f argument */
    587     for (i = 1; i < argc; i++) {
    588         if (!strcmp("-f", argv[i])) {
    589             if (i == argc-1) {
    590                 fprintf(stderr, "adb: -f passed with no filename\n");
    591                 return usage();
    592             }
    593             filename = argv[i+1];
    594             for (j = i+2; j <= argc; ) {
    595                 argv[i++] = argv[j++];
    596             }
    597             argc -= 2;
    598             argv[argc] = NULL;
    599         }
    600     }
    601 
    602     /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
    603     if (argc < 2) return usage();
    604 
    605     outFd = adb_open_mode(filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
    606     if (outFd < 0) {
    607         fprintf(stderr, "adb: unable to open file %s\n", filename);
    608         return -1;
    609     }
    610 
    611     snprintf(buf, sizeof(buf), "backup");
    612     for (argc--, argv++; argc; argc--, argv++) {
    613         strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
    614         strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
    615     }
    616 
    617     D("backup. filename=%s buf=%s\n", filename, buf);
    618     fd = adb_connect(buf);
    619     if (fd < 0) {
    620         fprintf(stderr, "adb: unable to connect for backup\n");
    621         adb_close(outFd);
    622         return -1;
    623     }
    624 
    625     copy_to_file(fd, outFd);
    626 
    627     adb_close(fd);
    628     adb_close(outFd);
    629     return 0;
    630 }
    631 
    632 static int restore(int argc, char** argv) {
    633     const char* filename;
    634     int fd, tarFd;
    635 
    636     if (argc != 2) return usage();
    637 
    638     filename = argv[1];
    639     tarFd = adb_open(filename, O_RDONLY);
    640     if (tarFd < 0) {
    641         fprintf(stderr, "adb: unable to open file %s\n", filename);
    642         return -1;
    643     }
    644 
    645     fd = adb_connect("restore:");
    646     if (fd < 0) {
    647         fprintf(stderr, "adb: unable to connect for backup\n");
    648         adb_close(tarFd);
    649         return -1;
    650     }
    651 
    652     copy_to_file(tarFd, fd);
    653 
    654     adb_close(fd);
    655     adb_close(tarFd);
    656     return 0;
    657 }
    658 
    659 #define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
    660 static int top_works(const char *top)
    661 {
    662     if (top != NULL && adb_is_absolute_host_path(top)) {
    663         char path_buf[PATH_MAX];
    664         snprintf(path_buf, sizeof(path_buf),
    665                 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
    666         return access(path_buf, F_OK) == 0;
    667     }
    668     return 0;
    669 }
    670 
    671 static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
    672 {
    673     strcpy(path_buf, indir);
    674     while (1) {
    675         if (top_works(path_buf)) {
    676             return path_buf;
    677         }
    678         char *s = adb_dirstop(path_buf);
    679         if (s != NULL) {
    680             *s = '\0';
    681         } else {
    682             path_buf[0] = '\0';
    683             return NULL;
    684         }
    685     }
    686 }
    687 
    688 static char *find_top(char path_buf[PATH_MAX])
    689 {
    690     char *top = getenv("ANDROID_BUILD_TOP");
    691     if (top != NULL && top[0] != '\0') {
    692         if (!top_works(top)) {
    693             fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
    694             return NULL;
    695         }
    696     } else {
    697         top = getenv("TOP");
    698         if (top != NULL && top[0] != '\0') {
    699             if (!top_works(top)) {
    700                 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
    701                 return NULL;
    702             }
    703         } else {
    704             top = NULL;
    705         }
    706     }
    707 
    708     if (top != NULL) {
    709         /* The environment pointed to a top directory that works.
    710          */
    711         strcpy(path_buf, top);
    712         return path_buf;
    713     }
    714 
    715     /* The environment didn't help.  Walk up the tree from the CWD
    716      * to see if we can find the top.
    717      */
    718     char dir[PATH_MAX];
    719     top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
    720     if (top == NULL) {
    721         /* If the CWD isn't under a good-looking top, see if the
    722          * executable is.
    723          */
    724         get_my_path(dir, PATH_MAX);
    725         top = find_top_from(dir, path_buf);
    726     }
    727     return top;
    728 }
    729 
    730 /* <hint> may be:
    731  * - A simple product name
    732  *   e.g., "sooner"
    733 TODO: debug?  sooner-debug, sooner:debug?
    734  * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
    735  *   e.g., "out/target/product/sooner"
    736  * - An absolute path to the PRODUCT_OUT dir
    737  *   e.g., "/src/device/out/target/product/sooner"
    738  *
    739  * Given <hint>, try to construct an absolute path to the
    740  * ANDROID_PRODUCT_OUT dir.
    741  */
    742 static const char *find_product_out_path(const char *hint)
    743 {
    744     static char path_buf[PATH_MAX];
    745 
    746     if (hint == NULL || hint[0] == '\0') {
    747         return NULL;
    748     }
    749 
    750     /* If it's already absolute, don't bother doing any work.
    751      */
    752     if (adb_is_absolute_host_path(hint)) {
    753         strcpy(path_buf, hint);
    754         return path_buf;
    755     }
    756 
    757     /* If there are any slashes in it, assume it's a relative path;
    758      * make it absolute.
    759      */
    760     if (adb_dirstart(hint) != NULL) {
    761         if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
    762             fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
    763             return NULL;
    764         }
    765         if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
    766             fprintf(stderr, "adb: Couldn't assemble path\n");
    767             return NULL;
    768         }
    769         strcat(path_buf, OS_PATH_SEPARATOR_STR);
    770         strcat(path_buf, hint);
    771         return path_buf;
    772     }
    773 
    774     /* It's a string without any slashes.  Try to do something with it.
    775      *
    776      * Try to find the root of the build tree, and build a PRODUCT_OUT
    777      * path from there.
    778      */
    779     char top_buf[PATH_MAX];
    780     const char *top = find_top(top_buf);
    781     if (top == NULL) {
    782         fprintf(stderr, "adb: Couldn't find top of build tree\n");
    783         return NULL;
    784     }
    785 //TODO: if we have a way to indicate debug, look in out/debug/target/...
    786     snprintf(path_buf, sizeof(path_buf),
    787             "%s" OS_PATH_SEPARATOR_STR
    788             "out" OS_PATH_SEPARATOR_STR
    789             "target" OS_PATH_SEPARATOR_STR
    790             "product" OS_PATH_SEPARATOR_STR
    791             "%s", top_buf, hint);
    792     if (access(path_buf, F_OK) < 0) {
    793         fprintf(stderr, "adb: Couldn't find a product dir "
    794                 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
    795         return NULL;
    796     }
    797     return path_buf;
    798 }
    799 
    800 int adb_commandline(int argc, char **argv)
    801 {
    802     char buf[4096];
    803     int no_daemon = 0;
    804     int is_daemon = 0;
    805     int is_server = 0;
    806     int persist = 0;
    807     int r;
    808     int quote;
    809     transport_type ttype = kTransportAny;
    810     char* serial = NULL;
    811     char* server_port_str = NULL;
    812 
    813         /* If defined, this should be an absolute path to
    814          * the directory containing all of the various system images
    815          * for a particular product.  If not defined, and the adb
    816          * command requires this information, then the user must
    817          * specify the path using "-p".
    818          */
    819     gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
    820     if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
    821         gProductOutPath = NULL;
    822     }
    823     // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
    824 
    825     serial = getenv("ANDROID_SERIAL");
    826 
    827     /* Validate and assign the server port */
    828     server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
    829     int server_port = DEFAULT_ADB_PORT;
    830     if (server_port_str && strlen(server_port_str) > 0) {
    831         server_port = (int) strtol(server_port_str, NULL, 0);
    832         if (server_port <= 0) {
    833             fprintf(stderr,
    834                     "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
    835                     server_port_str);
    836             return usage();
    837         }
    838     }
    839 
    840     /* modifiers and flags */
    841     while(argc > 0) {
    842         if(!strcmp(argv[0],"server")) {
    843             is_server = 1;
    844         } else if(!strcmp(argv[0],"nodaemon")) {
    845             no_daemon = 1;
    846         } else if (!strcmp(argv[0], "fork-server")) {
    847             /* this is a special flag used only when the ADB client launches the ADB Server */
    848             is_daemon = 1;
    849         } else if(!strcmp(argv[0],"persist")) {
    850             persist = 1;
    851         } else if(!strncmp(argv[0], "-p", 2)) {
    852             const char *product = NULL;
    853             if (argv[0][2] == '\0') {
    854                 if (argc < 2) return usage();
    855                 product = argv[1];
    856                 argc--;
    857                 argv++;
    858             } else {
    859                 product = argv[1] + 2;
    860             }
    861             gProductOutPath = find_product_out_path(product);
    862             if (gProductOutPath == NULL) {
    863                 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
    864                         product);
    865                 return usage();
    866             }
    867         } else if (argv[0][0]=='-' && argv[0][1]=='s') {
    868             if (isdigit(argv[0][2])) {
    869                 serial = argv[0] + 2;
    870             } else {
    871                 if(argc < 2 || argv[0][2] != '\0') return usage();
    872                 serial = argv[1];
    873                 argc--;
    874                 argv++;
    875             }
    876         } else if (!strcmp(argv[0],"-d")) {
    877             ttype = kTransportUsb;
    878         } else if (!strcmp(argv[0],"-e")) {
    879             ttype = kTransportLocal;
    880         } else {
    881                 /* out of recognized modifiers and flags */
    882             break;
    883         }
    884         argc--;
    885         argv++;
    886     }
    887 
    888     adb_set_transport(ttype, serial);
    889     adb_set_tcp_specifics(server_port);
    890 
    891     if (is_server) {
    892         if (no_daemon || is_daemon) {
    893             r = adb_main(is_daemon, server_port);
    894         } else {
    895             r = launch_server(server_port);
    896         }
    897         if(r) {
    898             fprintf(stderr,"* could not start server *\n");
    899         }
    900         return r;
    901     }
    902 
    903 top:
    904     if(argc == 0) {
    905         return usage();
    906     }
    907 
    908     /* adb_connect() commands */
    909 
    910     if(!strcmp(argv[0], "devices")) {
    911         char *tmp;
    912         snprintf(buf, sizeof buf, "host:%s", argv[0]);
    913         tmp = adb_query(buf);
    914         if(tmp) {
    915             printf("List of devices attached \n");
    916             printf("%s\n", tmp);
    917             return 0;
    918         } else {
    919             return 1;
    920         }
    921     }
    922 
    923     if(!strcmp(argv[0], "connect")) {
    924         char *tmp;
    925         if (argc != 2) {
    926             fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
    927             return 1;
    928         }
    929         snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
    930         tmp = adb_query(buf);
    931         if(tmp) {
    932             printf("%s\n", tmp);
    933             return 0;
    934         } else {
    935             return 1;
    936         }
    937     }
    938 
    939     if(!strcmp(argv[0], "disconnect")) {
    940         char *tmp;
    941         if (argc > 2) {
    942             fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
    943             return 1;
    944         }
    945         if (argc == 2) {
    946             snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
    947         } else {
    948             snprintf(buf, sizeof buf, "host:disconnect:");
    949         }
    950         tmp = adb_query(buf);
    951         if(tmp) {
    952             printf("%s\n", tmp);
    953             return 0;
    954         } else {
    955             return 1;
    956         }
    957     }
    958 
    959     if (!strcmp(argv[0], "emu")) {
    960         return adb_send_emulator_command(argc, argv);
    961     }
    962 
    963     if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
    964         int r;
    965         int fd;
    966 
    967         char h = (argv[0][0] == 'h');
    968 
    969         if (h) {
    970             printf("\x1b[41;33m");
    971             fflush(stdout);
    972         }
    973 
    974         if(argc < 2) {
    975             D("starting interactive shell\n");
    976             r = interactive_shell();
    977             if (h) {
    978                 printf("\x1b[0m");
    979                 fflush(stdout);
    980             }
    981             return r;
    982         }
    983 
    984         snprintf(buf, sizeof buf, "shell:%s", argv[1]);
    985         argc -= 2;
    986         argv += 2;
    987         while(argc-- > 0) {
    988             strcat(buf, " ");
    989 
    990             /* quote empty strings and strings with spaces */
    991             quote = (**argv == 0 || strchr(*argv, ' '));
    992             if (quote)
    993                 strcat(buf, "\"");
    994             strcat(buf, *argv++);
    995             if (quote)
    996                 strcat(buf, "\"");
    997         }
    998 
    999         for(;;) {
   1000             D("interactive shell loop. buff=%s\n", buf);
   1001             fd = adb_connect(buf);
   1002             if(fd >= 0) {
   1003                 D("about to read_and_dump(fd=%d)\n", fd);
   1004                 read_and_dump(fd);
   1005                 D("read_and_dump() done.\n");
   1006                 adb_close(fd);
   1007                 r = 0;
   1008             } else {
   1009                 fprintf(stderr,"error: %s\n", adb_error());
   1010                 r = -1;
   1011             }
   1012 
   1013             if(persist) {
   1014                 fprintf(stderr,"\n- waiting for device -\n");
   1015                 adb_sleep_ms(1000);
   1016                 do_cmd(ttype, serial, "wait-for-device", 0);
   1017             } else {
   1018                 if (h) {
   1019                     printf("\x1b[0m");
   1020                     fflush(stdout);
   1021                 }
   1022                 D("interactive shell loop. return r=%d\n", r);
   1023                 return r;
   1024             }
   1025         }
   1026     }
   1027 
   1028     if(!strcmp(argv[0], "kill-server")) {
   1029         int fd;
   1030         fd = _adb_connect("host:kill");
   1031         if(fd == -1) {
   1032             fprintf(stderr,"* server not running *\n");
   1033             return 1;
   1034         }
   1035         return 0;
   1036     }
   1037 
   1038     if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
   1039             || !strcmp(argv[0], "reboot-bootloader")
   1040             || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
   1041             || !strcmp(argv[0], "root")) {
   1042         char command[100];
   1043         if (!strcmp(argv[0], "reboot-bootloader"))
   1044             snprintf(command, sizeof(command), "reboot:bootloader");
   1045         else if (argc > 1)
   1046             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
   1047         else
   1048             snprintf(command, sizeof(command), "%s:", argv[0]);
   1049         int fd = adb_connect(command);
   1050         if(fd >= 0) {
   1051             read_and_dump(fd);
   1052             adb_close(fd);
   1053             return 0;
   1054         }
   1055         fprintf(stderr,"error: %s\n", adb_error());
   1056         return 1;
   1057     }
   1058 
   1059     if(!strcmp(argv[0], "bugreport")) {
   1060         if (argc != 1) return usage();
   1061         do_cmd(ttype, serial, "shell", "bugreport", 0);
   1062         return 0;
   1063     }
   1064 
   1065     /* adb_command() wrapper commands */
   1066 
   1067     if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
   1068         char* service = argv[0];
   1069         if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
   1070             if (ttype == kTransportUsb) {
   1071                 service = "wait-for-usb";
   1072             } else if (ttype == kTransportLocal) {
   1073                 service = "wait-for-local";
   1074             } else {
   1075                 service = "wait-for-any";
   1076             }
   1077         }
   1078 
   1079         format_host_command(buf, sizeof buf, service, ttype, serial);
   1080 
   1081         if (adb_command(buf)) {
   1082             D("failure: %s *\n",adb_error());
   1083             fprintf(stderr,"error: %s\n", adb_error());
   1084             return 1;
   1085         }
   1086 
   1087         /* Allow a command to be run after wait-for-device,
   1088             * e.g. 'adb wait-for-device shell'.
   1089             */
   1090         if(argc > 1) {
   1091             argc--;
   1092             argv++;
   1093             goto top;
   1094         }
   1095         return 0;
   1096     }
   1097 
   1098     if(!strcmp(argv[0], "forward")) {
   1099         if(argc != 3) return usage();
   1100         if (serial) {
   1101             snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
   1102         } else if (ttype == kTransportUsb) {
   1103             snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
   1104         } else if (ttype == kTransportLocal) {
   1105             snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
   1106         } else {
   1107             snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
   1108         }
   1109         if(adb_command(buf)) {
   1110             fprintf(stderr,"error: %s\n", adb_error());
   1111             return 1;
   1112         }
   1113         return 0;
   1114     }
   1115 
   1116     /* do_sync_*() commands */
   1117 
   1118     if(!strcmp(argv[0], "ls")) {
   1119         if(argc != 2) return usage();
   1120         return do_sync_ls(argv[1]);
   1121     }
   1122 
   1123     if(!strcmp(argv[0], "push")) {
   1124         if(argc != 3) return usage();
   1125         return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
   1126     }
   1127 
   1128     if(!strcmp(argv[0], "pull")) {
   1129         if (argc == 2) {
   1130             return do_sync_pull(argv[1], ".");
   1131         } else if (argc == 3) {
   1132             return do_sync_pull(argv[1], argv[2]);
   1133         } else {
   1134             return usage();
   1135         }
   1136     }
   1137 
   1138     if(!strcmp(argv[0], "install")) {
   1139         if (argc < 2) return usage();
   1140         return install_app(ttype, serial, argc, argv);
   1141     }
   1142 
   1143     if(!strcmp(argv[0], "uninstall")) {
   1144         if (argc < 2) return usage();
   1145         return uninstall_app(ttype, serial, argc, argv);
   1146     }
   1147 
   1148     if(!strcmp(argv[0], "sync")) {
   1149         char *srcarg, *android_srcpath, *data_srcpath;
   1150         int listonly = 0;
   1151 
   1152         int ret;
   1153         if(argc < 2) {
   1154             /* No local path was specified. */
   1155             srcarg = NULL;
   1156         } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
   1157             listonly = 1;
   1158             if (argc == 3) {
   1159                 srcarg = argv[2];
   1160             } else {
   1161                 srcarg = NULL;
   1162             }
   1163         } else if(argc == 2) {
   1164             /* A local path or "android"/"data" arg was specified. */
   1165             srcarg = argv[1];
   1166         } else {
   1167             return usage();
   1168         }
   1169         ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
   1170         if(ret != 0) return usage();
   1171 
   1172         if(android_srcpath != NULL)
   1173             ret = do_sync_sync(android_srcpath, "/system", listonly);
   1174         if(ret == 0 && data_srcpath != NULL)
   1175             ret = do_sync_sync(data_srcpath, "/data", listonly);
   1176 
   1177         free(android_srcpath);
   1178         free(data_srcpath);
   1179         return ret;
   1180     }
   1181 
   1182     /* passthrough commands */
   1183 
   1184     if(!strcmp(argv[0],"get-state") ||
   1185         !strcmp(argv[0],"get-serialno"))
   1186     {
   1187         char *tmp;
   1188 
   1189         format_host_command(buf, sizeof buf, argv[0], ttype, serial);
   1190         tmp = adb_query(buf);
   1191         if(tmp) {
   1192             printf("%s\n", tmp);
   1193             return 0;
   1194         } else {
   1195             return 1;
   1196         }
   1197     }
   1198 
   1199     /* other commands */
   1200 
   1201     if(!strcmp(argv[0],"status-window")) {
   1202         status_window(ttype, serial);
   1203         return 0;
   1204     }
   1205 
   1206     if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
   1207         return logcat(ttype, serial, argc, argv);
   1208     }
   1209 
   1210     if(!strcmp(argv[0],"ppp")) {
   1211         return ppp(argc, argv);
   1212     }
   1213 
   1214     if (!strcmp(argv[0], "start-server")) {
   1215         return adb_connect("host:start-server");
   1216     }
   1217 
   1218     if (!strcmp(argv[0], "backup")) {
   1219         return backup(argc, argv);
   1220     }
   1221 
   1222     if (!strcmp(argv[0], "restore")) {
   1223         return restore(argc, argv);
   1224     }
   1225 
   1226     if (!strcmp(argv[0], "jdwp")) {
   1227         int  fd = adb_connect("jdwp");
   1228         if (fd >= 0) {
   1229             read_and_dump(fd);
   1230             adb_close(fd);
   1231             return 0;
   1232         } else {
   1233             fprintf(stderr, "error: %s\n", adb_error());
   1234             return -1;
   1235         }
   1236     }
   1237 
   1238     /* "adb /?" is a common idiom under Windows */
   1239     if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
   1240         help();
   1241         return 0;
   1242     }
   1243 
   1244     if(!strcmp(argv[0], "version")) {
   1245         version(stdout);
   1246         return 0;
   1247     }
   1248 
   1249     usage();
   1250     return 1;
   1251 }
   1252 
   1253 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
   1254 {
   1255     char *argv[16];
   1256     int argc;
   1257     va_list ap;
   1258 
   1259     va_start(ap, cmd);
   1260     argc = 0;
   1261 
   1262     if (serial) {
   1263         argv[argc++] = "-s";
   1264         argv[argc++] = serial;
   1265     } else if (ttype == kTransportUsb) {
   1266         argv[argc++] = "-d";
   1267     } else if (ttype == kTransportLocal) {
   1268         argv[argc++] = "-e";
   1269     }
   1270 
   1271     argv[argc++] = cmd;
   1272     while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
   1273     va_end(ap);
   1274 
   1275 #if 0
   1276     int n;
   1277     fprintf(stderr,"argc = %d\n",argc);
   1278     for(n = 0; n < argc; n++) {
   1279         fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
   1280     }
   1281 #endif
   1282 
   1283     return adb_commandline(argc, argv);
   1284 }
   1285 
   1286 int find_sync_dirs(const char *srcarg,
   1287         char **android_srcdir_out, char **data_srcdir_out)
   1288 {
   1289     char *android_srcdir, *data_srcdir;
   1290 
   1291     if(srcarg == NULL) {
   1292         android_srcdir = product_file("system");
   1293         data_srcdir = product_file("data");
   1294     } else {
   1295         /* srcarg may be "data", "system" or NULL.
   1296          * if srcarg is NULL, then both data and system are synced
   1297          */
   1298         if(strcmp(srcarg, "system") == 0) {
   1299             android_srcdir = product_file("system");
   1300             data_srcdir = NULL;
   1301         } else if(strcmp(srcarg, "data") == 0) {
   1302             android_srcdir = NULL;
   1303             data_srcdir = product_file("data");
   1304         } else {
   1305             /* It's not "system" or "data".
   1306              */
   1307             return 1;
   1308         }
   1309     }
   1310 
   1311     if(android_srcdir_out != NULL)
   1312         *android_srcdir_out = android_srcdir;
   1313     else
   1314         free(android_srcdir);
   1315 
   1316     if(data_srcdir_out != NULL)
   1317         *data_srcdir_out = data_srcdir;
   1318     else
   1319         free(data_srcdir);
   1320 
   1321     return 0;
   1322 }
   1323 
   1324 static int pm_command(transport_type transport, char* serial,
   1325                       int argc, char** argv)
   1326 {
   1327     char buf[4096];
   1328 
   1329     snprintf(buf, sizeof(buf), "shell:pm");
   1330 
   1331     while(argc-- > 0) {
   1332         char *quoted;
   1333 
   1334         quoted = dupAndQuote(*argv++);
   1335 
   1336         strncat(buf, " ", sizeof(buf)-1);
   1337         strncat(buf, quoted, sizeof(buf)-1);
   1338         free(quoted);
   1339     }
   1340 
   1341     send_shellcommand(transport, serial, buf);
   1342     return 0;
   1343 }
   1344 
   1345 int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
   1346 {
   1347     /* if the user choose the -k option, we refuse to do it until devices are
   1348        out with the option to uninstall the remaining data somehow (adb/ui) */
   1349     if (argc == 3 && strcmp(argv[1], "-k") == 0)
   1350     {
   1351         printf(
   1352             "The -k option uninstalls the application while retaining the data/cache.\n"
   1353             "At the moment, there is no way to remove the remaining data.\n"
   1354             "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
   1355             "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
   1356         return -1;
   1357     }
   1358 
   1359     /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
   1360     return pm_command(transport, serial, argc, argv);
   1361 }
   1362 
   1363 static int delete_file(transport_type transport, char* serial, char* filename)
   1364 {
   1365     char buf[4096];
   1366     char* quoted;
   1367 
   1368     snprintf(buf, sizeof(buf), "shell:rm ");
   1369     quoted = dupAndQuote(filename);
   1370     strncat(buf, quoted, sizeof(buf)-1);
   1371     free(quoted);
   1372 
   1373     send_shellcommand(transport, serial, buf);
   1374     return 0;
   1375 }
   1376 
   1377 static const char* get_basename(const char* filename)
   1378 {
   1379     const char* basename = adb_dirstop(filename);
   1380     if (basename) {
   1381         basename++;
   1382         return basename;
   1383     } else {
   1384         return filename;
   1385     }
   1386 }
   1387 
   1388 static int check_file(const char* filename)
   1389 {
   1390     struct stat st;
   1391 
   1392     if (filename == NULL) {
   1393         return 0;
   1394     }
   1395 
   1396     if (stat(filename, &st) != 0) {
   1397         fprintf(stderr, "can't find '%s' to install\n", filename);
   1398         return 1;
   1399     }
   1400 
   1401     if (!S_ISREG(st.st_mode)) {
   1402         fprintf(stderr, "can't install '%s' because it's not a file\n", filename);
   1403         return 1;
   1404     }
   1405 
   1406     return 0;
   1407 }
   1408 
   1409 int install_app(transport_type transport, char* serial, int argc, char** argv)
   1410 {
   1411     static const char *const DATA_DEST = "/data/local/tmp/%s";
   1412     static const char *const SD_DEST = "/sdcard/tmp/%s";
   1413     const char* where = DATA_DEST;
   1414     char apk_dest[PATH_MAX];
   1415     char verification_dest[PATH_MAX];
   1416     char* apk_file;
   1417     char* verification_file = NULL;
   1418     int file_arg = -1;
   1419     int err;
   1420     int i;
   1421 
   1422     for (i = 1; i < argc; i++) {
   1423         if (*argv[i] != '-') {
   1424             file_arg = i;
   1425             break;
   1426         } else if (!strcmp(argv[i], "-i")) {
   1427             // Skip the installer package name.
   1428             i++;
   1429         } else if (!strcmp(argv[i], "-s")) {
   1430             where = SD_DEST;
   1431         }
   1432     }
   1433 
   1434     if (file_arg < 0) {
   1435         fprintf(stderr, "can't find filename in arguments\n");
   1436         return 1;
   1437     } else if (file_arg + 2 < argc) {
   1438         fprintf(stderr, "too many files specified; only takes APK file and verifier file\n");
   1439         return 1;
   1440     }
   1441 
   1442     apk_file = argv[file_arg];
   1443 
   1444     if (file_arg != argc - 1) {
   1445         verification_file = argv[file_arg + 1];
   1446     }
   1447 
   1448     if (check_file(apk_file) || check_file(verification_file)) {
   1449         return 1;
   1450     }
   1451 
   1452     snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
   1453     if (verification_file != NULL) {
   1454         snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file));
   1455 
   1456         if (!strcmp(apk_dest, verification_dest)) {
   1457             fprintf(stderr, "APK and verification file can't have the same name\n");
   1458             return 1;
   1459         }
   1460     }
   1461 
   1462     err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */);
   1463     if (err) {
   1464         return err;
   1465     } else {
   1466         argv[file_arg] = apk_dest; /* destination name, not source location */
   1467     }
   1468 
   1469     if (verification_file != NULL) {
   1470         err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
   1471         if (err) {
   1472             goto cleanup_apk;
   1473         } else {
   1474             argv[file_arg + 1] = verification_dest; /* destination name, not source location */
   1475         }
   1476     }
   1477 
   1478     pm_command(transport, serial, argc, argv);
   1479 
   1480     if (verification_file != NULL) {
   1481         delete_file(transport, serial, verification_dest);
   1482     }
   1483 
   1484 cleanup_apk:
   1485     delete_file(transport, serial, apk_dest);
   1486 
   1487     return err;
   1488 }
   1489