Loading fastboot/engine.cpp +23 −34 Original line number Diff line number Diff line Loading @@ -75,41 +75,35 @@ static Action *action_last = 0; int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...) { char cmd[CMD_SIZE] = "getvar:"; int getvar_len = strlen(cmd); va_list args; bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) { std::string cmd = "getvar:"; cmd += key; response[FB_RESPONSE_SZ] = '\0'; va_start(args, fmt); vsnprintf(cmd + getvar_len, sizeof(cmd) - getvar_len, fmt, args); va_end(args); cmd[CMD_SIZE - 1] = '\0'; return fb_command_response(usb, cmd, response); char buf[FB_RESPONSE_SZ + 1]; memset(buf, 0, sizeof(buf)); if (fb_command_response(usb, cmd.c_str(), buf)) { return false; } *value = buf; return true; } /* Return true if this partition is supported by the fastboot format command. * It is also used to determine if we should first erase a partition before * flashing it with an ext4 filesystem. See needs_erase() * * Not all devices report the filesystem type, so don't report any errors, * just return false. */ int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) { char fs_type[FB_RESPONSE_SZ + 1] = {0,}; int status; // Return true if this partition is supported by the fastboot format command. // It is also used to determine if we should first erase a partition before // flashing it with an ext4 filesystem. See needs_erase() // // Not all devices report the filesystem type, so don't report any errors, // just return false. bool fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) { if (type_override) { return !!fs_get_generator(type_override); return fs_get_generator(type_override) != nullptr; } status = fb_getvar(usb, fs_type, "partition-type:%s", partition); if (status) { return 0; std::string partition_type; if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { return false; } return !!fs_get_generator(fs_type); return fs_get_generator(partition_type.c_str()) != nullptr; } static int cb_default(Action* a, int status, const char* resp) { Loading Loading @@ -394,8 +388,3 @@ int fb_execute_queue(usb_handle *usb) fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); return status; } int fb_queue_is_empty(void) { return (action_list == nullptr); } fastboot/fastboot.cpp +64 −73 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <sys/types.h> #include <unistd.h> #include <base/parseint.h> #include <sparse/sparse.h> #include <ziparchive/zip_archive.h> Loading Loading @@ -567,25 +568,23 @@ static struct sparse_file **load_sparse_files(int fd, int max_size) return out_s; } static int64_t get_target_sparse_limit(struct usb_handle *usb) { int64_t limit = 0; char response[FB_RESPONSE_SZ + 1]; int status = fb_getvar(usb, response, "max-download-size"); static int64_t get_target_sparse_limit(usb_handle* usb) { std::string max_download_size; if (!fb_getvar(usb, "max-download-size", &max_download_size)) { return 0; } if (!status) { limit = strtoul(response, nullptr, 0); if (limit > 0) { fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit); uint64_t limit; if (!android::base::ParseUint(max_download_size.c_str(), &limit)) { return 0; } if (limit > 0) { fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit); } return limit; } static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) { static int64_t get_sparse_limit(usb_handle* usb, int64_t size) { int64_t limit; if (sparse_limit == 0) { Loading @@ -610,16 +609,11 @@ static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) return 0; } /* Until we get lazy inode table init working in make_ext4fs, we need to * erase partitions of type ext4 before flashing a filesystem so no stale * inodes are left lying around. Otherwise, e2fsck gets very upset. */ static int needs_erase(usb_handle* usb, const char *part) { /* The function fb_format_supported() currently returns the value * we want, so just call it. */ return fb_format_supported(usb, part, nullptr); // Until we get lazy inode table init working in make_ext4fs, we need to // erase partitions of type ext4 before flashing a filesystem so no stale // inodes are left lying around. Otherwise, e2fsck gets very upset. static bool needs_erase(usb_handle* usb, const char* part) { return !fb_format_supported(usb, part, nullptr); } static int load_buf_fd(usb_handle* usb, int fd, struct fastboot_buffer* buf) { Loading Loading @@ -854,85 +848,82 @@ static int64_t parse_num(const char *arg) static void fb_perform_format(usb_handle* usb, const char* partition, int skip_if_not_supported, const char* type_override, const char* size_override) { char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1]; char *pType = pTypeBuff; char *pSize = pSizeBuff; unsigned int limit = INT_MAX; std::string partition_type, partition_size; struct fastboot_buffer buf; const char* errMsg = nullptr; const struct fs_generator *gen; uint64_t pSz; int status; const struct fs_generator* gen = nullptr; int fd; if (target_sparse_limit > 0 && target_sparse_limit < limit) unsigned int limit = INT_MAX; if (target_sparse_limit > 0 && target_sparse_limit < limit) { limit = target_sparse_limit; if (sparse_limit > 0 && sparse_limit < limit) } if (sparse_limit > 0 && sparse_limit < limit) { limit = sparse_limit; } status = fb_getvar(usb, pType, "partition-type:%s", partition); if (status) { if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { errMsg = "Can't determine partition type.\n"; goto failed; } if (type_override) { if (strcmp(type_override, pType)) { fprintf(stderr, "Warning: %s type is %s, but %s was requested for formating.\n", partition, pType, type_override); if (partition_type != type_override) { fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n", partition, partition_type.c_str(), type_override); } pType = (char *)type_override; partition_type = type_override; } status = fb_getvar(usb, pSize, "partition-size:%s", partition); if (status) { if (!fb_getvar(usb, std::string("partition-size:") + partition, &partition_size)) { errMsg = "Unable to get partition size\n"; goto failed; } if (size_override) { if (strcmp(size_override, pSize)) { fprintf(stderr, "Warning: %s size is %s, but %s was requested for formating.\n", partition, pSize, size_override); if (partition_size != size_override) { fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n", partition, partition_size.c_str(), size_override); } pSize = (char *)size_override; partition_size = size_override; } gen = fs_get_generator(pType); gen = fs_get_generator(partition_type.c_str()); if (!gen) { if (skip_if_not_supported) { fprintf(stderr, "Erase successful, but not automatically formatting.\n"); fprintf(stderr, "File system type %s not supported.\n", pType); fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str()); return; } fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType); fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n", partition_type.c_str()); return; } pSz = strtoll(pSize, (char **)nullptr, 16); int64_t size; if (!android::base::ParseInt(partition_size.c_str(), &size)) { fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str()); return; } fd = fileno(tmpfile()); if (fs_generator_generate(gen, fd, pSz)) { if (fs_generator_generate(gen, fd, size)) { fprintf(stderr, "Cannot generate image: %s\n", strerror(errno)); close(fd); fprintf(stderr, "Cannot generate image.\n"); return; } if (load_buf_fd(usb, fd, &buf)) { fprintf(stderr, "Cannot read image.\n"); fprintf(stderr, "Cannot read image: %s\n", strerror(errno)); close(fd); return; } flash_buf(partition, &buf); return; failed: if (skip_if_not_supported) { fprintf(stderr, "Erase successful, but not automatically formatting.\n"); if (errMsg) fprintf(stderr, "%s", errMsg); if (errMsg) fprintf(stderr, "%s", errMsg); } fprintf(stderr,"FAILED (%s)\n", fb_get_error()); } Loading @@ -945,8 +936,6 @@ int main(int argc, char **argv) bool erase_first = true; void *data; int64_t sz; int status; int c; int longindex; const struct option longopts[] = { Loading @@ -964,7 +953,7 @@ int main(int argc, char **argv) serial = getenv("ANDROID_SERIAL"); while (1) { c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex); int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex); if (c < 0) { break; } Loading Loading @@ -1068,7 +1057,7 @@ int main(int argc, char **argv) } else if(!strcmp(*argv, "erase")) { require(2); if (fb_format_supported(usb, argv[1], nullptr)) { if (!fb_format_supported(usb, argv[1], nullptr)) { fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); } Loading Loading @@ -1217,11 +1206,17 @@ int main(int argc, char **argv) } if (wants_wipe) { fprintf(stderr, "wiping userdata...\n"); fb_queue_erase("userdata"); fb_perform_format(usb, "userdata", 1, nullptr, nullptr); std::string cache_type; if (fb_getvar(usb, "partition-type:cache", &cache_type) && !cache_type.empty()) { fprintf(stderr, "wiping cache...\n"); fb_queue_erase("cache"); fb_perform_format(usb, "cache", 1, nullptr, nullptr); } } if (wants_reboot) { fb_queue_reboot(); fb_queue_wait_for_disconnect(); Loading @@ -1230,9 +1225,5 @@ int main(int argc, char **argv) fb_queue_wait_for_disconnect(); } if (fb_queue_is_empty()) return 0; status = fb_execute_queue(usb); return (status) ? 1 : 0; return fb_execute_queue(usb) ? EXIT_FAILURE : EXIT_SUCCESS; } fastboot/fastboot.h +4 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <inttypes.h> #include <stdlib.h> #include <string> #include "usb.h" struct sparse_file; Loading @@ -47,8 +49,8 @@ char *fb_get_error(void); #define FB_RESPONSE_SZ 64 /* engine.c - high level command queue engine */ int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...); int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override); bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value); bool fb_format_supported(usb_handle* usb, const char* partition, const char* type_override); void fb_queue_flash(const char *ptn, void *data, uint32_t sz); void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, uint32_t sz); void fb_queue_erase(const char *ptn); Loading @@ -63,7 +65,6 @@ void fb_queue_download(const char *name, void *data, uint32_t size); void fb_queue_notice(const char *notice); void fb_queue_wait_for_disconnect(void); int fb_execute_queue(usb_handle *usb); int fb_queue_is_empty(void); /* util stuff */ double now(); Loading Loading
fastboot/engine.cpp +23 −34 Original line number Diff line number Diff line Loading @@ -75,41 +75,35 @@ static Action *action_last = 0; int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...) { char cmd[CMD_SIZE] = "getvar:"; int getvar_len = strlen(cmd); va_list args; bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) { std::string cmd = "getvar:"; cmd += key; response[FB_RESPONSE_SZ] = '\0'; va_start(args, fmt); vsnprintf(cmd + getvar_len, sizeof(cmd) - getvar_len, fmt, args); va_end(args); cmd[CMD_SIZE - 1] = '\0'; return fb_command_response(usb, cmd, response); char buf[FB_RESPONSE_SZ + 1]; memset(buf, 0, sizeof(buf)); if (fb_command_response(usb, cmd.c_str(), buf)) { return false; } *value = buf; return true; } /* Return true if this partition is supported by the fastboot format command. * It is also used to determine if we should first erase a partition before * flashing it with an ext4 filesystem. See needs_erase() * * Not all devices report the filesystem type, so don't report any errors, * just return false. */ int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) { char fs_type[FB_RESPONSE_SZ + 1] = {0,}; int status; // Return true if this partition is supported by the fastboot format command. // It is also used to determine if we should first erase a partition before // flashing it with an ext4 filesystem. See needs_erase() // // Not all devices report the filesystem type, so don't report any errors, // just return false. bool fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) { if (type_override) { return !!fs_get_generator(type_override); return fs_get_generator(type_override) != nullptr; } status = fb_getvar(usb, fs_type, "partition-type:%s", partition); if (status) { return 0; std::string partition_type; if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { return false; } return !!fs_get_generator(fs_type); return fs_get_generator(partition_type.c_str()) != nullptr; } static int cb_default(Action* a, int status, const char* resp) { Loading Loading @@ -394,8 +388,3 @@ int fb_execute_queue(usb_handle *usb) fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); return status; } int fb_queue_is_empty(void) { return (action_list == nullptr); }
fastboot/fastboot.cpp +64 −73 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <sys/types.h> #include <unistd.h> #include <base/parseint.h> #include <sparse/sparse.h> #include <ziparchive/zip_archive.h> Loading Loading @@ -567,25 +568,23 @@ static struct sparse_file **load_sparse_files(int fd, int max_size) return out_s; } static int64_t get_target_sparse_limit(struct usb_handle *usb) { int64_t limit = 0; char response[FB_RESPONSE_SZ + 1]; int status = fb_getvar(usb, response, "max-download-size"); static int64_t get_target_sparse_limit(usb_handle* usb) { std::string max_download_size; if (!fb_getvar(usb, "max-download-size", &max_download_size)) { return 0; } if (!status) { limit = strtoul(response, nullptr, 0); if (limit > 0) { fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit); uint64_t limit; if (!android::base::ParseUint(max_download_size.c_str(), &limit)) { return 0; } if (limit > 0) { fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit); } return limit; } static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) { static int64_t get_sparse_limit(usb_handle* usb, int64_t size) { int64_t limit; if (sparse_limit == 0) { Loading @@ -610,16 +609,11 @@ static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size) return 0; } /* Until we get lazy inode table init working in make_ext4fs, we need to * erase partitions of type ext4 before flashing a filesystem so no stale * inodes are left lying around. Otherwise, e2fsck gets very upset. */ static int needs_erase(usb_handle* usb, const char *part) { /* The function fb_format_supported() currently returns the value * we want, so just call it. */ return fb_format_supported(usb, part, nullptr); // Until we get lazy inode table init working in make_ext4fs, we need to // erase partitions of type ext4 before flashing a filesystem so no stale // inodes are left lying around. Otherwise, e2fsck gets very upset. static bool needs_erase(usb_handle* usb, const char* part) { return !fb_format_supported(usb, part, nullptr); } static int load_buf_fd(usb_handle* usb, int fd, struct fastboot_buffer* buf) { Loading Loading @@ -854,85 +848,82 @@ static int64_t parse_num(const char *arg) static void fb_perform_format(usb_handle* usb, const char* partition, int skip_if_not_supported, const char* type_override, const char* size_override) { char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1]; char *pType = pTypeBuff; char *pSize = pSizeBuff; unsigned int limit = INT_MAX; std::string partition_type, partition_size; struct fastboot_buffer buf; const char* errMsg = nullptr; const struct fs_generator *gen; uint64_t pSz; int status; const struct fs_generator* gen = nullptr; int fd; if (target_sparse_limit > 0 && target_sparse_limit < limit) unsigned int limit = INT_MAX; if (target_sparse_limit > 0 && target_sparse_limit < limit) { limit = target_sparse_limit; if (sparse_limit > 0 && sparse_limit < limit) } if (sparse_limit > 0 && sparse_limit < limit) { limit = sparse_limit; } status = fb_getvar(usb, pType, "partition-type:%s", partition); if (status) { if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { errMsg = "Can't determine partition type.\n"; goto failed; } if (type_override) { if (strcmp(type_override, pType)) { fprintf(stderr, "Warning: %s type is %s, but %s was requested for formating.\n", partition, pType, type_override); if (partition_type != type_override) { fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n", partition, partition_type.c_str(), type_override); } pType = (char *)type_override; partition_type = type_override; } status = fb_getvar(usb, pSize, "partition-size:%s", partition); if (status) { if (!fb_getvar(usb, std::string("partition-size:") + partition, &partition_size)) { errMsg = "Unable to get partition size\n"; goto failed; } if (size_override) { if (strcmp(size_override, pSize)) { fprintf(stderr, "Warning: %s size is %s, but %s was requested for formating.\n", partition, pSize, size_override); if (partition_size != size_override) { fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n", partition, partition_size.c_str(), size_override); } pSize = (char *)size_override; partition_size = size_override; } gen = fs_get_generator(pType); gen = fs_get_generator(partition_type.c_str()); if (!gen) { if (skip_if_not_supported) { fprintf(stderr, "Erase successful, but not automatically formatting.\n"); fprintf(stderr, "File system type %s not supported.\n", pType); fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str()); return; } fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType); fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n", partition_type.c_str()); return; } pSz = strtoll(pSize, (char **)nullptr, 16); int64_t size; if (!android::base::ParseInt(partition_size.c_str(), &size)) { fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str()); return; } fd = fileno(tmpfile()); if (fs_generator_generate(gen, fd, pSz)) { if (fs_generator_generate(gen, fd, size)) { fprintf(stderr, "Cannot generate image: %s\n", strerror(errno)); close(fd); fprintf(stderr, "Cannot generate image.\n"); return; } if (load_buf_fd(usb, fd, &buf)) { fprintf(stderr, "Cannot read image.\n"); fprintf(stderr, "Cannot read image: %s\n", strerror(errno)); close(fd); return; } flash_buf(partition, &buf); return; failed: if (skip_if_not_supported) { fprintf(stderr, "Erase successful, but not automatically formatting.\n"); if (errMsg) fprintf(stderr, "%s", errMsg); if (errMsg) fprintf(stderr, "%s", errMsg); } fprintf(stderr,"FAILED (%s)\n", fb_get_error()); } Loading @@ -945,8 +936,6 @@ int main(int argc, char **argv) bool erase_first = true; void *data; int64_t sz; int status; int c; int longindex; const struct option longopts[] = { Loading @@ -964,7 +953,7 @@ int main(int argc, char **argv) serial = getenv("ANDROID_SERIAL"); while (1) { c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex); int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex); if (c < 0) { break; } Loading Loading @@ -1068,7 +1057,7 @@ int main(int argc, char **argv) } else if(!strcmp(*argv, "erase")) { require(2); if (fb_format_supported(usb, argv[1], nullptr)) { if (!fb_format_supported(usb, argv[1], nullptr)) { fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); } Loading Loading @@ -1217,11 +1206,17 @@ int main(int argc, char **argv) } if (wants_wipe) { fprintf(stderr, "wiping userdata...\n"); fb_queue_erase("userdata"); fb_perform_format(usb, "userdata", 1, nullptr, nullptr); std::string cache_type; if (fb_getvar(usb, "partition-type:cache", &cache_type) && !cache_type.empty()) { fprintf(stderr, "wiping cache...\n"); fb_queue_erase("cache"); fb_perform_format(usb, "cache", 1, nullptr, nullptr); } } if (wants_reboot) { fb_queue_reboot(); fb_queue_wait_for_disconnect(); Loading @@ -1230,9 +1225,5 @@ int main(int argc, char **argv) fb_queue_wait_for_disconnect(); } if (fb_queue_is_empty()) return 0; status = fb_execute_queue(usb); return (status) ? 1 : 0; return fb_execute_queue(usb) ? EXIT_FAILURE : EXIT_SUCCESS; }
fastboot/fastboot.h +4 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <inttypes.h> #include <stdlib.h> #include <string> #include "usb.h" struct sparse_file; Loading @@ -47,8 +49,8 @@ char *fb_get_error(void); #define FB_RESPONSE_SZ 64 /* engine.c - high level command queue engine */ int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...); int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override); bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value); bool fb_format_supported(usb_handle* usb, const char* partition, const char* type_override); void fb_queue_flash(const char *ptn, void *data, uint32_t sz); void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, uint32_t sz); void fb_queue_erase(const char *ptn); Loading @@ -63,7 +65,6 @@ void fb_queue_download(const char *name, void *data, uint32_t size); void fb_queue_notice(const char *notice); void fb_queue_wait_for_disconnect(void); int fb_execute_queue(usb_handle *usb); int fb_queue_is_empty(void); /* util stuff */ double now(); Loading