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