Home | History | Annotate | Download | only in fastboot
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #define _LARGEFILE64_SOURCE
     30 
     31 #include <ctype.h>
     32 #include <errno.h>
     33 #include <fcntl.h>
     34 #include <getopt.h>
     35 #include <inttypes.h>
     36 #include <limits.h>
     37 #include <stdint.h>
     38 #include <stdio.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #include <sys/stat.h>
     42 #include <sys/time.h>
     43 #include <sys/types.h>
     44 #include <unistd.h>
     45 
     46 #include <functional>
     47 #include <utility>
     48 #include <vector>
     49 
     50 #include <android-base/parseint.h>
     51 #include <android-base/parsenetaddress.h>
     52 #include <android-base/stringprintf.h>
     53 #include <android-base/strings.h>
     54 #include <sparse/sparse.h>
     55 #include <ziparchive/zip_archive.h>
     56 
     57 #include "bootimg_utils.h"
     58 #include "diagnose_usb.h"
     59 #include "fastboot.h"
     60 #include "fs.h"
     61 #include "tcp.h"
     62 #include "transport.h"
     63 #include "udp.h"
     64 #include "usb.h"
     65 
     66 #ifndef O_BINARY
     67 #define O_BINARY 0
     68 #endif
     69 
     70 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
     71 
     72 char cur_product[FB_RESPONSE_SZ + 1];
     73 
     74 static const char* serial = nullptr;
     75 static const char* product = nullptr;
     76 static const char* cmdline = nullptr;
     77 static unsigned short vendor_id = 0;
     78 static int long_listing = 0;
     79 static int64_t sparse_limit = -1;
     80 static int64_t target_sparse_limit = -1;
     81 
     82 static unsigned page_size = 2048;
     83 static unsigned base_addr      = 0x10000000;
     84 static unsigned kernel_offset  = 0x00008000;
     85 static unsigned ramdisk_offset = 0x01000000;
     86 static unsigned second_offset  = 0x00f00000;
     87 static unsigned tags_offset    = 0x00000100;
     88 
     89 static const std::string convert_fbe_marker_filename("convert_fbe");
     90 
     91 enum fb_buffer_type {
     92     FB_BUFFER,
     93     FB_BUFFER_SPARSE,
     94 };
     95 
     96 struct fastboot_buffer {
     97     enum fb_buffer_type type;
     98     void* data;
     99     int64_t sz;
    100 };
    101 
    102 static struct {
    103     char img_name[17];
    104     char sig_name[17];
    105     char part_name[9];
    106     bool is_optional;
    107     bool is_secondary;
    108 } images[] = {
    109     {"boot.img", "boot.sig", "boot", false, false},
    110     {"boot_other.img", "boot.sig", "boot", true, true},
    111     {"recovery.img", "recovery.sig", "recovery", true, false},
    112     {"system.img", "system.sig", "system", false, false},
    113     {"system_other.img", "system.sig", "system", true, true},
    114     {"vendor.img", "vendor.sig", "vendor", true, false},
    115     {"vendor_other.img", "vendor.sig", "vendor", true, true},
    116 };
    117 
    118 static std::string find_item_given_name(const char* img_name, const char* product) {
    119     char path_c_str[PATH_MAX + 128];
    120 
    121     if(product) {
    122         get_my_path(path_c_str);
    123         std::string path = path_c_str;
    124         path.erase(path.find_last_of('/'));
    125         return android::base::StringPrintf("%s/../../../target/product/%s/%s",
    126                                            path.c_str(), product, img_name);
    127     }
    128 
    129     char *dir = getenv("ANDROID_PRODUCT_OUT");
    130     if (dir == nullptr || dir[0] == '\0') {
    131         die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
    132     }
    133 
    134     return android::base::StringPrintf("%s/%s", dir, img_name);
    135 }
    136 
    137 std::string find_item(const char* item, const char* product) {
    138     const char *fn;
    139 
    140     if(!strcmp(item,"boot")) {
    141         fn = "boot.img";
    142     } else if(!strcmp(item,"recovery")) {
    143         fn = "recovery.img";
    144     } else if(!strcmp(item,"system")) {
    145         fn = "system.img";
    146     } else if(!strcmp(item,"vendor")) {
    147         fn = "vendor.img";
    148     } else if(!strcmp(item,"userdata")) {
    149         fn = "userdata.img";
    150     } else if(!strcmp(item,"cache")) {
    151         fn = "cache.img";
    152     } else if(!strcmp(item,"info")) {
    153         fn = "android-info.txt";
    154     } else {
    155         fprintf(stderr,"unknown partition '%s'\n", item);
    156         return "";
    157     }
    158 
    159     return find_item_given_name(fn, product);
    160 }
    161 
    162 static int64_t get_file_size(int fd) {
    163     struct stat sb;
    164     return fstat(fd, &sb) == -1 ? -1 : sb.st_size;
    165 }
    166 
    167 static void* load_fd(int fd, int64_t* sz) {
    168     int errno_tmp;
    169     char* data = nullptr;
    170 
    171     *sz = get_file_size(fd);
    172     if (*sz < 0) {
    173         goto oops;
    174     }
    175 
    176     data = (char*) malloc(*sz);
    177     if (data == nullptr) goto oops;
    178 
    179     if(read(fd, data, *sz) != *sz) goto oops;
    180     close(fd);
    181 
    182     return data;
    183 
    184 oops:
    185     errno_tmp = errno;
    186     close(fd);
    187     if(data != 0) free(data);
    188     errno = errno_tmp;
    189     return 0;
    190 }
    191 
    192 static void* load_file(const char* fn, int64_t* sz) {
    193     int fd = open(fn, O_RDONLY | O_BINARY);
    194     if (fd == -1) return nullptr;
    195     return load_fd(fd, sz);
    196 }
    197 
    198 static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) {
    199     // Require a matching vendor id if the user specified one with -i.
    200     if (vendor_id != 0 && info->dev_vendor != vendor_id) {
    201         return -1;
    202     }
    203 
    204     if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) {
    205         return -1;
    206     }
    207 
    208     // require matching serial number or device path if requested
    209     // at the command line with the -s option.
    210     if (local_serial && (strcmp(local_serial, info->serial_number) != 0 &&
    211                    strcmp(local_serial, info->device_path) != 0)) return -1;
    212     return 0;
    213 }
    214 
    215 static int match_fastboot(usb_ifc_info* info) {
    216     return match_fastboot_with_serial(info, serial);
    217 }
    218 
    219 static int list_devices_callback(usb_ifc_info* info) {
    220     if (match_fastboot_with_serial(info, nullptr) == 0) {
    221         std::string serial = info->serial_number;
    222         if (!info->writable) {
    223             serial = UsbNoPermissionsShortHelpText();
    224         }
    225         if (!serial[0]) {
    226             serial = "????????????";
    227         }
    228         // output compatible with "adb devices"
    229         if (!long_listing) {
    230             printf("%s\tfastboot", serial.c_str());
    231         } else {
    232             printf("%-22s fastboot", serial.c_str());
    233             if (strlen(info->device_path) > 0) printf(" %s", info->device_path);
    234         }
    235         putchar('\n');
    236     }
    237 
    238     return -1;
    239 }
    240 
    241 // Opens a new Transport connected to a device. If |serial| is non-null it will be used to identify
    242 // a specific device, otherwise the first USB device found will be used.
    243 //
    244 // If |serial| is non-null but invalid, this prints an error message to stderr and returns nullptr.
    245 // Otherwise it blocks until the target is available.
    246 //
    247 // The returned Transport is a singleton, so multiple calls to this function will return the same
    248 // object, and the caller should not attempt to delete the returned Transport.
    249 static Transport* open_device() {
    250     static Transport* transport = nullptr;
    251     bool announce = true;
    252 
    253     if (transport != nullptr) {
    254         return transport;
    255     }
    256 
    257     Socket::Protocol protocol = Socket::Protocol::kTcp;
    258     std::string host;
    259     int port = 0;
    260     if (serial != nullptr) {
    261         const char* net_address = nullptr;
    262 
    263         if (android::base::StartsWith(serial, "tcp:")) {
    264             protocol = Socket::Protocol::kTcp;
    265             port = tcp::kDefaultPort;
    266             net_address = serial + strlen("tcp:");
    267         } else if (android::base::StartsWith(serial, "udp:")) {
    268             protocol = Socket::Protocol::kUdp;
    269             port = udp::kDefaultPort;
    270             net_address = serial + strlen("udp:");
    271         }
    272 
    273         if (net_address != nullptr) {
    274             std::string error;
    275             if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) {
    276                 fprintf(stderr, "error: Invalid network address '%s': %s\n", net_address,
    277                         error.c_str());
    278                 return nullptr;
    279             }
    280         }
    281     }
    282 
    283     while (true) {
    284         if (!host.empty()) {
    285             std::string error;
    286             if (protocol == Socket::Protocol::kTcp) {
    287                 transport = tcp::Connect(host, port, &error).release();
    288             } else if (protocol == Socket::Protocol::kUdp) {
    289                 transport = udp::Connect(host, port, &error).release();
    290             }
    291 
    292             if (transport == nullptr && announce) {
    293                 fprintf(stderr, "error: %s\n", error.c_str());
    294             }
    295         } else {
    296             transport = usb_open(match_fastboot);
    297         }
    298 
    299         if (transport != nullptr) {
    300             return transport;
    301         }
    302 
    303         if (announce) {
    304             announce = false;
    305             fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device");
    306         }
    307         usleep(1000);
    308     }
    309 }
    310 
    311 static void list_devices() {
    312     // We don't actually open a USB device here,
    313     // just getting our callback called so we can
    314     // list all the connected devices.
    315     usb_open(list_devices_callback);
    316 }
    317 
    318 static void usage() {
    319     fprintf(stderr,
    320 /*           1234567890123456789012345678901234567890123456789012345678901234567890123456 */
    321             "usage: fastboot [ <option> ] <command>\n"
    322             "\n"
    323             "commands:\n"
    324             "  update <filename>                        Reflash device from update.zip.\n"
    325             "                                           Sets the flashed slot as active.\n"
    326             "  flashall                                 Flash boot, system, vendor, and --\n"
    327             "                                           if found -- recovery. If the device\n"
    328             "                                           supports slots, the slot that has\n"
    329             "                                           been flashed to is set as active.\n"
    330             "                                           Secondary images may be flashed to\n"
    331             "                                           an inactive slot.\n"
    332             "  flash <partition> [ <filename> ]         Write a file to a flash partition.\n"
    333             "  flashing lock                            Locks the device. Prevents flashing.\n"
    334             "  flashing unlock                          Unlocks the device. Allows flashing\n"
    335             "                                           any partition except\n"
    336             "                                           bootloader-related partitions.\n"
    337             "  flashing lock_critical                   Prevents flashing bootloader-related\n"
    338             "                                           partitions.\n"
    339             "  flashing unlock_critical                 Enables flashing bootloader-related\n"
    340             "                                           partitions.\n"
    341             "  flashing get_unlock_ability              Queries bootloader to see if the\n"
    342             "                                           device is unlocked.\n"
    343             "  flashing get_unlock_bootloader_nonce     Queries the bootloader to get the\n"
    344             "                                           unlock nonce.\n"
    345             "  flashing unlock_bootloader <request>     Issue unlock bootloader using request.\n"
    346             "  flashing lock_bootloader                 Locks the bootloader to prevent\n"
    347             "                                           bootloader version rollback.\n"
    348             "  erase <partition>                        Erase a flash partition.\n"
    349             "  format[:[<fs type>][:[<size>]] <partition>\n"
    350             "                                           Format a flash partition. Can\n"
    351             "                                           override the fs type and/or size\n"
    352             "                                           the bootloader reports.\n"
    353             "  getvar <variable>                        Display a bootloader variable.\n"
    354             "  set_active <slot>                        Sets the active slot. If slots are\n"
    355             "                                           not supported, this does nothing.\n"
    356             "  boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
    357             "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
    358             "                                           Create bootimage and flash it.\n"
    359             "  devices [-l]                             List all connected devices [with\n"
    360             "                                           device paths].\n"
    361             "  continue                                 Continue with autoboot.\n"
    362             "  reboot [bootloader]                      Reboot device [into bootloader].\n"
    363             "  reboot-bootloader                        Reboot device into bootloader.\n"
    364             "  help                                     Show this help message.\n"
    365             "\n"
    366             "options:\n"
    367             "  -w                                       Erase userdata and cache (and format\n"
    368             "                                           if supported by partition type).\n"
    369             "  -u                                       Do not erase partition before\n"
    370             "                                           formatting.\n"
    371             "  -s <specific device>                     Specify a device. For USB, provide either\n"
    372             "                                           a serial number or path to device port.\n"
    373             "                                           For ethernet, provide an address in the\n"
    374             "                                           form <protocol>:<hostname>[:port] where\n"
    375             "                                           <protocol> is either tcp or udp.\n"
    376             "  -p <product>                             Specify product name.\n"
    377             "  -c <cmdline>                             Override kernel commandline.\n"
    378             "  -i <vendor id>                           Specify a custom USB vendor id.\n"
    379             "  -b, --base <base_addr>                   Specify a custom kernel base\n"
    380             "                                           address (default: 0x10000000).\n"
    381             "  --kernel-offset                          Specify a custom kernel offset.\n"
    382             "                                           (default: 0x00008000)\n"
    383             "  --ramdisk-offset                         Specify a custom ramdisk offset.\n"
    384             "                                           (default: 0x01000000)\n"
    385             "  --tags-offset                            Specify a custom tags offset.\n"
    386             "                                           (default: 0x00000100)\n"
    387             "  -n, --page-size <page size>              Specify the nand page size\n"
    388             "                                           (default: 2048).\n"
    389             "  -S <size>[K|M|G]                         Automatically sparse files greater\n"
    390             "                                           than 'size'. 0 to disable.\n"
    391             "  --slot <slot>                            Specify slot name to be used if the\n"
    392             "                                           device supports slots. All operations\n"
    393             "                                           on partitions that support slots will\n"
    394             "                                           be done on the slot specified.\n"
    395             "                                           'all' can be given to refer to all slots.\n"
    396             "                                           'other' can be given to refer to a\n"
    397             "                                           non-current slot. If this flag is not\n"
    398             "                                           used, slotted partitions will default\n"
    399             "                                           to the current active slot.\n"
    400             "  -a, --set-active[=<slot>]                Sets the active slot. If no slot is\n"
    401             "                                           provided, this will default to the value\n"
    402             "                                           given by --slot. If slots are not\n"
    403             "                                           supported, this sets the current slot\n"
    404             "                                           to be active. This will run after all\n"
    405             "                                           non-reboot commands.\n"
    406             "  --skip-secondary                         Will not flash secondary slots when\n"
    407             "                                           performing a flashall or update. This\n"
    408             "                                           will preserve data on other slots.\n"
    409 #if !defined(_WIN32)
    410             "  --wipe-and-use-fbe                       On devices which support it,\n"
    411             "                                           erase userdata and cache, and\n"
    412             "                                           enable file-based encryption\n"
    413 #endif
    414             "  --unbuffered                             Do not buffer input or output.\n"
    415             "  --version                                Display version.\n"
    416             "  -h, --help                               show this message.\n"
    417         );
    418 }
    419 
    420 static void* load_bootable_image(const char* kernel, const char* ramdisk,
    421                                  const char* secondstage, int64_t* sz,
    422                                  const char* cmdline) {
    423     if (kernel == nullptr) {
    424         fprintf(stderr, "no image specified\n");
    425         return 0;
    426     }
    427 
    428     int64_t ksize;
    429     void* kdata = load_file(kernel, &ksize);
    430     if (kdata == nullptr) {
    431         fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno));
    432         return 0;
    433     }
    434 
    435     // Is this actually a boot image?
    436     if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
    437         if (cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline);
    438 
    439         if (ramdisk) {
    440             fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n");
    441             return 0;
    442         }
    443 
    444         *sz = ksize;
    445         return kdata;
    446     }
    447 
    448     void* rdata = nullptr;
    449     int64_t rsize = 0;
    450     if (ramdisk) {
    451         rdata = load_file(ramdisk, &rsize);
    452         if (rdata == nullptr) {
    453             fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno));
    454             return  0;
    455         }
    456     }
    457 
    458     void* sdata = nullptr;
    459     int64_t ssize = 0;
    460     if (secondstage) {
    461         sdata = load_file(secondstage, &ssize);
    462         if (sdata == nullptr) {
    463             fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno));
    464             return  0;
    465         }
    466     }
    467 
    468     fprintf(stderr,"creating boot image...\n");
    469     int64_t bsize = 0;
    470     void* bdata = mkbootimg(kdata, ksize, kernel_offset,
    471                       rdata, rsize, ramdisk_offset,
    472                       sdata, ssize, second_offset,
    473                       page_size, base_addr, tags_offset, &bsize);
    474     if (bdata == nullptr) {
    475         fprintf(stderr,"failed to create boot.img\n");
    476         return 0;
    477     }
    478     if (cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline);
    479     fprintf(stderr, "creating boot image - %" PRId64 " bytes\n", bsize);
    480     *sz = bsize;
    481 
    482     return bdata;
    483 }
    484 
    485 static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz)
    486 {
    487     ZipString zip_entry_name(entry_name);
    488     ZipEntry zip_entry;
    489     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
    490         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
    491         return 0;
    492     }
    493 
    494     *sz = zip_entry.uncompressed_length;
    495 
    496     uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length));
    497     if (data == nullptr) {
    498         fprintf(stderr, "failed to allocate %" PRId64 " bytes for '%s'\n", *sz, entry_name);
    499         return 0;
    500     }
    501 
    502     int error = ExtractToMemory(zip, &zip_entry, data, zip_entry.uncompressed_length);
    503     if (error != 0) {
    504         fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
    505         free(data);
    506         return 0;
    507     }
    508 
    509     return data;
    510 }
    511 
    512 #if defined(_WIN32)
    513 
    514 // TODO: move this to somewhere it can be shared.
    515 
    516 #include <windows.h>
    517 
    518 // Windows' tmpfile(3) requires administrator rights because
    519 // it creates temporary files in the root directory.
    520 static FILE* win32_tmpfile() {
    521     char temp_path[PATH_MAX];
    522     DWORD nchars = GetTempPath(sizeof(temp_path), temp_path);
    523     if (nchars == 0 || nchars >= sizeof(temp_path)) {
    524         fprintf(stderr, "GetTempPath failed, error %ld\n", GetLastError());
    525         return nullptr;
    526     }
    527 
    528     char filename[PATH_MAX];
    529     if (GetTempFileName(temp_path, "fastboot", 0, filename) == 0) {
    530         fprintf(stderr, "GetTempFileName failed, error %ld\n", GetLastError());
    531         return nullptr;
    532     }
    533 
    534     return fopen(filename, "w+bTD");
    535 }
    536 
    537 #define tmpfile win32_tmpfile
    538 
    539 static std::string make_temporary_directory() {
    540     fprintf(stderr, "make_temporary_directory not supported under Windows, sorry!");
    541     return "";
    542 }
    543 
    544 #else
    545 
    546 static std::string make_temporary_directory() {
    547     const char *tmpdir = getenv("TMPDIR");
    548     if (tmpdir == nullptr) {
    549         tmpdir = P_tmpdir;
    550     }
    551     std::string result = std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
    552     if (mkdtemp(&result[0]) == NULL) {
    553         fprintf(stderr, "Unable to create temporary directory: %s\n",
    554             strerror(errno));
    555         return "";
    556     }
    557     return result;
    558 }
    559 
    560 #endif
    561 
    562 static std::string create_fbemarker_tmpdir() {
    563     std::string dir = make_temporary_directory();
    564     if (dir.empty()) {
    565         fprintf(stderr, "Unable to create local temp directory for FBE marker\n");
    566         return "";
    567     }
    568     std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    569     int fd = open(marker_file.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0666);
    570     if (fd == -1) {
    571         fprintf(stderr, "Unable to create FBE marker file %s locally: %d, %s\n",
    572             marker_file.c_str(), errno, strerror(errno));
    573         return "";
    574     }
    575     close(fd);
    576     return dir;
    577 }
    578 
    579 static void delete_fbemarker_tmpdir(const std::string& dir) {
    580     std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    581     if (unlink(marker_file.c_str()) == -1) {
    582         fprintf(stderr, "Unable to delete FBE marker file %s locally: %d, %s\n",
    583             marker_file.c_str(), errno, strerror(errno));
    584         return;
    585     }
    586     if (rmdir(dir.c_str()) == -1) {
    587         fprintf(stderr, "Unable to delete FBE marker directory %s locally: %d, %s\n",
    588             dir.c_str(), errno, strerror(errno));
    589         return;
    590     }
    591 }
    592 
    593 static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) {
    594     FILE* fp = tmpfile();
    595     if (fp == nullptr) {
    596         fprintf(stderr, "failed to create temporary file for '%s': %s\n",
    597                 entry_name, strerror(errno));
    598         return -1;
    599     }
    600 
    601     ZipString zip_entry_name(entry_name);
    602     ZipEntry zip_entry;
    603     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
    604         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
    605         return -1;
    606     }
    607 
    608     int fd = fileno(fp);
    609     int error = ExtractEntryToFile(zip, &zip_entry, fd);
    610     if (error != 0) {
    611         fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
    612         return -1;
    613     }
    614 
    615     lseek(fd, 0, SEEK_SET);
    616     return fd;
    617 }
    618 
    619 static char *strip(char *s)
    620 {
    621     int n;
    622     while(*s && isspace(*s)) s++;
    623     n = strlen(s);
    624     while(n-- > 0) {
    625         if(!isspace(s[n])) break;
    626         s[n] = 0;
    627     }
    628     return s;
    629 }
    630 
    631 #define MAX_OPTIONS 32
    632 static int setup_requirement_line(char *name)
    633 {
    634     char *val[MAX_OPTIONS];
    635     char *prod = nullptr;
    636     unsigned n, count;
    637     char *x;
    638     int invert = 0;
    639 
    640     if (!strncmp(name, "reject ", 7)) {
    641         name += 7;
    642         invert = 1;
    643     } else if (!strncmp(name, "require ", 8)) {
    644         name += 8;
    645         invert = 0;
    646     } else if (!strncmp(name, "require-for-product:", 20)) {
    647         // Get the product and point name past it
    648         prod = name + 20;
    649         name = strchr(name, ' ');
    650         if (!name) return -1;
    651         *name = 0;
    652         name += 1;
    653         invert = 0;
    654     }
    655 
    656     x = strchr(name, '=');
    657     if (x == 0) return 0;
    658     *x = 0;
    659     val[0] = x + 1;
    660 
    661     for(count = 1; count < MAX_OPTIONS; count++) {
    662         x = strchr(val[count - 1],'|');
    663         if (x == 0) break;
    664         *x = 0;
    665         val[count] = x + 1;
    666     }
    667 
    668     name = strip(name);
    669     for(n = 0; n < count; n++) val[n] = strip(val[n]);
    670 
    671     name = strip(name);
    672     if (name == 0) return -1;
    673 
    674     const char* var = name;
    675     // Work around an unfortunate name mismatch.
    676     if (!strcmp(name,"board")) var = "product";
    677 
    678     const char** out = reinterpret_cast<const char**>(malloc(sizeof(char*) * count));
    679     if (out == 0) return -1;
    680 
    681     for(n = 0; n < count; n++) {
    682         out[n] = strdup(strip(val[n]));
    683         if (out[n] == 0) {
    684             for(size_t i = 0; i < n; ++i) {
    685                 free((char*) out[i]);
    686             }
    687             free(out);
    688             return -1;
    689         }
    690     }
    691 
    692     fb_queue_require(prod, var, invert, n, out);
    693     return 0;
    694 }
    695 
    696 static void setup_requirements(char* data, int64_t sz) {
    697     char* s = data;
    698     while (sz-- > 0) {
    699         if (*s == '\n') {
    700             *s++ = 0;
    701             if (setup_requirement_line(data)) {
    702                 die("out of memory");
    703             }
    704             data = s;
    705         } else {
    706             s++;
    707         }
    708     }
    709 }
    710 
    711 static void queue_info_dump() {
    712     fb_queue_notice("--------------------------------------------");
    713     fb_queue_display("version-bootloader", "Bootloader Version...");
    714     fb_queue_display("version-baseband",   "Baseband Version.....");
    715     fb_queue_display("serialno",           "Serial Number........");
    716     fb_queue_notice("--------------------------------------------");
    717 }
    718 
    719 static struct sparse_file **load_sparse_files(int fd, int max_size)
    720 {
    721     struct sparse_file* s = sparse_file_import_auto(fd, false, true);
    722     if (!s) {
    723         die("cannot sparse read file\n");
    724     }
    725 
    726     int files = sparse_file_resparse(s, max_size, nullptr, 0);
    727     if (files < 0) {
    728         die("Failed to resparse\n");
    729     }
    730 
    731     sparse_file** out_s = reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file *), files + 1));
    732     if (!out_s) {
    733         die("Failed to allocate sparse file array\n");
    734     }
    735 
    736     files = sparse_file_resparse(s, max_size, out_s, files);
    737     if (files < 0) {
    738         die("Failed to resparse\n");
    739     }
    740 
    741     return out_s;
    742 }
    743 
    744 static int64_t get_target_sparse_limit(Transport* transport) {
    745     std::string max_download_size;
    746     if (!fb_getvar(transport, "max-download-size", &max_download_size) ||
    747             max_download_size.empty()) {
    748         fprintf(stderr, "target didn't report max-download-size\n");
    749         return 0;
    750     }
    751 
    752     // Some bootloaders (angler, for example) send spurious whitespace too.
    753     max_download_size = android::base::Trim(max_download_size);
    754 
    755     uint64_t limit;
    756     if (!android::base::ParseUint(max_download_size.c_str(), &limit)) {
    757         fprintf(stderr, "couldn't parse max-download-size '%s'\n", max_download_size.c_str());
    758         return 0;
    759     }
    760     if (limit > 0) {
    761         fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit);
    762     }
    763     return limit;
    764 }
    765 
    766 static int64_t get_sparse_limit(Transport* transport, int64_t size) {
    767     int64_t limit;
    768 
    769     if (sparse_limit == 0) {
    770         return 0;
    771     } else if (sparse_limit > 0) {
    772         limit = sparse_limit;
    773     } else {
    774         if (target_sparse_limit == -1) {
    775             target_sparse_limit = get_target_sparse_limit(transport);
    776         }
    777         if (target_sparse_limit > 0) {
    778             limit = target_sparse_limit;
    779         } else {
    780             return 0;
    781         }
    782     }
    783 
    784     if (size > limit) {
    785         return limit;
    786     }
    787 
    788     return 0;
    789 }
    790 
    791 // Until we get lazy inode table init working in make_ext4fs, we need to
    792 // erase partitions of type ext4 before flashing a filesystem so no stale
    793 // inodes are left lying around.  Otherwise, e2fsck gets very upset.
    794 static bool needs_erase(Transport* transport, const char* partition) {
    795     std::string partition_type;
    796     if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
    797         return false;
    798     }
    799     return partition_type == "ext4";
    800 }
    801 
    802 static int load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf) {
    803     int64_t sz = get_file_size(fd);
    804     if (sz == -1) {
    805         return -1;
    806     }
    807 
    808     lseek64(fd, 0, SEEK_SET);
    809     int64_t limit = get_sparse_limit(transport, sz);
    810     if (limit) {
    811         sparse_file** s = load_sparse_files(fd, limit);
    812         if (s == nullptr) {
    813             return -1;
    814         }
    815         buf->type = FB_BUFFER_SPARSE;
    816         buf->data = s;
    817     } else {
    818         void* data = load_fd(fd, &sz);
    819         if (data == nullptr) return -1;
    820         buf->type = FB_BUFFER;
    821         buf->data = data;
    822         buf->sz = sz;
    823     }
    824 
    825     return 0;
    826 }
    827 
    828 static int load_buf(Transport* transport, const char *fname, struct fastboot_buffer *buf)
    829 {
    830     int fd;
    831 
    832     fd = open(fname, O_RDONLY | O_BINARY);
    833     if (fd < 0) {
    834         return -1;
    835     }
    836 
    837     return load_buf_fd(transport, fd, buf);
    838 }
    839 
    840 static void flash_buf(const char *pname, struct fastboot_buffer *buf)
    841 {
    842     sparse_file** s;
    843 
    844     switch (buf->type) {
    845         case FB_BUFFER_SPARSE: {
    846             std::vector<std::pair<sparse_file*, int64_t>> sparse_files;
    847             s = reinterpret_cast<sparse_file**>(buf->data);
    848             while (*s) {
    849                 int64_t sz = sparse_file_len(*s, true, false);
    850                 sparse_files.emplace_back(*s, sz);
    851                 ++s;
    852             }
    853 
    854             for (size_t i = 0; i < sparse_files.size(); ++i) {
    855                 const auto& pair = sparse_files[i];
    856                 fb_queue_flash_sparse(pname, pair.first, pair.second, i + 1, sparse_files.size());
    857             }
    858             break;
    859         }
    860 
    861         case FB_BUFFER:
    862             fb_queue_flash(pname, buf->data, buf->sz);
    863             break;
    864         default:
    865             die("unknown buffer type: %d", buf->type);
    866     }
    867 }
    868 
    869 static std::string get_current_slot(Transport* transport)
    870 {
    871     std::string current_slot;
    872     if (fb_getvar(transport, "current-slot", &current_slot)) {
    873         if (current_slot == "_a") return "a"; // Legacy support
    874         if (current_slot == "_b") return "b"; // Legacy support
    875         return current_slot;
    876     }
    877     return "";
    878 }
    879 
    880 // Legacy support
    881 static std::vector<std::string> get_suffixes_obsolete(Transport* transport) {
    882     std::vector<std::string> suffixes;
    883     std::string suffix_list;
    884     if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
    885         return suffixes;
    886     }
    887     suffixes = android::base::Split(suffix_list, ",");
    888     // Unfortunately some devices will return an error message in the
    889     // guise of a valid value. If we only see only one suffix, it's probably
    890     // not real.
    891     if (suffixes.size() == 1) {
    892         suffixes.clear();
    893     }
    894     return suffixes;
    895 }
    896 
    897 // Legacy support
    898 static bool supports_AB_obsolete(Transport* transport) {
    899   return !get_suffixes_obsolete(transport).empty();
    900 }
    901 
    902 static int get_slot_count(Transport* transport) {
    903     std::string var;
    904     int count;
    905     if (!fb_getvar(transport, "slot-count", &var)) {
    906         if (supports_AB_obsolete(transport)) return 2; // Legacy support
    907     }
    908     if (!android::base::ParseInt(var.c_str(), &count)) return 0;
    909     return count;
    910 }
    911 
    912 static bool supports_AB(Transport* transport) {
    913   return get_slot_count(transport) >= 2;
    914 }
    915 
    916 // Given a current slot, this returns what the 'other' slot is.
    917 static std::string get_other_slot(const std::string& current_slot, int count) {
    918     if (count == 0) return "";
    919 
    920     char next = (current_slot[0] - 'a' + 1)%count + 'a';
    921     return std::string(1, next);
    922 }
    923 
    924 static std::string get_other_slot(Transport* transport, const std::string& current_slot) {
    925     return get_other_slot(current_slot, get_slot_count(transport));
    926 }
    927 
    928 static std::string get_other_slot(Transport* transport, int count) {
    929     return get_other_slot(get_current_slot(transport), count);
    930 }
    931 
    932 static std::string get_other_slot(Transport* transport) {
    933     return get_other_slot(get_current_slot(transport), get_slot_count(transport));
    934 }
    935 
    936 static std::string verify_slot(Transport* transport, const std::string& slot_name, bool allow_all) {
    937     std::string slot = slot_name;
    938     if (slot == "_a") slot = "a"; // Legacy support
    939     if (slot == "_b") slot = "b"; // Legacy support
    940     if (slot == "all") {
    941         if (allow_all) {
    942             return "all";
    943         } else {
    944             int count = get_slot_count(transport);
    945             if (count > 0) {
    946                 return "a";
    947             } else {
    948                 die("No known slots.");
    949             }
    950         }
    951     }
    952 
    953     int count = get_slot_count(transport);
    954     if (count == 0) die("Device does not support slots.\n");
    955 
    956     if (slot == "other") {
    957         std::string other = get_other_slot(transport, count);
    958         if (other == "") {
    959            die("No known slots.");
    960         }
    961         return other;
    962     }
    963 
    964     if (slot.size() == 1 && (slot[0]-'a' >= 0 && slot[0]-'a' < count)) return slot;
    965 
    966     fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot.c_str());
    967     for (int i=0; i<count; i++) {
    968         fprintf(stderr, "%c\n", (char)(i + 'a'));
    969     }
    970 
    971     exit(1);
    972 }
    973 
    974 static std::string verify_slot(Transport* transport, const std::string& slot) {
    975    return verify_slot(transport, slot, true);
    976 }
    977 
    978 static void do_for_partition(Transport* transport, const std::string& part, const std::string& slot,
    979                              std::function<void(const std::string&)> func, bool force_slot) {
    980     std::string has_slot;
    981     std::string current_slot;
    982 
    983     if (!fb_getvar(transport, "has-slot:" + part, &has_slot)) {
    984         /* If has-slot is not supported, the answer is no. */
    985         has_slot = "no";
    986     }
    987     if (has_slot == "yes") {
    988         if (slot == "") {
    989             current_slot = get_current_slot(transport);
    990             if (current_slot == "") {
    991                 die("Failed to identify current slot.\n");
    992             }
    993             func(part + "_" + current_slot);
    994         } else {
    995             func(part + '_' + slot);
    996         }
    997     } else {
    998         if (force_slot && slot != "") {
    999              fprintf(stderr, "Warning: %s does not support slots, and slot %s was requested.\n",
   1000                      part.c_str(), slot.c_str());
   1001         }
   1002         func(part);
   1003     }
   1004 }
   1005 
   1006 /* This function will find the real partition name given a base name, and a slot. If slot is NULL or
   1007  * empty, it will use the current slot. If slot is "all", it will return a list of all possible
   1008  * partition names. If force_slot is true, it will fail if a slot is specified, and the given
   1009  * partition does not support slots.
   1010  */
   1011 static void do_for_partitions(Transport* transport, const std::string& part, const std::string& slot,
   1012                               std::function<void(const std::string&)> func, bool force_slot) {
   1013     std::string has_slot;
   1014 
   1015     if (slot == "all") {
   1016         if (!fb_getvar(transport, "has-slot:" + part, &has_slot)) {
   1017             die("Could not check if partition %s has slot.", part.c_str());
   1018         }
   1019         if (has_slot == "yes") {
   1020             for (int i=0; i < get_slot_count(transport); i++) {
   1021                 do_for_partition(transport, part, std::string(1, (char)(i + 'a')), func, force_slot);
   1022             }
   1023         } else {
   1024             do_for_partition(transport, part, "", func, force_slot);
   1025         }
   1026     } else {
   1027         do_for_partition(transport, part, slot, func, force_slot);
   1028     }
   1029 }
   1030 
   1031 static void do_flash(Transport* transport, const char* pname, const char* fname) {
   1032     struct fastboot_buffer buf;
   1033 
   1034     if (load_buf(transport, fname, &buf)) {
   1035         die("cannot load '%s'", fname);
   1036     }
   1037     flash_buf(pname, &buf);
   1038 }
   1039 
   1040 static void do_update_signature(ZipArchiveHandle zip, char* fn) {
   1041     int64_t sz;
   1042     void* data = unzip_file(zip, fn, &sz);
   1043     if (data == nullptr) return;
   1044     fb_queue_download("signature", data, sz);
   1045     fb_queue_command("signature", "installing signature");
   1046 }
   1047 
   1048 // Sets slot_override as the active slot. If slot_override is blank,
   1049 // set current slot as active instead. This clears slot-unbootable.
   1050 static void set_active(Transport* transport, const std::string& slot_override) {
   1051     std::string separator = "";
   1052     if (!supports_AB(transport)) {
   1053         if (supports_AB_obsolete(transport)) {
   1054             separator = "_"; // Legacy support
   1055         } else {
   1056             return;
   1057         }
   1058     }
   1059     if (slot_override != "") {
   1060         fb_set_active((separator + slot_override).c_str());
   1061     } else {
   1062         std::string current_slot = get_current_slot(transport);
   1063         if (current_slot != "") {
   1064             fb_set_active((separator + current_slot).c_str());
   1065         }
   1066     }
   1067 }
   1068 
   1069 static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first, bool skip_secondary) {
   1070     queue_info_dump();
   1071 
   1072     fb_queue_query_save("product", cur_product, sizeof(cur_product));
   1073 
   1074     ZipArchiveHandle zip;
   1075     int error = OpenArchive(filename, &zip);
   1076     if (error != 0) {
   1077         CloseArchive(zip);
   1078         die("failed to open zip file '%s': %s", filename, ErrorCodeString(error));
   1079     }
   1080 
   1081     int64_t sz;
   1082     void* data = unzip_file(zip, "android-info.txt", &sz);
   1083     if (data == nullptr) {
   1084         CloseArchive(zip);
   1085         die("update package '%s' has no android-info.txt", filename);
   1086     }
   1087 
   1088     setup_requirements(reinterpret_cast<char*>(data), sz);
   1089 
   1090     std::string secondary;
   1091     if (!skip_secondary) {
   1092         if (slot_override != "") {
   1093             secondary = get_other_slot(transport, slot_override);
   1094         } else {
   1095             secondary = get_other_slot(transport);
   1096         }
   1097         if (secondary == "") {
   1098             if (supports_AB(transport)) {
   1099                 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
   1100             }
   1101             skip_secondary = true;
   1102         }
   1103     }
   1104     for (size_t i = 0; i < ARRAY_SIZE(images); ++i) {
   1105         const char* slot = slot_override.c_str();
   1106         if (images[i].is_secondary) {
   1107             if (!skip_secondary) {
   1108                 slot = secondary.c_str();
   1109             } else {
   1110                 continue;
   1111             }
   1112         }
   1113 
   1114         int fd = unzip_to_file(zip, images[i].img_name);
   1115         if (fd == -1) {
   1116             if (images[i].is_optional) {
   1117                 continue;
   1118             }
   1119             CloseArchive(zip);
   1120             exit(1); // unzip_to_file already explained why.
   1121         }
   1122         fastboot_buffer buf;
   1123         int rc = load_buf_fd(transport, fd, &buf);
   1124         if (rc) die("cannot load %s from flash", images[i].img_name);
   1125 
   1126         auto update = [&](const std::string &partition) {
   1127             do_update_signature(zip, images[i].sig_name);
   1128             if (erase_first && needs_erase(transport, partition.c_str())) {
   1129                 fb_queue_erase(partition.c_str());
   1130             }
   1131             flash_buf(partition.c_str(), &buf);
   1132             /* not closing the fd here since the sparse code keeps the fd around
   1133              * but hasn't mmaped data yet. The tmpfile will get cleaned up when the
   1134              * program exits.
   1135              */
   1136         };
   1137         do_for_partitions(transport, images[i].part_name, slot, update, false);
   1138     }
   1139 
   1140     CloseArchive(zip);
   1141     if (slot_override == "all") {
   1142         set_active(transport, "a");
   1143     } else {
   1144         set_active(transport, slot_override);
   1145     }
   1146 }
   1147 
   1148 static void do_send_signature(const std::string& fn) {
   1149     std::size_t extension_loc = fn.find(".img");
   1150     if (extension_loc == std::string::npos) return;
   1151 
   1152     std::string fs_sig = fn.substr(0, extension_loc) + ".sig";
   1153 
   1154     int64_t sz;
   1155     void* data = load_file(fs_sig.c_str(), &sz);
   1156     if (data == nullptr) return;
   1157     fb_queue_download("signature", data, sz);
   1158     fb_queue_command("signature", "installing signature");
   1159 }
   1160 
   1161 static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool skip_secondary) {
   1162     std::string fname;
   1163     queue_info_dump();
   1164 
   1165     fb_queue_query_save("product", cur_product, sizeof(cur_product));
   1166 
   1167     fname = find_item("info", product);
   1168     if (fname == "") die("cannot find android-info.txt");
   1169 
   1170     int64_t sz;
   1171     void* data = load_file(fname.c_str(), &sz);
   1172     if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno));
   1173 
   1174     setup_requirements(reinterpret_cast<char*>(data), sz);
   1175 
   1176     std::string secondary;
   1177     if (!skip_secondary) {
   1178         if (slot_override != "") {
   1179             secondary = get_other_slot(transport, slot_override);
   1180         } else {
   1181             secondary = get_other_slot(transport);
   1182         }
   1183         if (secondary == "") {
   1184             if (supports_AB(transport)) {
   1185                 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
   1186             }
   1187             skip_secondary = true;
   1188         }
   1189     }
   1190 
   1191     for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
   1192         const char* slot = NULL;
   1193         if (images[i].is_secondary) {
   1194             if (!skip_secondary) slot = secondary.c_str();
   1195         } else {
   1196             slot = slot_override.c_str();
   1197         }
   1198         if (!slot) continue;
   1199         fname = find_item_given_name(images[i].img_name, product);
   1200         fastboot_buffer buf;
   1201         if (load_buf(transport, fname.c_str(), &buf)) {
   1202             if (images[i].is_optional) continue;
   1203             die("could not load %s\n", images[i].img_name);
   1204         }
   1205 
   1206         auto flashall = [&](const std::string &partition) {
   1207             do_send_signature(fname);
   1208             if (erase_first && needs_erase(transport, partition.c_str())) {
   1209                 fb_queue_erase(partition.c_str());
   1210             }
   1211             flash_buf(partition.c_str(), &buf);
   1212         };
   1213         do_for_partitions(transport, images[i].part_name, slot, flashall, false);
   1214     }
   1215 
   1216     if (slot_override == "all") {
   1217         set_active(transport, "a");
   1218     } else {
   1219         set_active(transport, slot_override);
   1220     }
   1221 }
   1222 
   1223 #define skip(n) do { argc -= (n); argv += (n); } while (0)
   1224 #define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0)
   1225 
   1226 static int do_bypass_unlock_command(int argc, char **argv)
   1227 {
   1228     if (argc <= 2) return 0;
   1229     skip(2);
   1230 
   1231     /*
   1232      * Process unlock_bootloader, we have to load the message file
   1233      * and send that to the remote device.
   1234      */
   1235     require(1);
   1236 
   1237     int64_t sz;
   1238     void* data = load_file(*argv, &sz);
   1239     if (data == nullptr) die("could not load '%s': %s", *argv, strerror(errno));
   1240     fb_queue_download("unlock_message", data, sz);
   1241     fb_queue_command("flashing unlock_bootloader", "unlocking bootloader");
   1242     skip(1);
   1243     return 0;
   1244 }
   1245 
   1246 static int do_oem_command(int argc, char **argv)
   1247 {
   1248     char command[256];
   1249     if (argc <= 1) return 0;
   1250 
   1251     command[0] = 0;
   1252     while(1) {
   1253         strcat(command,*argv);
   1254         skip(1);
   1255         if(argc == 0) break;
   1256         strcat(command," ");
   1257     }
   1258 
   1259     fb_queue_command(command,"");
   1260     return 0;
   1261 }
   1262 
   1263 static int64_t parse_num(const char *arg)
   1264 {
   1265     char *endptr;
   1266     unsigned long long num;
   1267 
   1268     num = strtoull(arg, &endptr, 0);
   1269     if (endptr == arg) {
   1270         return -1;
   1271     }
   1272 
   1273     if (*endptr == 'k' || *endptr == 'K') {
   1274         if (num >= (-1ULL) / 1024) {
   1275             return -1;
   1276         }
   1277         num *= 1024LL;
   1278         endptr++;
   1279     } else if (*endptr == 'm' || *endptr == 'M') {
   1280         if (num >= (-1ULL) / (1024 * 1024)) {
   1281             return -1;
   1282         }
   1283         num *= 1024LL * 1024LL;
   1284         endptr++;
   1285     } else if (*endptr == 'g' || *endptr == 'G') {
   1286         if (num >= (-1ULL) / (1024 * 1024 * 1024)) {
   1287             return -1;
   1288         }
   1289         num *= 1024LL * 1024LL * 1024LL;
   1290         endptr++;
   1291     }
   1292 
   1293     if (*endptr != '\0') {
   1294         return -1;
   1295     }
   1296 
   1297     if (num > INT64_MAX) {
   1298         return -1;
   1299     }
   1300 
   1301     return num;
   1302 }
   1303 
   1304 static void fb_perform_format(Transport* transport,
   1305                               const char* partition, int skip_if_not_supported,
   1306                               const char* type_override, const char* size_override,
   1307                               const std::string& initial_dir) {
   1308     std::string partition_type, partition_size;
   1309 
   1310     struct fastboot_buffer buf;
   1311     const char* errMsg = nullptr;
   1312     const struct fs_generator* gen = nullptr;
   1313     int fd;
   1314 
   1315     unsigned int limit = INT_MAX;
   1316     if (target_sparse_limit > 0 && target_sparse_limit < limit) {
   1317         limit = target_sparse_limit;
   1318     }
   1319     if (sparse_limit > 0 && sparse_limit < limit) {
   1320         limit = sparse_limit;
   1321     }
   1322 
   1323     if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
   1324         errMsg = "Can't determine partition type.\n";
   1325         goto failed;
   1326     }
   1327     if (type_override) {
   1328         if (partition_type != type_override) {
   1329             fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n",
   1330                     partition, partition_type.c_str(), type_override);
   1331         }
   1332         partition_type = type_override;
   1333     }
   1334 
   1335     if (!fb_getvar(transport, std::string("partition-size:") + partition, &partition_size)) {
   1336         errMsg = "Unable to get partition size\n";
   1337         goto failed;
   1338     }
   1339     if (size_override) {
   1340         if (partition_size != size_override) {
   1341             fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n",
   1342                     partition, partition_size.c_str(), size_override);
   1343         }
   1344         partition_size = size_override;
   1345     }
   1346     // Some bootloaders (angler, for example), send spurious leading whitespace.
   1347     partition_size = android::base::Trim(partition_size);
   1348     // Some bootloaders (hammerhead, for example) use implicit hex.
   1349     // This code used to use strtol with base 16.
   1350     if (!android::base::StartsWith(partition_size, "0x")) partition_size = "0x" + partition_size;
   1351 
   1352     gen = fs_get_generator(partition_type);
   1353     if (!gen) {
   1354         if (skip_if_not_supported) {
   1355             fprintf(stderr, "Erase successful, but not automatically formatting.\n");
   1356             fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str());
   1357             return;
   1358         }
   1359         fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n",
   1360                 partition_type.c_str());
   1361         return;
   1362     }
   1363 
   1364     int64_t size;
   1365     if (!android::base::ParseInt(partition_size.c_str(), &size)) {
   1366         fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str());
   1367         return;
   1368     }
   1369 
   1370     fd = fileno(tmpfile());
   1371     if (fs_generator_generate(gen, fd, size, initial_dir)) {
   1372         fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
   1373         close(fd);
   1374         return;
   1375     }
   1376 
   1377     if (load_buf_fd(transport, fd, &buf)) {
   1378         fprintf(stderr, "Cannot read image: %s\n", strerror(errno));
   1379         close(fd);
   1380         return;
   1381     }
   1382     flash_buf(partition, &buf);
   1383     return;
   1384 
   1385 failed:
   1386     if (skip_if_not_supported) {
   1387         fprintf(stderr, "Erase successful, but not automatically formatting.\n");
   1388         if (errMsg) fprintf(stderr, "%s", errMsg);
   1389     }
   1390     fprintf(stderr,"FAILED (%s)\n", fb_get_error());
   1391 }
   1392 
   1393 int main(int argc, char **argv)
   1394 {
   1395     bool wants_wipe = false;
   1396     bool wants_reboot = false;
   1397     bool wants_reboot_bootloader = false;
   1398     bool wants_set_active = false;
   1399     bool skip_secondary = false;
   1400     bool erase_first = true;
   1401     bool set_fbe_marker = false;
   1402     void *data;
   1403     int64_t sz;
   1404     int longindex;
   1405     std::string slot_override;
   1406     std::string next_active;
   1407 
   1408     const struct option longopts[] = {
   1409         {"base", required_argument, 0, 'b'},
   1410         {"kernel_offset", required_argument, 0, 'k'},
   1411         {"kernel-offset", required_argument, 0, 'k'},
   1412         {"page_size", required_argument, 0, 'n'},
   1413         {"page-size", required_argument, 0, 'n'},
   1414         {"ramdisk_offset", required_argument, 0, 'r'},
   1415         {"ramdisk-offset", required_argument, 0, 'r'},
   1416         {"tags_offset", required_argument, 0, 't'},
   1417         {"tags-offset", required_argument, 0, 't'},
   1418         {"help", no_argument, 0, 'h'},
   1419         {"unbuffered", no_argument, 0, 0},
   1420         {"version", no_argument, 0, 0},
   1421         {"slot", required_argument, 0, 0},
   1422         {"set_active", optional_argument, 0, 'a'},
   1423         {"set-active", optional_argument, 0, 'a'},
   1424         {"skip-secondary", no_argument, 0, 0},
   1425 #if !defined(_WIN32)
   1426         {"wipe-and-use-fbe", no_argument, 0, 0},
   1427 #endif
   1428         {0, 0, 0, 0}
   1429     };
   1430 
   1431     serial = getenv("ANDROID_SERIAL");
   1432 
   1433     while (1) {
   1434         int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:ha::", longopts, &longindex);
   1435         if (c < 0) {
   1436             break;
   1437         }
   1438         /* Alphabetical cases */
   1439         switch (c) {
   1440         case 'a':
   1441             wants_set_active = true;
   1442             if (optarg)
   1443                 next_active = optarg;
   1444             break;
   1445         case 'b':
   1446             base_addr = strtoul(optarg, 0, 16);
   1447             break;
   1448         case 'c':
   1449             cmdline = optarg;
   1450             break;
   1451         case 'h':
   1452             usage();
   1453             return 1;
   1454         case 'i': {
   1455                 char *endptr = nullptr;
   1456                 unsigned long val;
   1457 
   1458                 val = strtoul(optarg, &endptr, 0);
   1459                 if (!endptr || *endptr != '\0' || (val & ~0xffff))
   1460                     die("invalid vendor id '%s'", optarg);
   1461                 vendor_id = (unsigned short)val;
   1462                 break;
   1463             }
   1464         case 'k':
   1465             kernel_offset = strtoul(optarg, 0, 16);
   1466             break;
   1467         case 'l':
   1468             long_listing = 1;
   1469             break;
   1470         case 'n':
   1471             page_size = (unsigned)strtoul(optarg, nullptr, 0);
   1472             if (!page_size) die("invalid page size");
   1473             break;
   1474         case 'p':
   1475             product = optarg;
   1476             break;
   1477         case 'r':
   1478             ramdisk_offset = strtoul(optarg, 0, 16);
   1479             break;
   1480         case 't':
   1481             tags_offset = strtoul(optarg, 0, 16);
   1482             break;
   1483         case 's':
   1484             serial = optarg;
   1485             break;
   1486         case 'S':
   1487             sparse_limit = parse_num(optarg);
   1488             if (sparse_limit < 0) {
   1489                     die("invalid sparse limit");
   1490             }
   1491             break;
   1492         case 'u':
   1493             erase_first = false;
   1494             break;
   1495         case 'w':
   1496             wants_wipe = true;
   1497             break;
   1498         case '?':
   1499             return 1;
   1500         case 0:
   1501             if (strcmp("unbuffered", longopts[longindex].name) == 0) {
   1502                 setvbuf(stdout, nullptr, _IONBF, 0);
   1503                 setvbuf(stderr, nullptr, _IONBF, 0);
   1504             } else if (strcmp("version", longopts[longindex].name) == 0) {
   1505                 fprintf(stdout, "fastboot version %s\n", FASTBOOT_REVISION);
   1506                 return 0;
   1507             } else if (strcmp("slot", longopts[longindex].name) == 0) {
   1508                 slot_override = std::string(optarg);
   1509             } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
   1510                 skip_secondary = true;
   1511 #if !defined(_WIN32)
   1512             } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
   1513                 wants_wipe = true;
   1514                 set_fbe_marker = true;
   1515 #endif
   1516             } else {
   1517                 fprintf(stderr, "Internal error in options processing for %s\n",
   1518                     longopts[longindex].name);
   1519                 return 1;
   1520             }
   1521             break;
   1522         default:
   1523             abort();
   1524         }
   1525     }
   1526 
   1527     argc -= optind;
   1528     argv += optind;
   1529 
   1530     if (argc == 0 && !wants_wipe && !wants_set_active) {
   1531         usage();
   1532         return 1;
   1533     }
   1534 
   1535     if (argc > 0 && !strcmp(*argv, "devices")) {
   1536         skip(1);
   1537         list_devices();
   1538         return 0;
   1539     }
   1540 
   1541     if (argc > 0 && !strcmp(*argv, "help")) {
   1542         usage();
   1543         return 0;
   1544     }
   1545 
   1546     Transport* transport = open_device();
   1547     if (transport == nullptr) {
   1548         return 1;
   1549     }
   1550 
   1551     if (!supports_AB(transport) && supports_AB_obsolete(transport)) {
   1552         fprintf(stderr, "Warning: Device A/B support is outdated. Bootloader update required.\n");
   1553     }
   1554     if (slot_override != "") slot_override = verify_slot(transport, slot_override);
   1555     if (next_active != "") next_active = verify_slot(transport, next_active, false);
   1556 
   1557     if (wants_set_active) {
   1558         if (next_active == "") {
   1559             if (slot_override == "") {
   1560                 std::string current_slot;
   1561                 if (fb_getvar(transport, "current-slot", &current_slot)) {
   1562                     next_active = verify_slot(transport, current_slot, false);
   1563                 } else {
   1564                     wants_set_active = false;
   1565                 }
   1566             } else {
   1567                 next_active = verify_slot(transport, slot_override, false);
   1568             }
   1569         }
   1570     }
   1571 
   1572     while (argc > 0) {
   1573         if (!strcmp(*argv, "getvar")) {
   1574             require(2);
   1575             fb_queue_display(argv[1], argv[1]);
   1576             skip(2);
   1577         } else if(!strcmp(*argv, "erase")) {
   1578             require(2);
   1579 
   1580             auto erase = [&](const std::string &partition) {
   1581                 std::string partition_type;
   1582                 if (fb_getvar(transport, std::string("partition-type:") + argv[1], &partition_type) &&
   1583                     fs_get_generator(partition_type) != nullptr) {
   1584                     fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
   1585                             partition_type.c_str());
   1586                 }
   1587 
   1588                 fb_queue_erase(partition.c_str());
   1589             };
   1590             do_for_partitions(transport, argv[1], slot_override, erase, true);
   1591             skip(2);
   1592         } else if(!strncmp(*argv, "format", strlen("format"))) {
   1593             char *overrides;
   1594             char *type_override = nullptr;
   1595             char *size_override = nullptr;
   1596             require(2);
   1597             /*
   1598              * Parsing for: "format[:[type][:[size]]]"
   1599              * Some valid things:
   1600              *  - select ontly the size, and leave default fs type:
   1601              *    format::0x4000000 userdata
   1602              *  - default fs type and size:
   1603              *    format userdata
   1604              *    format:: userdata
   1605              */
   1606             overrides = strchr(*argv, ':');
   1607             if (overrides) {
   1608                 overrides++;
   1609                 size_override = strchr(overrides, ':');
   1610                 if (size_override) {
   1611                     size_override[0] = '\0';
   1612                     size_override++;
   1613                 }
   1614                 type_override = overrides;
   1615             }
   1616             if (type_override && !type_override[0]) type_override = nullptr;
   1617             if (size_override && !size_override[0]) size_override = nullptr;
   1618 
   1619             auto format = [&](const std::string &partition) {
   1620                 if (erase_first && needs_erase(transport, partition.c_str())) {
   1621                     fb_queue_erase(partition.c_str());
   1622                 }
   1623                 fb_perform_format(transport, partition.c_str(), 0,
   1624                     type_override, size_override, "");
   1625             };
   1626             do_for_partitions(transport, argv[1], slot_override, format, true);
   1627             skip(2);
   1628         } else if(!strcmp(*argv, "signature")) {
   1629             require(2);
   1630             data = load_file(argv[1], &sz);
   1631             if (data == nullptr) die("could not load '%s': %s", argv[1], strerror(errno));
   1632             if (sz != 256) die("signature must be 256 bytes");
   1633             fb_queue_download("signature", data, sz);
   1634             fb_queue_command("signature", "installing signature");
   1635             skip(2);
   1636         } else if(!strcmp(*argv, "reboot")) {
   1637             wants_reboot = true;
   1638             skip(1);
   1639             if (argc > 0) {
   1640                 if (!strcmp(*argv, "bootloader")) {
   1641                     wants_reboot = false;
   1642                     wants_reboot_bootloader = true;
   1643                     skip(1);
   1644                 }
   1645             }
   1646             require(0);
   1647         } else if(!strcmp(*argv, "reboot-bootloader")) {
   1648             wants_reboot_bootloader = true;
   1649             skip(1);
   1650         } else if (!strcmp(*argv, "continue")) {
   1651             fb_queue_command("continue", "resuming boot");
   1652             skip(1);
   1653         } else if(!strcmp(*argv, "boot")) {
   1654             char *kname = 0;
   1655             char *rname = 0;
   1656             char *sname = 0;
   1657             skip(1);
   1658             if (argc > 0) {
   1659                 kname = argv[0];
   1660                 skip(1);
   1661             }
   1662             if (argc > 0) {
   1663                 rname = argv[0];
   1664                 skip(1);
   1665             }
   1666             if (argc > 0) {
   1667                 sname = argv[0];
   1668                 skip(1);
   1669             }
   1670             data = load_bootable_image(kname, rname, sname, &sz, cmdline);
   1671             if (data == 0) return 1;
   1672             fb_queue_download("boot.img", data, sz);
   1673             fb_queue_command("boot", "booting");
   1674         } else if(!strcmp(*argv, "flash")) {
   1675             char *pname = argv[1];
   1676             std::string fname;
   1677             require(2);
   1678             if (argc > 2) {
   1679                 fname = argv[2];
   1680                 skip(3);
   1681             } else {
   1682                 fname = find_item(pname, product);
   1683                 skip(2);
   1684             }
   1685             if (fname == "") die("cannot determine image filename for '%s'", pname);
   1686 
   1687             auto flash = [&](const std::string &partition) {
   1688                 if (erase_first && needs_erase(transport, partition.c_str())) {
   1689                     fb_queue_erase(partition.c_str());
   1690                 }
   1691                 do_flash(transport, partition.c_str(), fname.c_str());
   1692             };
   1693             do_for_partitions(transport, pname, slot_override, flash, true);
   1694         } else if(!strcmp(*argv, "flash:raw")) {
   1695             char *kname = argv[2];
   1696             char *rname = 0;
   1697             char *sname = 0;
   1698             require(3);
   1699             skip(3);
   1700             if (argc > 0) {
   1701                 rname = argv[0];
   1702                 skip(1);
   1703             }
   1704             if (argc > 0) {
   1705                 sname = argv[0];
   1706                 skip(1);
   1707             }
   1708             data = load_bootable_image(kname, rname, sname, &sz, cmdline);
   1709             if (data == 0) die("cannot load bootable image");
   1710             auto flashraw = [&](const std::string &partition) {
   1711                 fb_queue_flash(partition.c_str(), data, sz);
   1712             };
   1713             do_for_partitions(transport, argv[1], slot_override, flashraw, true);
   1714         } else if(!strcmp(*argv, "flashall")) {
   1715             skip(1);
   1716             if (slot_override == "all") {
   1717                 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
   1718                 do_flashall(transport, slot_override, erase_first, true);
   1719             } else {
   1720                 do_flashall(transport, slot_override, erase_first, skip_secondary);
   1721             }
   1722             wants_reboot = true;
   1723         } else if(!strcmp(*argv, "update")) {
   1724             bool slot_all = (slot_override == "all");
   1725             if (slot_all) {
   1726                 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
   1727             }
   1728             if (argc > 1) {
   1729                 do_update(transport, argv[1], slot_override, erase_first, skip_secondary || slot_all);
   1730                 skip(2);
   1731             } else {
   1732                 do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
   1733                 skip(1);
   1734             }
   1735             wants_reboot = 1;
   1736         } else if(!strcmp(*argv, "set_active")) {
   1737             require(2);
   1738             std::string slot = verify_slot(transport, std::string(argv[1]), false);
   1739             fb_set_active(slot.c_str());
   1740             skip(2);
   1741         } else if(!strcmp(*argv, "oem")) {
   1742             argc = do_oem_command(argc, argv);
   1743         } else if(!strcmp(*argv, "flashing")) {
   1744             if (argc == 2 && (!strcmp(*(argv+1), "unlock") ||
   1745                               !strcmp(*(argv+1), "lock") ||
   1746                               !strcmp(*(argv+1), "unlock_critical") ||
   1747                               !strcmp(*(argv+1), "lock_critical") ||
   1748                               !strcmp(*(argv+1), "get_unlock_ability") ||
   1749                               !strcmp(*(argv+1), "get_unlock_bootloader_nonce") ||
   1750                               !strcmp(*(argv+1), "lock_bootloader"))) {
   1751                 argc = do_oem_command(argc, argv);
   1752             } else
   1753             if (argc == 3 && !strcmp(*(argv+1), "unlock_bootloader")) {
   1754                 argc = do_bypass_unlock_command(argc, argv);
   1755             } else {
   1756               usage();
   1757               return 1;
   1758             }
   1759         } else {
   1760             usage();
   1761             return 1;
   1762         }
   1763     }
   1764 
   1765     if (wants_wipe) {
   1766         fprintf(stderr, "wiping userdata...\n");
   1767         fb_queue_erase("userdata");
   1768         if (set_fbe_marker) {
   1769             fprintf(stderr, "setting FBE marker...\n");
   1770             std::string initial_userdata_dir = create_fbemarker_tmpdir();
   1771             if (initial_userdata_dir.empty()) {
   1772                 return 1;
   1773             }
   1774             fb_perform_format(transport, "userdata", 1, nullptr, nullptr, initial_userdata_dir);
   1775             delete_fbemarker_tmpdir(initial_userdata_dir);
   1776         } else {
   1777             fb_perform_format(transport, "userdata", 1, nullptr, nullptr, "");
   1778         }
   1779 
   1780         std::string cache_type;
   1781         if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) {
   1782             fprintf(stderr, "wiping cache...\n");
   1783             fb_queue_erase("cache");
   1784             fb_perform_format(transport, "cache", 1, nullptr, nullptr, "");
   1785         }
   1786     }
   1787     if (wants_set_active) {
   1788         fb_set_active(next_active.c_str());
   1789     }
   1790     if (wants_reboot) {
   1791         fb_queue_reboot();
   1792         fb_queue_wait_for_disconnect();
   1793     } else if (wants_reboot_bootloader) {
   1794         fb_queue_command("reboot-bootloader", "rebooting into bootloader");
   1795         fb_queue_wait_for_disconnect();
   1796     }
   1797 
   1798     return fb_execute_queue(transport) ? EXIT_FAILURE : EXIT_SUCCESS;
   1799 }
   1800