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 <chrono>
     47 #include <functional>
     48 #include <thread>
     49 #include <utility>
     50 #include <vector>
     51 
     52 #include <android-base/file.h>
     53 #include <android-base/macros.h>
     54 #include <android-base/parseint.h>
     55 #include <android-base/parsenetaddress.h>
     56 #include <android-base/stringprintf.h>
     57 #include <android-base/strings.h>
     58 #include <sparse/sparse.h>
     59 #include <ziparchive/zip_archive.h>
     60 
     61 #include "bootimg_utils.h"
     62 #include "diagnose_usb.h"
     63 #include "fastboot.h"
     64 #include "fs.h"
     65 #include "tcp.h"
     66 #include "transport.h"
     67 #include "udp.h"
     68 #include "usb.h"
     69 
     70 #ifndef O_BINARY
     71 #define O_BINARY 0
     72 #endif
     73 
     74 char cur_product[FB_RESPONSE_SZ + 1];
     75 
     76 static const char* serial = nullptr;
     77 static const char* product = nullptr;
     78 static const char* cmdline = nullptr;
     79 static unsigned short vendor_id = 0;
     80 static int long_listing = 0;
     81 static int64_t sparse_limit = -1;
     82 static int64_t target_sparse_limit = -1;
     83 
     84 static unsigned page_size = 2048;
     85 static unsigned base_addr      = 0x10000000;
     86 static unsigned kernel_offset  = 0x00008000;
     87 static unsigned ramdisk_offset = 0x01000000;
     88 static unsigned second_offset  = 0x00f00000;
     89 static unsigned tags_offset    = 0x00000100;
     90 
     91 static const std::string convert_fbe_marker_filename("convert_fbe");
     92 
     93 enum fb_buffer_type {
     94     FB_BUFFER,
     95     FB_BUFFER_SPARSE,
     96 };
     97 
     98 struct fastboot_buffer {
     99     enum fb_buffer_type type;
    100     void* data;
    101     int64_t sz;
    102 };
    103 
    104 static struct {
    105     char img_name[17];
    106     char sig_name[17];
    107     char part_name[9];
    108     bool is_optional;
    109     bool is_secondary;
    110 } images[] = {
    111     {"boot.img", "boot.sig", "boot", false, false},
    112     {"boot_other.img", "boot.sig", "boot", true, true},
    113     {"recovery.img", "recovery.sig", "recovery", true, false},
    114     {"system.img", "system.sig", "system", false, false},
    115     {"system_other.img", "system.sig", "system", true, true},
    116     {"vendor.img", "vendor.sig", "vendor", true, false},
    117     {"vendor_other.img", "vendor.sig", "vendor", true, true},
    118 };
    119 
    120 static std::string find_item_given_name(const char* img_name, const char* product) {
    121     if(product) {
    122         std::string path = android::base::GetExecutablePath();
    123         path.erase(path.find_last_of('/'));
    124         return android::base::StringPrintf("%s/../../../target/product/%s/%s",
    125                                            path.c_str(), product, img_name);
    126     }
    127 
    128     char *dir = getenv("ANDROID_PRODUCT_OUT");
    129     if (dir == nullptr || dir[0] == '\0') {
    130         die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
    131     }
    132 
    133     return android::base::StringPrintf("%s/%s", dir, img_name);
    134 }
    135 
    136 std::string find_item(const char* item, const char* product) {
    137     const char *fn;
    138 
    139     if (!strcmp(item,"boot")) {
    140         fn = "boot.img";
    141     } else if(!strcmp(item,"recovery")) {
    142         fn = "recovery.img";
    143     } else if(!strcmp(item,"system")) {
    144         fn = "system.img";
    145     } else if(!strcmp(item,"vendor")) {
    146         fn = "vendor.img";
    147     } else if(!strcmp(item,"userdata")) {
    148         fn = "userdata.img";
    149     } else if(!strcmp(item,"cache")) {
    150         fn = "cache.img";
    151     } else if(!strcmp(item,"info")) {
    152         fn = "android-info.txt";
    153     } else {
    154         fprintf(stderr,"unknown partition '%s'\n", item);
    155         return "";
    156     }
    157 
    158     return find_item_given_name(fn, product);
    159 }
    160 
    161 static int64_t get_file_size(int fd) {
    162     struct stat sb;
    163     return fstat(fd, &sb) == -1 ? -1 : sb.st_size;
    164 }
    165 
    166 static void* load_fd(int fd, int64_t* sz) {
    167     int errno_tmp;
    168     char* data = nullptr;
    169 
    170     *sz = get_file_size(fd);
    171     if (*sz < 0) {
    172         goto oops;
    173     }
    174 
    175     data = (char*) malloc(*sz);
    176     if (data == nullptr) goto oops;
    177 
    178     if(read(fd, data, *sz) != *sz) goto oops;
    179     close(fd);
    180 
    181     return data;
    182 
    183 oops:
    184     errno_tmp = errno;
    185     close(fd);
    186     if(data != 0) free(data);
    187     errno = errno_tmp;
    188     return 0;
    189 }
    190 
    191 static void* load_file(const std::string& path, int64_t* sz) {
    192     int fd = open(path.c_str(), O_RDONLY | O_BINARY);
    193     if (fd == -1) return nullptr;
    194     return load_fd(fd, sz);
    195 }
    196 
    197 static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) {
    198     // Require a matching vendor id if the user specified one with -i.
    199     if (vendor_id != 0 && info->dev_vendor != vendor_id) {
    200         return -1;
    201     }
    202 
    203     if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) {
    204         return -1;
    205     }
    206 
    207     // require matching serial number or device path if requested
    208     // at the command line with the -s option.
    209     if (local_serial && (strcmp(local_serial, info->serial_number) != 0 &&
    210                    strcmp(local_serial, info->device_path) != 0)) return -1;
    211     return 0;
    212 }
    213 
    214 static int match_fastboot(usb_ifc_info* info) {
    215     return match_fastboot_with_serial(info, serial);
    216 }
    217 
    218 static int list_devices_callback(usb_ifc_info* info) {
    219     if (match_fastboot_with_serial(info, nullptr) == 0) {
    220         std::string serial = info->serial_number;
    221         if (!info->writable) {
    222             serial = UsbNoPermissionsShortHelpText();
    223         }
    224         if (!serial[0]) {
    225             serial = "????????????";
    226         }
    227         // output compatible with "adb devices"
    228         if (!long_listing) {
    229             printf("%s\tfastboot", serial.c_str());
    230         } else {
    231             printf("%-22s fastboot", serial.c_str());
    232             if (strlen(info->device_path) > 0) printf(" %s", info->device_path);
    233         }
    234         putchar('\n');
    235     }
    236 
    237     return -1;
    238 }
    239 
    240 // Opens a new Transport connected to a device. If |serial| is non-null it will be used to identify
    241 // a specific device, otherwise the first USB device found will be used.
    242 //
    243 // If |serial| is non-null but invalid, this prints an error message to stderr and returns nullptr.
    244 // Otherwise it blocks until the target is available.
    245 //
    246 // The returned Transport is a singleton, so multiple calls to this function will return the same
    247 // object, and the caller should not attempt to delete the returned Transport.
    248 static Transport* open_device() {
    249     static Transport* transport = nullptr;
    250     bool announce = true;
    251 
    252     if (transport != nullptr) {
    253         return transport;
    254     }
    255 
    256     Socket::Protocol protocol = Socket::Protocol::kTcp;
    257     std::string host;
    258     int port = 0;
    259     if (serial != nullptr) {
    260         const char* net_address = nullptr;
    261 
    262         if (android::base::StartsWith(serial, "tcp:")) {
    263             protocol = Socket::Protocol::kTcp;
    264             port = tcp::kDefaultPort;
    265             net_address = serial + strlen("tcp:");
    266         } else if (android::base::StartsWith(serial, "udp:")) {
    267             protocol = Socket::Protocol::kUdp;
    268             port = udp::kDefaultPort;
    269             net_address = serial + strlen("udp:");
    270         }
    271 
    272         if (net_address != nullptr) {
    273             std::string error;
    274             if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) {
    275                 fprintf(stderr, "error: Invalid network address '%s': %s\n", net_address,
    276                         error.c_str());
    277                 return nullptr;
    278             }
    279         }
    280     }
    281 
    282     while (true) {
    283         if (!host.empty()) {
    284             std::string error;
    285             if (protocol == Socket::Protocol::kTcp) {
    286                 transport = tcp::Connect(host, port, &error).release();
    287             } else if (protocol == Socket::Protocol::kUdp) {
    288                 transport = udp::Connect(host, port, &error).release();
    289             }
    290 
    291             if (transport == nullptr && announce) {
    292                 fprintf(stderr, "error: %s\n", error.c_str());
    293             }
    294         } else {
    295             transport = usb_open(match_fastboot);
    296         }
    297 
    298         if (transport != nullptr) {
    299             return transport;
    300         }
    301 
    302         if (announce) {
    303             announce = false;
    304             fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device");
    305         }
    306         std::this_thread::sleep_for(std::chrono::milliseconds(1));
    307     }
    308 }
    309 
    310 static void list_devices() {
    311     // We don't actually open a USB device here,
    312     // just getting our callback called so we can
    313     // list all the connected devices.
    314     usb_open(list_devices_callback);
    315 }
    316 
    317 static void usage() {
    318     fprintf(stderr,
    319 /*           1234567890123456789012345678901234567890123456789012345678901234567890123456 */
    320             "usage: fastboot [ <option> ] <command>\n"
    321             "\n"
    322             "commands:\n"
    323             "  update <filename>                        Reflash device from update.zip.\n"
    324             "                                           Sets the flashed slot as active.\n"
    325             "  flashall                                 Flash boot, system, vendor, and --\n"
    326             "                                           if found -- recovery. If the device\n"
    327             "                                           supports slots, the slot that has\n"
    328             "                                           been flashed to is set as active.\n"
    329             "                                           Secondary images may be flashed to\n"
    330             "                                           an inactive slot.\n"
    331             "  flash <partition> [ <filename> ]         Write a file to a flash partition.\n"
    332             "  flashing lock                            Locks the device. Prevents flashing.\n"
    333             "  flashing unlock                          Unlocks the device. Allows flashing\n"
    334             "                                           any partition except\n"
    335             "                                           bootloader-related partitions.\n"
    336             "  flashing lock_critical                   Prevents flashing bootloader-related\n"
    337             "                                           partitions.\n"
    338             "  flashing unlock_critical                 Enables flashing bootloader-related\n"
    339             "                                           partitions.\n"
    340             "  flashing get_unlock_ability              Queries bootloader to see if the\n"
    341             "                                           device is unlocked.\n"
    342             "  flashing get_unlock_bootloader_nonce     Queries the bootloader to get the\n"
    343             "                                           unlock nonce.\n"
    344             "  flashing unlock_bootloader <request>     Issue unlock bootloader using request.\n"
    345             "  flashing lock_bootloader                 Locks the bootloader to prevent\n"
    346             "                                           bootloader version rollback.\n"
    347             "  erase <partition>                        Erase a flash partition.\n"
    348             "  format[:[<fs type>][:[<size>]] <partition>\n"
    349             "                                           Format a flash partition. Can\n"
    350             "                                           override the fs type and/or size\n"
    351             "                                           the bootloader reports.\n"
    352             "  getvar <variable>                        Display a bootloader variable.\n"
    353             "  set_active <slot>                        Sets the active slot. If slots are\n"
    354             "                                           not supported, this does nothing.\n"
    355             "  boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
    356             "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
    357             "                                           Create bootimage and flash it.\n"
    358             "  devices [-l]                             List all connected devices [with\n"
    359             "                                           device paths].\n"
    360             "  continue                                 Continue with autoboot.\n"
    361             "  reboot [bootloader|emergency]            Reboot device [into bootloader or emergency mode].\n"
    362             "  reboot-bootloader                        Reboot device into bootloader.\n"
    363             "  help                                     Show this help message.\n"
    364             "\n"
    365             "options:\n"
    366             "  -w                                       Erase userdata and cache (and format\n"
    367             "                                           if supported by partition type).\n"
    368             "  -u                                       Do not erase partition before\n"
    369             "                                           formatting.\n"
    370             "  -s <specific device>                     Specify a device. For USB, provide either\n"
    371             "                                           a serial number or path to device port.\n"
    372             "                                           For ethernet, provide an address in the\n"
    373             "                                           form <protocol>:<hostname>[:port] where\n"
    374             "                                           <protocol> is either tcp or udp.\n"
    375             "  -p <product>                             Specify product name.\n"
    376             "  -c <cmdline>                             Override kernel commandline.\n"
    377             "  -i <vendor id>                           Specify a custom USB vendor id.\n"
    378             "  -b, --base <base_addr>                   Specify a custom kernel base\n"
    379             "                                           address (default: 0x10000000).\n"
    380             "  --kernel-offset                          Specify a custom kernel offset.\n"
    381             "                                           (default: 0x00008000)\n"
    382             "  --ramdisk-offset                         Specify a custom ramdisk offset.\n"
    383             "                                           (default: 0x01000000)\n"
    384             "  --tags-offset                            Specify a custom tags offset.\n"
    385             "                                           (default: 0x00000100)\n"
    386             "  -n, --page-size <page size>              Specify the nand page size\n"
    387             "                                           (default: 2048).\n"
    388             "  -S <size>[K|M|G]                         Automatically sparse files greater\n"
    389             "                                           than 'size'. 0 to disable.\n"
    390             "  --slot <slot>                            Specify slot name to be used if the\n"
    391             "                                           device supports slots. All operations\n"
    392             "                                           on partitions that support slots will\n"
    393             "                                           be done on the slot specified.\n"
    394             "                                           'all' can be given to refer to all slots.\n"
    395             "                                           'other' can be given to refer to a\n"
    396             "                                           non-current slot. If this flag is not\n"
    397             "                                           used, slotted partitions will default\n"
    398             "                                           to the current active slot.\n"
    399             "  -a, --set-active[=<slot>]                Sets the active slot. If no slot is\n"
    400             "                                           provided, this will default to the value\n"
    401             "                                           given by --slot. If slots are not\n"
    402             "                                           supported, this does nothing. This will\n"
    403             "                                           run after all non-reboot commands.\n"
    404             "  --skip-secondary                         Will not flash secondary slots when\n"
    405             "                                           performing a flashall or update. This\n"
    406             "                                           will preserve data on other slots.\n"
    407             "  --skip-reboot                            Will not reboot the device when\n"
    408             "                                           performing commands that normally\n"
    409             "                                           trigger a reboot.\n"
    410 #if !defined(_WIN32)
    411             "  --wipe-and-use-fbe                       On devices which support it,\n"
    412             "                                           erase userdata and cache, and\n"
    413             "                                           enable file-based encryption\n"
    414 #endif
    415             "  --unbuffered                             Do not buffer input or output.\n"
    416             "  --version                                Display version.\n"
    417             "  -h, --help                               show this message.\n"
    418         );
    419 }
    420 
    421 static void* load_bootable_image(const char* kernel, const char* ramdisk,
    422                                  const char* secondstage, int64_t* sz,
    423                                  const char* cmdline) {
    424     if (kernel == nullptr) {
    425         fprintf(stderr, "no image specified\n");
    426         return 0;
    427     }
    428 
    429     int64_t ksize;
    430     void* kdata = load_file(kernel, &ksize);
    431     if (kdata == nullptr) {
    432         fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno));
    433         return 0;
    434     }
    435 
    436     // Is this actually a boot image?
    437     if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
    438         if (cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline);
    439 
    440         if (ramdisk) {
    441             fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n");
    442             return 0;
    443         }
    444 
    445         *sz = ksize;
    446         return kdata;
    447     }
    448 
    449     void* rdata = nullptr;
    450     int64_t rsize = 0;
    451     if (ramdisk) {
    452         rdata = load_file(ramdisk, &rsize);
    453         if (rdata == nullptr) {
    454             fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno));
    455             return  0;
    456         }
    457     }
    458 
    459     void* sdata = nullptr;
    460     int64_t ssize = 0;
    461     if (secondstage) {
    462         sdata = load_file(secondstage, &ssize);
    463         if (sdata == nullptr) {
    464             fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno));
    465             return  0;
    466         }
    467     }
    468 
    469     fprintf(stderr,"creating boot image...\n");
    470     int64_t bsize = 0;
    471     void* bdata = mkbootimg(kdata, ksize, kernel_offset,
    472                       rdata, rsize, ramdisk_offset,
    473                       sdata, ssize, second_offset,
    474                       page_size, base_addr, tags_offset, &bsize);
    475     if (bdata == nullptr) {
    476         fprintf(stderr,"failed to create boot.img\n");
    477         return 0;
    478     }
    479     if (cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline);
    480     fprintf(stderr, "creating boot image - %" PRId64 " bytes\n", bsize);
    481     *sz = bsize;
    482 
    483     return bdata;
    484 }
    485 
    486 static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz)
    487 {
    488     ZipString zip_entry_name(entry_name);
    489     ZipEntry zip_entry;
    490     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
    491         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
    492         return 0;
    493     }
    494 
    495     *sz = zip_entry.uncompressed_length;
    496 
    497     uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length));
    498     if (data == nullptr) {
    499         fprintf(stderr, "failed to allocate %" PRId64 " bytes for '%s'\n", *sz, entry_name);
    500         return 0;
    501     }
    502 
    503     int error = ExtractToMemory(zip, &zip_entry, data, zip_entry.uncompressed_length);
    504     if (error != 0) {
    505         fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
    506         free(data);
    507         return 0;
    508     }
    509 
    510     return data;
    511 }
    512 
    513 #if defined(_WIN32)
    514 
    515 // TODO: move this to somewhere it can be shared.
    516 
    517 #include <windows.h>
    518 
    519 // Windows' tmpfile(3) requires administrator rights because
    520 // it creates temporary files in the root directory.
    521 static FILE* win32_tmpfile() {
    522     char temp_path[PATH_MAX];
    523     DWORD nchars = GetTempPath(sizeof(temp_path), temp_path);
    524     if (nchars == 0 || nchars >= sizeof(temp_path)) {
    525         fprintf(stderr, "GetTempPath failed, error %ld\n", GetLastError());
    526         return nullptr;
    527     }
    528 
    529     char filename[PATH_MAX];
    530     if (GetTempFileName(temp_path, "fastboot", 0, filename) == 0) {
    531         fprintf(stderr, "GetTempFileName failed, error %ld\n", GetLastError());
    532         return nullptr;
    533     }
    534 
    535     return fopen(filename, "w+bTD");
    536 }
    537 
    538 #define tmpfile win32_tmpfile
    539 
    540 static std::string make_temporary_directory() {
    541     fprintf(stderr, "make_temporary_directory not supported under Windows, sorry!");
    542     return "";
    543 }
    544 
    545 #else
    546 
    547 static std::string make_temporary_directory() {
    548     const char *tmpdir = getenv("TMPDIR");
    549     if (tmpdir == nullptr) {
    550         tmpdir = P_tmpdir;
    551     }
    552     std::string result = std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
    553     if (mkdtemp(&result[0]) == NULL) {
    554         fprintf(stderr, "Unable to create temporary directory: %s\n",
    555             strerror(errno));
    556         return "";
    557     }
    558     return result;
    559 }
    560 
    561 #endif
    562 
    563 static std::string create_fbemarker_tmpdir() {
    564     std::string dir = make_temporary_directory();
    565     if (dir.empty()) {
    566         fprintf(stderr, "Unable to create local temp directory for FBE marker\n");
    567         return "";
    568     }
    569     std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    570     int fd = open(marker_file.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0666);
    571     if (fd == -1) {
    572         fprintf(stderr, "Unable to create FBE marker file %s locally: %d, %s\n",
    573             marker_file.c_str(), errno, strerror(errno));
    574         return "";
    575     }
    576     close(fd);
    577     return dir;
    578 }
    579 
    580 static void delete_fbemarker_tmpdir(const std::string& dir) {
    581     std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    582     if (unlink(marker_file.c_str()) == -1) {
    583         fprintf(stderr, "Unable to delete FBE marker file %s locally: %d, %s\n",
    584             marker_file.c_str(), errno, strerror(errno));
    585         return;
    586     }
    587     if (rmdir(dir.c_str()) == -1) {
    588         fprintf(stderr, "Unable to delete FBE marker directory %s locally: %d, %s\n",
    589             dir.c_str(), errno, strerror(errno));
    590         return;
    591     }
    592 }
    593 
    594 static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) {
    595     FILE* fp = tmpfile();
    596     if (fp == nullptr) {
    597         fprintf(stderr, "failed to create temporary file for '%s': %s\n",
    598                 entry_name, strerror(errno));
    599         return -1;
    600     }
    601 
    602     ZipString zip_entry_name(entry_name);
    603     ZipEntry zip_entry;
    604     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
    605         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
    606         fclose(fp);
    607         return -1;
    608     }
    609 
    610     int fd = fileno(fp);
    611     int error = ExtractEntryToFile(zip, &zip_entry, fd);
    612     if (error != 0) {
    613         fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
    614         fclose(fp);
    615         return -1;
    616     }
    617 
    618     lseek(fd, 0, SEEK_SET);
    619     // TODO: We're leaking 'fp' here.
    620     return fd;
    621 }
    622 
    623 static char *strip(char *s)
    624 {
    625     int n;
    626     while(*s && isspace(*s)) s++;
    627     n = strlen(s);
    628     while(n-- > 0) {
    629         if(!isspace(s[n])) break;
    630         s[n] = 0;
    631     }
    632     return s;
    633 }
    634 
    635 #define MAX_OPTIONS 32
    636 static int setup_requirement_line(char *name)
    637 {
    638     char *val[MAX_OPTIONS];
    639     char *prod = nullptr;
    640     unsigned n, count;
    641     char *x;
    642     int invert = 0;
    643 
    644     if (!strncmp(name, "reject ", 7)) {
    645         name += 7;
    646         invert = 1;
    647     } else if (!strncmp(name, "require ", 8)) {
    648         name += 8;
    649         invert = 0;
    650     } else if (!strncmp(name, "require-for-product:", 20)) {
    651         // Get the product and point name past it
    652         prod = name + 20;
    653         name = strchr(name, ' ');
    654         if (!name) return -1;
    655         *name = 0;
    656         name += 1;
    657         invert = 0;
    658     }
    659 
    660     x = strchr(name, '=');
    661     if (x == 0) return 0;
    662     *x = 0;
    663     val[0] = x + 1;
    664 
    665     for(count = 1; count < MAX_OPTIONS; count++) {
    666         x = strchr(val[count - 1],'|');
    667         if (x == 0) break;
    668         *x = 0;
    669         val[count] = x + 1;
    670     }
    671 
    672     name = strip(name);
    673     for(n = 0; n < count; n++) val[n] = strip(val[n]);
    674 
    675     name = strip(name);
    676     if (name == 0) return -1;
    677 
    678     const char* var = name;
    679     // Work around an unfortunate name mismatch.
    680     if (!strcmp(name,"board")) var = "product";
    681 
    682     const char** out = reinterpret_cast<const char**>(malloc(sizeof(char*) * count));
    683     if (out == 0) return -1;
    684 
    685     for(n = 0; n < count; n++) {
    686         out[n] = strdup(strip(val[n]));
    687         if (out[n] == 0) {
    688             for(size_t i = 0; i < n; ++i) {
    689                 free((char*) out[i]);
    690             }
    691             free(out);
    692             return -1;
    693         }
    694     }
    695 
    696     fb_queue_require(prod, var, invert, n, out);
    697     return 0;
    698 }
    699 
    700 static void setup_requirements(char* data, int64_t sz) {
    701     char* s = data;
    702     while (sz-- > 0) {
    703         if (*s == '\n') {
    704             *s++ = 0;
    705             if (setup_requirement_line(data)) {
    706                 die("out of memory");
    707             }
    708             data = s;
    709         } else {
    710             s++;
    711         }
    712     }
    713 }
    714 
    715 static void queue_info_dump() {
    716     fb_queue_notice("--------------------------------------------");
    717     fb_queue_display("version-bootloader", "Bootloader Version...");
    718     fb_queue_display("version-baseband",   "Baseband Version.....");
    719     fb_queue_display("serialno",           "Serial Number........");
    720     fb_queue_notice("--------------------------------------------");
    721 }
    722 
    723 static struct sparse_file **load_sparse_files(int fd, int max_size)
    724 {
    725     struct sparse_file* s = sparse_file_import_auto(fd, false, true);
    726     if (!s) {
    727         die("cannot sparse read file\n");
    728     }
    729 
    730     int files = sparse_file_resparse(s, max_size, nullptr, 0);
    731     if (files < 0) {
    732         die("Failed to resparse\n");
    733     }
    734 
    735     sparse_file** out_s = reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file *), files + 1));
    736     if (!out_s) {
    737         die("Failed to allocate sparse file array\n");
    738     }
    739 
    740     files = sparse_file_resparse(s, max_size, out_s, files);
    741     if (files < 0) {
    742         die("Failed to resparse\n");
    743     }
    744 
    745     return out_s;
    746 }
    747 
    748 static int64_t get_target_sparse_limit(Transport* transport) {
    749     std::string max_download_size;
    750     if (!fb_getvar(transport, "max-download-size", &max_download_size) ||
    751             max_download_size.empty()) {
    752         fprintf(stderr, "target didn't report max-download-size\n");
    753         return 0;
    754     }
    755 
    756     // Some bootloaders (angler, for example) send spurious whitespace too.
    757     max_download_size = android::base::Trim(max_download_size);
    758 
    759     uint64_t limit;
    760     if (!android::base::ParseUint(max_download_size, &limit)) {
    761         fprintf(stderr, "couldn't parse max-download-size '%s'\n", max_download_size.c_str());
    762         return 0;
    763     }
    764     if (limit > 0) {
    765         fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit);
    766     }
    767     return limit;
    768 }
    769 
    770 static int64_t get_sparse_limit(Transport* transport, int64_t size) {
    771     int64_t limit;
    772 
    773     if (sparse_limit == 0) {
    774         return 0;
    775     } else if (sparse_limit > 0) {
    776         limit = sparse_limit;
    777     } else {
    778         if (target_sparse_limit == -1) {
    779             target_sparse_limit = get_target_sparse_limit(transport);
    780         }
    781         if (target_sparse_limit > 0) {
    782             limit = target_sparse_limit;
    783         } else {
    784             return 0;
    785         }
    786     }
    787 
    788     if (size > limit) {
    789         return limit;
    790     }
    791 
    792     return 0;
    793 }
    794 
    795 // Until we get lazy inode table init working in make_ext4fs, we need to
    796 // erase partitions of type ext4 before flashing a filesystem so no stale
    797 // inodes are left lying around.  Otherwise, e2fsck gets very upset.
    798 static bool needs_erase(Transport* transport, const char* partition) {
    799     std::string partition_type;
    800     if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
    801         return false;
    802     }
    803     return partition_type == "ext4";
    804 }
    805 
    806 static bool load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf) {
    807     int64_t sz = get_file_size(fd);
    808     if (sz == -1) {
    809         return false;
    810     }
    811 
    812     lseek64(fd, 0, SEEK_SET);
    813     int64_t limit = get_sparse_limit(transport, sz);
    814     if (limit) {
    815         sparse_file** s = load_sparse_files(fd, limit);
    816         if (s == nullptr) {
    817             return false;
    818         }
    819         buf->type = FB_BUFFER_SPARSE;
    820         buf->data = s;
    821     } else {
    822         void* data = load_fd(fd, &sz);
    823         if (data == nullptr) return -1;
    824         buf->type = FB_BUFFER;
    825         buf->data = data;
    826         buf->sz = sz;
    827     }
    828 
    829     return true;
    830 }
    831 
    832 static bool load_buf(Transport* transport, const char* fname, struct fastboot_buffer* buf) {
    833     int fd = open(fname, O_RDONLY | O_BINARY);
    834     if (fd == -1) {
    835         return false;
    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, &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                              const 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                               const 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': %s", fname, strerror(errno));
   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 < arraysize(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         if (!load_buf_fd(transport, fd, &buf)) {
   1124             die("cannot load %s from flash: %s", images[i].img_name, strerror(errno));
   1125         }
   1126 
   1127         auto update = [&](const std::string &partition) {
   1128             do_update_signature(zip, images[i].sig_name);
   1129             if (erase_first && needs_erase(transport, partition.c_str())) {
   1130                 fb_queue_erase(partition.c_str());
   1131             }
   1132             flash_buf(partition.c_str(), &buf);
   1133             /* not closing the fd here since the sparse code keeps the fd around
   1134              * but hasn't mmaped data yet. The tmpfile will get cleaned up when the
   1135              * program exits.
   1136              */
   1137         };
   1138         do_for_partitions(transport, images[i].part_name, slot, update, false);
   1139     }
   1140 
   1141     CloseArchive(zip);
   1142     if (slot_override == "all") {
   1143         set_active(transport, "a");
   1144     } else {
   1145         set_active(transport, slot_override);
   1146     }
   1147 }
   1148 
   1149 static void do_send_signature(const std::string& fn) {
   1150     std::size_t extension_loc = fn.find(".img");
   1151     if (extension_loc == std::string::npos) return;
   1152 
   1153     std::string fs_sig = fn.substr(0, extension_loc) + ".sig";
   1154 
   1155     int64_t sz;
   1156     void* data = load_file(fs_sig.c_str(), &sz);
   1157     if (data == nullptr) return;
   1158 
   1159     fb_queue_download("signature", data, sz);
   1160     fb_queue_command("signature", "installing signature");
   1161 }
   1162 
   1163 static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool skip_secondary) {
   1164     std::string fname;
   1165     queue_info_dump();
   1166 
   1167     fb_queue_query_save("product", cur_product, sizeof(cur_product));
   1168 
   1169     fname = find_item("info", product);
   1170     if (fname.empty()) die("cannot find android-info.txt");
   1171 
   1172     int64_t sz;
   1173     void* data = load_file(fname.c_str(), &sz);
   1174     if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno));
   1175 
   1176     setup_requirements(reinterpret_cast<char*>(data), sz);
   1177 
   1178     std::string secondary;
   1179     if (!skip_secondary) {
   1180         if (slot_override != "") {
   1181             secondary = get_other_slot(transport, slot_override);
   1182         } else {
   1183             secondary = get_other_slot(transport);
   1184         }
   1185         if (secondary == "") {
   1186             if (supports_AB(transport)) {
   1187                 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
   1188             }
   1189             skip_secondary = true;
   1190         }
   1191     }
   1192 
   1193     for (size_t i = 0; i < arraysize(images); i++) {
   1194         const char* slot = NULL;
   1195         if (images[i].is_secondary) {
   1196             if (!skip_secondary) slot = secondary.c_str();
   1197         } else {
   1198             slot = slot_override.c_str();
   1199         }
   1200         if (!slot) continue;
   1201         fname = find_item_given_name(images[i].img_name, product);
   1202         fastboot_buffer buf;
   1203         if (!load_buf(transport, fname.c_str(), &buf)) {
   1204             if (images[i].is_optional) continue;
   1205             die("could not load '%s': %s\n", images[i].img_name, strerror(errno));
   1206         }
   1207 
   1208         auto flashall = [&](const std::string &partition) {
   1209             do_send_signature(fname.c_str());
   1210             if (erase_first && needs_erase(transport, partition.c_str())) {
   1211                 fb_queue_erase(partition.c_str());
   1212             }
   1213             flash_buf(partition.c_str(), &buf);
   1214         };
   1215         do_for_partitions(transport, images[i].part_name, slot, flashall, false);
   1216     }
   1217 
   1218     if (slot_override == "all") {
   1219         set_active(transport, "a");
   1220     } else {
   1221         set_active(transport, slot_override);
   1222     }
   1223 }
   1224 
   1225 #define skip(n) do { argc -= (n); argv += (n); } while (0)
   1226 #define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0)
   1227 
   1228 static int do_bypass_unlock_command(int argc, char **argv)
   1229 {
   1230     if (argc <= 2) return 0;
   1231     skip(2);
   1232 
   1233     /*
   1234      * Process unlock_bootloader, we have to load the message file
   1235      * and send that to the remote device.
   1236      */
   1237     require(1);
   1238 
   1239     int64_t sz;
   1240     void* data = load_file(*argv, &sz);
   1241     if (data == nullptr) die("could not load '%s': %s", *argv, strerror(errno));
   1242     fb_queue_download("unlock_message", data, sz);
   1243     fb_queue_command("flashing unlock_bootloader", "unlocking bootloader");
   1244     skip(1);
   1245     return 0;
   1246 }
   1247 
   1248 static int do_oem_command(int argc, char** argv) {
   1249     if (argc <= 1) return 0;
   1250 
   1251     std::string command;
   1252     while (argc > 0) {
   1253         command += *argv;
   1254         skip(1);
   1255         if (argc != 0) command += " ";
   1256     }
   1257 
   1258     fb_queue_command(command.c_str(), "");
   1259     return 0;
   1260 }
   1261 
   1262 static int64_t parse_num(const char *arg)
   1263 {
   1264     char *endptr;
   1265     unsigned long long num;
   1266 
   1267     num = strtoull(arg, &endptr, 0);
   1268     if (endptr == arg) {
   1269         return -1;
   1270     }
   1271 
   1272     if (*endptr == 'k' || *endptr == 'K') {
   1273         if (num >= (-1ULL) / 1024) {
   1274             return -1;
   1275         }
   1276         num *= 1024LL;
   1277         endptr++;
   1278     } else if (*endptr == 'm' || *endptr == 'M') {
   1279         if (num >= (-1ULL) / (1024 * 1024)) {
   1280             return -1;
   1281         }
   1282         num *= 1024LL * 1024LL;
   1283         endptr++;
   1284     } else if (*endptr == 'g' || *endptr == 'G') {
   1285         if (num >= (-1ULL) / (1024 * 1024 * 1024)) {
   1286             return -1;
   1287         }
   1288         num *= 1024LL * 1024LL * 1024LL;
   1289         endptr++;
   1290     }
   1291 
   1292     if (*endptr != '\0') {
   1293         return -1;
   1294     }
   1295 
   1296     if (num > INT64_MAX) {
   1297         return -1;
   1298     }
   1299 
   1300     return num;
   1301 }
   1302 
   1303 static std::string fb_fix_numeric_var(std::string var) {
   1304     // Some bootloaders (angler, for example), send spurious leading whitespace.
   1305     var = android::base::Trim(var);
   1306     // Some bootloaders (hammerhead, for example) use implicit hex.
   1307     // This code used to use strtol with base 16.
   1308     if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
   1309     return var;
   1310 }
   1311 
   1312 static unsigned fb_get_flash_block_size(Transport* transport, std::string name) {
   1313     std::string sizeString;
   1314     if (!fb_getvar(transport, name.c_str(), &sizeString)) {
   1315         /* This device does not report flash block sizes, so return 0 */
   1316         return 0;
   1317     }
   1318     sizeString = fb_fix_numeric_var(sizeString);
   1319 
   1320     unsigned size;
   1321     if (!android::base::ParseUint(sizeString, &size)) {
   1322         fprintf(stderr, "Couldn't parse %s '%s'.\n", name.c_str(), sizeString.c_str());
   1323         return 0;
   1324     }
   1325     if (size < 4096 || (size & (size - 1)) != 0) {
   1326         fprintf(stderr, "Invalid %s %u: must be a power of 2 and at least 4096.\n",
   1327                 name.c_str(), size);
   1328         return 0;
   1329     }
   1330     return size;
   1331 }
   1332 
   1333 static void fb_perform_format(Transport* transport,
   1334                               const char* partition, int skip_if_not_supported,
   1335                               const char* type_override, const char* size_override,
   1336                               const std::string& initial_dir) {
   1337     std::string partition_type, partition_size;
   1338 
   1339     struct fastboot_buffer buf;
   1340     const char* errMsg = nullptr;
   1341     const struct fs_generator* gen = nullptr;
   1342     int fd;
   1343 
   1344     unsigned int limit = INT_MAX;
   1345     if (target_sparse_limit > 0 && target_sparse_limit < limit) {
   1346         limit = target_sparse_limit;
   1347     }
   1348     if (sparse_limit > 0 && sparse_limit < limit) {
   1349         limit = sparse_limit;
   1350     }
   1351 
   1352     if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
   1353         errMsg = "Can't determine partition type.\n";
   1354         goto failed;
   1355     }
   1356     if (type_override) {
   1357         if (partition_type != type_override) {
   1358             fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n",
   1359                     partition, partition_type.c_str(), type_override);
   1360         }
   1361         partition_type = type_override;
   1362     }
   1363 
   1364     if (!fb_getvar(transport, std::string("partition-size:") + partition, &partition_size)) {
   1365         errMsg = "Unable to get partition size\n";
   1366         goto failed;
   1367     }
   1368     if (size_override) {
   1369         if (partition_size != size_override) {
   1370             fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n",
   1371                     partition, partition_size.c_str(), size_override);
   1372         }
   1373         partition_size = size_override;
   1374     }
   1375     partition_size = fb_fix_numeric_var(partition_size);
   1376 
   1377     gen = fs_get_generator(partition_type);
   1378     if (!gen) {
   1379         if (skip_if_not_supported) {
   1380             fprintf(stderr, "Erase successful, but not automatically formatting.\n");
   1381             fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str());
   1382             return;
   1383         }
   1384         fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n",
   1385                 partition_type.c_str());
   1386         return;
   1387     }
   1388 
   1389     int64_t size;
   1390     if (!android::base::ParseInt(partition_size, &size)) {
   1391         fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str());
   1392         return;
   1393     }
   1394 
   1395     fd = fileno(tmpfile());
   1396 
   1397     unsigned eraseBlkSize, logicalBlkSize;
   1398     eraseBlkSize = fb_get_flash_block_size(transport, "erase-block-size");
   1399     logicalBlkSize = fb_get_flash_block_size(transport, "logical-block-size");
   1400 
   1401     if (fs_generator_generate(gen, fd, size, initial_dir, eraseBlkSize, logicalBlkSize)) {
   1402         fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
   1403         close(fd);
   1404         return;
   1405     }
   1406 
   1407     if (!load_buf_fd(transport, fd, &buf)) {
   1408         fprintf(stderr, "Cannot read image: %s\n", strerror(errno));
   1409         close(fd);
   1410         return;
   1411     }
   1412     flash_buf(partition, &buf);
   1413     return;
   1414 
   1415 failed:
   1416     if (skip_if_not_supported) {
   1417         fprintf(stderr, "Erase successful, but not automatically formatting.\n");
   1418         if (errMsg) fprintf(stderr, "%s", errMsg);
   1419     }
   1420     fprintf(stderr, "FAILED (%s)\n", fb_get_error().c_str());
   1421 }
   1422 
   1423 int main(int argc, char **argv)
   1424 {
   1425     bool wants_wipe = false;
   1426     bool wants_reboot = false;
   1427     bool wants_reboot_bootloader = false;
   1428     bool wants_reboot_emergency = false;
   1429     bool skip_reboot = false;
   1430     bool wants_set_active = false;
   1431     bool skip_secondary = false;
   1432     bool erase_first = true;
   1433     bool set_fbe_marker = false;
   1434     void *data;
   1435     int64_t sz;
   1436     int longindex;
   1437     std::string slot_override;
   1438     std::string next_active;
   1439 
   1440     const struct option longopts[] = {
   1441         {"base", required_argument, 0, 'b'},
   1442         {"kernel_offset", required_argument, 0, 'k'},
   1443         {"kernel-offset", required_argument, 0, 'k'},
   1444         {"page_size", required_argument, 0, 'n'},
   1445         {"page-size", required_argument, 0, 'n'},
   1446         {"ramdisk_offset", required_argument, 0, 'r'},
   1447         {"ramdisk-offset", required_argument, 0, 'r'},
   1448         {"tags_offset", required_argument, 0, 't'},
   1449         {"tags-offset", required_argument, 0, 't'},
   1450         {"help", no_argument, 0, 'h'},
   1451         {"unbuffered", no_argument, 0, 0},
   1452         {"version", no_argument, 0, 0},
   1453         {"slot", required_argument, 0, 0},
   1454         {"set_active", optional_argument, 0, 'a'},
   1455         {"set-active", optional_argument, 0, 'a'},
   1456         {"skip-secondary", no_argument, 0, 0},
   1457         {"skip-reboot", no_argument, 0, 0},
   1458 #if !defined(_WIN32)
   1459         {"wipe-and-use-fbe", no_argument, 0, 0},
   1460 #endif
   1461         {0, 0, 0, 0}
   1462     };
   1463 
   1464     serial = getenv("ANDROID_SERIAL");
   1465 
   1466     while (1) {
   1467         int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:ha::", longopts, &longindex);
   1468         if (c < 0) {
   1469             break;
   1470         }
   1471         /* Alphabetical cases */
   1472         switch (c) {
   1473         case 'a':
   1474             wants_set_active = true;
   1475             if (optarg)
   1476                 next_active = optarg;
   1477             break;
   1478         case 'b':
   1479             base_addr = strtoul(optarg, 0, 16);
   1480             break;
   1481         case 'c':
   1482             cmdline = optarg;
   1483             break;
   1484         case 'h':
   1485             usage();
   1486             return 1;
   1487         case 'i': {
   1488                 char *endptr = nullptr;
   1489                 unsigned long val;
   1490 
   1491                 val = strtoul(optarg, &endptr, 0);
   1492                 if (!endptr || *endptr != '\0' || (val & ~0xffff))
   1493                     die("invalid vendor id '%s'", optarg);
   1494                 vendor_id = (unsigned short)val;
   1495                 break;
   1496             }
   1497         case 'k':
   1498             kernel_offset = strtoul(optarg, 0, 16);
   1499             break;
   1500         case 'l':
   1501             long_listing = 1;
   1502             break;
   1503         case 'n':
   1504             page_size = (unsigned)strtoul(optarg, nullptr, 0);
   1505             if (!page_size) die("invalid page size");
   1506             break;
   1507         case 'p':
   1508             product = optarg;
   1509             break;
   1510         case 'r':
   1511             ramdisk_offset = strtoul(optarg, 0, 16);
   1512             break;
   1513         case 't':
   1514             tags_offset = strtoul(optarg, 0, 16);
   1515             break;
   1516         case 's':
   1517             serial = optarg;
   1518             break;
   1519         case 'S':
   1520             sparse_limit = parse_num(optarg);
   1521             if (sparse_limit < 0) {
   1522                     die("invalid sparse limit");
   1523             }
   1524             break;
   1525         case 'u':
   1526             erase_first = false;
   1527             break;
   1528         case 'w':
   1529             wants_wipe = true;
   1530             break;
   1531         case '?':
   1532             return 1;
   1533         case 0:
   1534             if (strcmp("unbuffered", longopts[longindex].name) == 0) {
   1535                 setvbuf(stdout, nullptr, _IONBF, 0);
   1536                 setvbuf(stderr, nullptr, _IONBF, 0);
   1537             } else if (strcmp("version", longopts[longindex].name) == 0) {
   1538                 fprintf(stdout, "fastboot version %s\n", FASTBOOT_REVISION);
   1539                 return 0;
   1540             } else if (strcmp("slot", longopts[longindex].name) == 0) {
   1541                 slot_override = std::string(optarg);
   1542             } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
   1543                 skip_secondary = true;
   1544             } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) {
   1545                 skip_reboot = true;
   1546 #if !defined(_WIN32)
   1547             } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
   1548                 wants_wipe = true;
   1549                 set_fbe_marker = true;
   1550 #endif
   1551             } else {
   1552                 fprintf(stderr, "Internal error in options processing for %s\n",
   1553                     longopts[longindex].name);
   1554                 return 1;
   1555             }
   1556             break;
   1557         default:
   1558             abort();
   1559         }
   1560     }
   1561 
   1562     argc -= optind;
   1563     argv += optind;
   1564 
   1565     if (argc == 0 && !wants_wipe && !wants_set_active) {
   1566         usage();
   1567         return 1;
   1568     }
   1569 
   1570     if (argc > 0 && !strcmp(*argv, "devices")) {
   1571         skip(1);
   1572         list_devices();
   1573         return 0;
   1574     }
   1575 
   1576     if (argc > 0 && !strcmp(*argv, "help")) {
   1577         usage();
   1578         return 0;
   1579     }
   1580 
   1581     Transport* transport = open_device();
   1582     if (transport == nullptr) {
   1583         return 1;
   1584     }
   1585 
   1586     if (!supports_AB(transport) && supports_AB_obsolete(transport)) {
   1587         fprintf(stderr, "Warning: Device A/B support is outdated. Bootloader update required.\n");
   1588     }
   1589     if (slot_override != "") slot_override = verify_slot(transport, slot_override);
   1590     if (next_active != "") next_active = verify_slot(transport, next_active, false);
   1591 
   1592     if (wants_set_active) {
   1593         if (next_active == "") {
   1594             if (slot_override == "") {
   1595                 std::string current_slot;
   1596                 if (fb_getvar(transport, "current-slot", &current_slot)) {
   1597                     next_active = verify_slot(transport, current_slot, false);
   1598                 } else {
   1599                     wants_set_active = false;
   1600                 }
   1601             } else {
   1602                 next_active = verify_slot(transport, slot_override, false);
   1603             }
   1604         }
   1605     }
   1606 
   1607     while (argc > 0) {
   1608         if (!strcmp(*argv, "getvar")) {
   1609             require(2);
   1610             fb_queue_display(argv[1], argv[1]);
   1611             skip(2);
   1612         } else if(!strcmp(*argv, "erase")) {
   1613             require(2);
   1614 
   1615             auto erase = [&](const std::string &partition) {
   1616                 std::string partition_type;
   1617                 if (fb_getvar(transport, std::string("partition-type:") + argv[1], &partition_type) &&
   1618                     fs_get_generator(partition_type) != nullptr) {
   1619                     fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
   1620                             partition_type.c_str());
   1621                 }
   1622 
   1623                 fb_queue_erase(partition.c_str());
   1624             };
   1625             do_for_partitions(transport, argv[1], slot_override, erase, true);
   1626             skip(2);
   1627         } else if(!strncmp(*argv, "format", strlen("format"))) {
   1628             char *overrides;
   1629             char *type_override = nullptr;
   1630             char *size_override = nullptr;
   1631             require(2);
   1632             /*
   1633              * Parsing for: "format[:[type][:[size]]]"
   1634              * Some valid things:
   1635              *  - select ontly the size, and leave default fs type:
   1636              *    format::0x4000000 userdata
   1637              *  - default fs type and size:
   1638              *    format userdata
   1639              *    format:: userdata
   1640              */
   1641             overrides = strchr(*argv, ':');
   1642             if (overrides) {
   1643                 overrides++;
   1644                 size_override = strchr(overrides, ':');
   1645                 if (size_override) {
   1646                     size_override[0] = '\0';
   1647                     size_override++;
   1648                 }
   1649                 type_override = overrides;
   1650             }
   1651             if (type_override && !type_override[0]) type_override = nullptr;
   1652             if (size_override && !size_override[0]) size_override = nullptr;
   1653 
   1654             auto format = [&](const std::string &partition) {
   1655                 if (erase_first && needs_erase(transport, partition.c_str())) {
   1656                     fb_queue_erase(partition.c_str());
   1657                 }
   1658                 fb_perform_format(transport, partition.c_str(), 0,
   1659                     type_override, size_override, "");
   1660             };
   1661             do_for_partitions(transport, argv[1], slot_override, format, true);
   1662             skip(2);
   1663         } else if(!strcmp(*argv, "signature")) {
   1664             require(2);
   1665             data = load_file(argv[1], &sz);
   1666             if (data == nullptr) die("could not load '%s': %s", argv[1], strerror(errno));
   1667             if (sz != 256) die("signature must be 256 bytes");
   1668             fb_queue_download("signature", data, sz);
   1669             fb_queue_command("signature", "installing signature");
   1670             skip(2);
   1671         } else if(!strcmp(*argv, "reboot")) {
   1672             wants_reboot = true;
   1673             skip(1);
   1674             if (argc > 0) {
   1675                 if (!strcmp(*argv, "bootloader")) {
   1676                     wants_reboot = false;
   1677                     wants_reboot_bootloader = true;
   1678                     skip(1);
   1679                 } else if (!strcmp(*argv, "emergency")) {
   1680                     wants_reboot = false;
   1681                     wants_reboot_emergency = true;
   1682                     skip(1);
   1683                 }
   1684             }
   1685             require(0);
   1686         } else if(!strcmp(*argv, "reboot-bootloader")) {
   1687             wants_reboot_bootloader = true;
   1688             skip(1);
   1689         } else if (!strcmp(*argv, "continue")) {
   1690             fb_queue_command("continue", "resuming boot");
   1691             skip(1);
   1692         } else if(!strcmp(*argv, "boot")) {
   1693             char *kname = 0;
   1694             char *rname = 0;
   1695             char *sname = 0;
   1696             skip(1);
   1697             if (argc > 0) {
   1698                 kname = argv[0];
   1699                 skip(1);
   1700             }
   1701             if (argc > 0) {
   1702                 rname = argv[0];
   1703                 skip(1);
   1704             }
   1705             if (argc > 0) {
   1706                 sname = argv[0];
   1707                 skip(1);
   1708             }
   1709             data = load_bootable_image(kname, rname, sname, &sz, cmdline);
   1710             if (data == 0) return 1;
   1711             fb_queue_download("boot.img", data, sz);
   1712             fb_queue_command("boot", "booting");
   1713         } else if(!strcmp(*argv, "flash")) {
   1714             char* pname = argv[1];
   1715             std::string fname;
   1716             require(2);
   1717             if (argc > 2) {
   1718                 fname = argv[2];
   1719                 skip(3);
   1720             } else {
   1721                 fname = find_item(pname, product);
   1722                 skip(2);
   1723             }
   1724             if (fname.empty()) die("cannot determine image filename for '%s'", pname);
   1725 
   1726             auto flash = [&](const std::string &partition) {
   1727                 if (erase_first && needs_erase(transport, partition.c_str())) {
   1728                     fb_queue_erase(partition.c_str());
   1729                 }
   1730                 do_flash(transport, partition.c_str(), fname.c_str());
   1731             };
   1732             do_for_partitions(transport, pname, slot_override, flash, true);
   1733         } else if(!strcmp(*argv, "flash:raw")) {
   1734             char *kname = argv[2];
   1735             char *rname = 0;
   1736             char *sname = 0;
   1737             require(3);
   1738             skip(3);
   1739             if (argc > 0) {
   1740                 rname = argv[0];
   1741                 skip(1);
   1742             }
   1743             if (argc > 0) {
   1744                 sname = argv[0];
   1745                 skip(1);
   1746             }
   1747             data = load_bootable_image(kname, rname, sname, &sz, cmdline);
   1748             if (data == 0) die("cannot load bootable image");
   1749             auto flashraw = [&](const std::string &partition) {
   1750                 fb_queue_flash(partition.c_str(), data, sz);
   1751             };
   1752             do_for_partitions(transport, argv[1], slot_override, flashraw, true);
   1753         } else if(!strcmp(*argv, "flashall")) {
   1754             skip(1);
   1755             if (slot_override == "all") {
   1756                 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
   1757                 do_flashall(transport, slot_override, erase_first, true);
   1758             } else {
   1759                 do_flashall(transport, slot_override, erase_first, skip_secondary);
   1760             }
   1761             wants_reboot = true;
   1762         } else if(!strcmp(*argv, "update")) {
   1763             bool slot_all = (slot_override == "all");
   1764             if (slot_all) {
   1765                 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
   1766             }
   1767             if (argc > 1) {
   1768                 do_update(transport, argv[1], slot_override, erase_first, skip_secondary || slot_all);
   1769                 skip(2);
   1770             } else {
   1771                 do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
   1772                 skip(1);
   1773             }
   1774             wants_reboot = true;
   1775         } else if(!strcmp(*argv, "set_active")) {
   1776             require(2);
   1777             std::string slot = verify_slot(transport, std::string(argv[1]), false);
   1778             // Legacy support: verify_slot() removes leading underscores, we need to put them back
   1779             // in for old bootloaders. Legacy bootloaders do not have the slot-count variable but
   1780             // do have slot-suffixes.
   1781             std::string var;
   1782             if (!fb_getvar(transport, "slot-count", &var) &&
   1783                     fb_getvar(transport, "slot-suffixes", &var)) {
   1784                 slot = "_" + slot;
   1785             }
   1786             fb_set_active(slot.c_str());
   1787             skip(2);
   1788         } else if(!strcmp(*argv, "oem")) {
   1789             argc = do_oem_command(argc, argv);
   1790         } else if(!strcmp(*argv, "flashing")) {
   1791             if (argc == 2 && (!strcmp(*(argv+1), "unlock") ||
   1792                               !strcmp(*(argv+1), "lock") ||
   1793                               !strcmp(*(argv+1), "unlock_critical") ||
   1794                               !strcmp(*(argv+1), "lock_critical") ||
   1795                               !strcmp(*(argv+1), "get_unlock_ability") ||
   1796                               !strcmp(*(argv+1), "get_unlock_bootloader_nonce") ||
   1797                               !strcmp(*(argv+1), "lock_bootloader"))) {
   1798                 argc = do_oem_command(argc, argv);
   1799             } else
   1800             if (argc == 3 && !strcmp(*(argv+1), "unlock_bootloader")) {
   1801                 argc = do_bypass_unlock_command(argc, argv);
   1802             } else {
   1803               usage();
   1804               return 1;
   1805             }
   1806         } else {
   1807             usage();
   1808             return 1;
   1809         }
   1810     }
   1811 
   1812     if (wants_wipe) {
   1813         fprintf(stderr, "wiping userdata...\n");
   1814         fb_queue_erase("userdata");
   1815         if (set_fbe_marker) {
   1816             fprintf(stderr, "setting FBE marker...\n");
   1817             std::string initial_userdata_dir = create_fbemarker_tmpdir();
   1818             if (initial_userdata_dir.empty()) {
   1819                 return 1;
   1820             }
   1821             fb_perform_format(transport, "userdata", 1, nullptr, nullptr, initial_userdata_dir);
   1822             delete_fbemarker_tmpdir(initial_userdata_dir);
   1823         } else {
   1824             fb_perform_format(transport, "userdata", 1, nullptr, nullptr, "");
   1825         }
   1826 
   1827         std::string cache_type;
   1828         if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) {
   1829             fprintf(stderr, "wiping cache...\n");
   1830             fb_queue_erase("cache");
   1831             fb_perform_format(transport, "cache", 1, nullptr, nullptr, "");
   1832         }
   1833     }
   1834     if (wants_set_active) {
   1835         fb_set_active(next_active.c_str());
   1836     }
   1837     if (wants_reboot && !skip_reboot) {
   1838         fb_queue_reboot();
   1839         fb_queue_wait_for_disconnect();
   1840     } else if (wants_reboot_bootloader) {
   1841         fb_queue_command("reboot-bootloader", "rebooting into bootloader");
   1842         fb_queue_wait_for_disconnect();
   1843     } else if (wants_reboot_emergency) {
   1844         fb_queue_command("reboot-emergency", "rebooting into emergency download (EDL) mode");
   1845         fb_queue_wait_for_disconnect();
   1846     }
   1847 
   1848     return fb_execute_queue(transport) ? EXIT_FAILURE : EXIT_SUCCESS;
   1849 }
   1850