xref: /aosp_15_r20/system/core/fastboot/util.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1*00c7fec1SAndroid Build Coastguard Worker /*
2*00c7fec1SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*00c7fec1SAndroid Build Coastguard Worker  * All rights reserved.
4*00c7fec1SAndroid Build Coastguard Worker  *
5*00c7fec1SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*00c7fec1SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
7*00c7fec1SAndroid Build Coastguard Worker  * are met:
8*00c7fec1SAndroid Build Coastguard Worker  *  * Redistributions of source code must retain the above copyright
9*00c7fec1SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
10*00c7fec1SAndroid Build Coastguard Worker  *  * Redistributions in binary form must reproduce the above copyright
11*00c7fec1SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in
12*00c7fec1SAndroid Build Coastguard Worker  *    the documentation and/or other materials provided with the
13*00c7fec1SAndroid Build Coastguard Worker  *    distribution.
14*00c7fec1SAndroid Build Coastguard Worker  *
15*00c7fec1SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*00c7fec1SAndroid Build Coastguard Worker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*00c7fec1SAndroid Build Coastguard Worker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*00c7fec1SAndroid Build Coastguard Worker  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*00c7fec1SAndroid Build Coastguard Worker  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*00c7fec1SAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*00c7fec1SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*00c7fec1SAndroid Build Coastguard Worker  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*00c7fec1SAndroid Build Coastguard Worker  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*00c7fec1SAndroid Build Coastguard Worker  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*00c7fec1SAndroid Build Coastguard Worker  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*00c7fec1SAndroid Build Coastguard Worker  * SUCH DAMAGE.
27*00c7fec1SAndroid Build Coastguard Worker  */
28*00c7fec1SAndroid Build Coastguard Worker 
29*00c7fec1SAndroid Build Coastguard Worker #include <stdarg.h>
30*00c7fec1SAndroid Build Coastguard Worker #include <stdio.h>
31*00c7fec1SAndroid Build Coastguard Worker #include <stdlib.h>
32*00c7fec1SAndroid Build Coastguard Worker #include <string.h>
33*00c7fec1SAndroid Build Coastguard Worker #include <sys/stat.h>
34*00c7fec1SAndroid Build Coastguard Worker #include <time.h>
35*00c7fec1SAndroid Build Coastguard Worker 
36*00c7fec1SAndroid Build Coastguard Worker #include <android-base/parseint.h>
37*00c7fec1SAndroid Build Coastguard Worker #include <android-base/strings.h>
38*00c7fec1SAndroid Build Coastguard Worker 
39*00c7fec1SAndroid Build Coastguard Worker #include "util.h"
40*00c7fec1SAndroid Build Coastguard Worker 
41*00c7fec1SAndroid Build Coastguard Worker using android::base::borrowed_fd;
42*00c7fec1SAndroid Build Coastguard Worker 
43*00c7fec1SAndroid Build Coastguard Worker static bool g_verbose = false;
44*00c7fec1SAndroid Build Coastguard Worker 
now()45*00c7fec1SAndroid Build Coastguard Worker double now() {
46*00c7fec1SAndroid Build Coastguard Worker     struct timespec ts;
47*00c7fec1SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &ts);
48*00c7fec1SAndroid Build Coastguard Worker     return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000;
49*00c7fec1SAndroid Build Coastguard Worker }
50*00c7fec1SAndroid Build Coastguard Worker 
die(const char * fmt,...)51*00c7fec1SAndroid Build Coastguard Worker void die(const char* fmt, ...) {
52*00c7fec1SAndroid Build Coastguard Worker     va_list ap;
53*00c7fec1SAndroid Build Coastguard Worker     va_start(ap, fmt);
54*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "fastboot: error: ");
55*00c7fec1SAndroid Build Coastguard Worker     vfprintf(stderr, fmt, ap);
56*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "\n");
57*00c7fec1SAndroid Build Coastguard Worker     va_end(ap);
58*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
59*00c7fec1SAndroid Build Coastguard Worker }
60*00c7fec1SAndroid Build Coastguard Worker 
die(const std::string & str)61*00c7fec1SAndroid Build Coastguard Worker void die(const std::string& str) {
62*00c7fec1SAndroid Build Coastguard Worker     die("%s", str.c_str());
63*00c7fec1SAndroid Build Coastguard Worker }
64*00c7fec1SAndroid Build Coastguard Worker 
set_verbose()65*00c7fec1SAndroid Build Coastguard Worker void set_verbose() {
66*00c7fec1SAndroid Build Coastguard Worker     g_verbose = true;
67*00c7fec1SAndroid Build Coastguard Worker }
68*00c7fec1SAndroid Build Coastguard Worker 
verbose(const char * fmt,...)69*00c7fec1SAndroid Build Coastguard Worker void verbose(const char* fmt, ...) {
70*00c7fec1SAndroid Build Coastguard Worker     if (!g_verbose) return;
71*00c7fec1SAndroid Build Coastguard Worker 
72*00c7fec1SAndroid Build Coastguard Worker     if (*fmt != '\n') {
73*00c7fec1SAndroid Build Coastguard Worker         va_list ap;
74*00c7fec1SAndroid Build Coastguard Worker         va_start(ap, fmt);
75*00c7fec1SAndroid Build Coastguard Worker         fprintf(stderr, "fastboot: verbose: ");
76*00c7fec1SAndroid Build Coastguard Worker         vfprintf(stderr, fmt, ap);
77*00c7fec1SAndroid Build Coastguard Worker         va_end(ap);
78*00c7fec1SAndroid Build Coastguard Worker     }
79*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "\n");
80*00c7fec1SAndroid Build Coastguard Worker }
81*00c7fec1SAndroid Build Coastguard Worker 
should_flash_in_userspace(const android::fs_mgr::LpMetadata & metadata,const std::string & partition_name)82*00c7fec1SAndroid Build Coastguard Worker bool should_flash_in_userspace(const android::fs_mgr::LpMetadata& metadata,
83*00c7fec1SAndroid Build Coastguard Worker                                const std::string& partition_name) {
84*00c7fec1SAndroid Build Coastguard Worker     for (const auto& partition : metadata.partitions) {
85*00c7fec1SAndroid Build Coastguard Worker         auto candidate = android::fs_mgr::GetPartitionName(partition);
86*00c7fec1SAndroid Build Coastguard Worker         if (partition.attributes & LP_PARTITION_ATTR_SLOT_SUFFIXED) {
87*00c7fec1SAndroid Build Coastguard Worker             // On retrofit devices, we don't know if, or whether, the A or B
88*00c7fec1SAndroid Build Coastguard Worker             // slot has been flashed for dynamic partitions. Instead we add
89*00c7fec1SAndroid Build Coastguard Worker             // both names to the list as a conservative guess.
90*00c7fec1SAndroid Build Coastguard Worker             if (candidate + "_a" == partition_name || candidate + "_b" == partition_name) {
91*00c7fec1SAndroid Build Coastguard Worker                 return true;
92*00c7fec1SAndroid Build Coastguard Worker             }
93*00c7fec1SAndroid Build Coastguard Worker         } else if (candidate == partition_name) {
94*00c7fec1SAndroid Build Coastguard Worker             return true;
95*00c7fec1SAndroid Build Coastguard Worker         }
96*00c7fec1SAndroid Build Coastguard Worker     }
97*00c7fec1SAndroid Build Coastguard Worker     return false;
98*00c7fec1SAndroid Build Coastguard Worker }
99*00c7fec1SAndroid Build Coastguard Worker 
is_sparse_file(borrowed_fd fd)100*00c7fec1SAndroid Build Coastguard Worker bool is_sparse_file(borrowed_fd fd) {
101*00c7fec1SAndroid Build Coastguard Worker     SparsePtr s(sparse_file_import(fd.get(), false, false), sparse_file_destroy);
102*00c7fec1SAndroid Build Coastguard Worker     return !!s;
103*00c7fec1SAndroid Build Coastguard Worker }
104*00c7fec1SAndroid Build Coastguard Worker 
get_file_size(borrowed_fd fd)105*00c7fec1SAndroid Build Coastguard Worker int64_t get_file_size(borrowed_fd fd) {
106*00c7fec1SAndroid Build Coastguard Worker     struct stat sb;
107*00c7fec1SAndroid Build Coastguard Worker     if (fstat(fd.get(), &sb) == -1) {
108*00c7fec1SAndroid Build Coastguard Worker         die("could not get file size");
109*00c7fec1SAndroid Build Coastguard Worker     }
110*00c7fec1SAndroid Build Coastguard Worker     return sb.st_size;
111*00c7fec1SAndroid Build Coastguard Worker }
112*00c7fec1SAndroid Build Coastguard Worker 
fb_fix_numeric_var(std::string var)113*00c7fec1SAndroid Build Coastguard Worker std::string fb_fix_numeric_var(std::string var) {
114*00c7fec1SAndroid Build Coastguard Worker     // Some bootloaders (angler, for example), send spurious leading whitespace.
115*00c7fec1SAndroid Build Coastguard Worker     var = android::base::Trim(var);
116*00c7fec1SAndroid Build Coastguard Worker     // Some bootloaders (hammerhead, for example) use implicit hex.
117*00c7fec1SAndroid Build Coastguard Worker     // This code used to use strtol with base 16.
118*00c7fec1SAndroid Build Coastguard Worker     if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
119*00c7fec1SAndroid Build Coastguard Worker     return var;
120*00c7fec1SAndroid Build Coastguard Worker }
121