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