summaryrefslogtreecommitdiffstats
path: root/fastboot/fastboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fastboot/fastboot.c')
-rw-r--r--fastboot/fastboot.c98
1 files changed, 82 insertions, 16 deletions
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index f186c93..4fd1a8e 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -30,7 +30,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@@ -50,6 +49,7 @@
#include <zipfile/zipfile.h>
#include "fastboot.h"
+#include "fs.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -106,17 +106,6 @@ static struct {
{"system.img", "system.sig", "system", false},
};
-void die(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr,"error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr,"\n");
- va_end(ap);
- exit(1);
-}
-
void get_my_path(char *path);
char *find_item(const char *item, const char *product)
@@ -503,7 +492,13 @@ static int setup_requirement_line(char *name)
for(n = 0; n < count; n++) {
out[n] = strdup(strip(val[n]));
- if (out[n] == 0) return -1;
+ if (out[n] == 0) {
+ for(size_t i = 0; i < n; ++i) {
+ free((char*) out[i]);
+ }
+ free(out);
+ return -1;
+ }
}
fb_queue_require(prod, name, invert, n, out);
@@ -628,10 +623,13 @@ static int load_buf_fd(usb_handle *usb, int fd,
void *data;
int64_t limit;
+
sz64 = file_size(fd);
if (sz64 < 0) {
return -1;
}
+
+ lseek(fd, 0, SEEK_SET);
limit = get_sparse_limit(usb, sz64);
if (limit) {
struct sparse_file **s = load_sparse_files(fd, limit);
@@ -878,6 +876,73 @@ static int64_t parse_num(const char *arg)
return num;
}
+void fb_perform_format(const char *partition, int skip_if_not_supported)
+{
+ char pType[FB_RESPONSE_SZ + 1], pSize[FB_RESPONSE_SZ + 1];
+ unsigned int limit = INT_MAX;
+ struct fastboot_buffer buf;
+ const char *errMsg = NULL;
+ const struct fs_generator *gen;
+ uint64_t pSz;
+ int status;
+ int fd;
+
+ if (target_sparse_limit > 0 && target_sparse_limit < limit)
+ limit = target_sparse_limit;
+ if (sparse_limit > 0 && sparse_limit < limit)
+ limit = sparse_limit;
+
+ status = fb_getvar(usb, pType, "partition-type:%s", partition);
+ if (status) {
+ errMsg = "Can't determine partition type.\n";
+ goto failed;
+ }
+
+ status = fb_getvar(usb, pSize, "partition-size:%s", partition);
+ if (status) {
+ errMsg = "Unable to get partition size\n";
+ goto failed;
+ }
+
+ gen = fs_get_generator(pType);
+ 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);
+ return;
+ }
+ fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType);
+ return;
+ }
+
+ pSz = strtoll(pSize, (char **)NULL, 16);
+
+ fd = fileno(tmpfile());
+ if (fs_generator_generate(gen, fd, pSz)) {
+ close(fd);
+ fprintf(stderr, "Cannot generate image.\n");
+ return;
+ }
+
+ if (load_buf_fd(usb, fd, &buf)) {
+ fprintf(stderr, "Cannot read image.\n");
+ 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);
+ }
+ fprintf(stderr,"FAILED (%s)\n", fb_get_error());
+}
+
int main(int argc, char **argv)
{
int wants_wipe = 0;
@@ -1006,7 +1071,7 @@ int main(int argc, char **argv)
if (erase_first && needs_erase(argv[1])) {
fb_queue_erase(argv[1]);
}
- fb_queue_format(argv[1], 0);
+ fb_perform_format(argv[1], 0);
skip(2);
} else if(!strcmp(*argv, "signature")) {
require(2);
@@ -1094,14 +1159,15 @@ int main(int argc, char **argv)
if (wants_wipe) {
fb_queue_erase("userdata");
- fb_queue_format("userdata", 1);
+ fb_perform_format("userdata", 1);
fb_queue_erase("cache");
- fb_queue_format("cache", 1);
+ fb_perform_format("cache", 1);
}
if (wants_reboot) {
fb_queue_reboot();
} else if (wants_reboot_bootloader) {
fb_queue_command("reboot-bootloader", "rebooting into bootloader");
+ fb_queue_wait_for_disconnect();
}
if (fb_queue_is_empty())