diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp index 47567c041..db5d0e0b2 100644 --- a/fastboot/engine.cpp +++ b/fastboot/engine.cpp @@ -351,21 +351,21 @@ int fb_execute_queue(Transport* transport) } if (a->op == OP_DOWNLOAD) { status = fb_download_data(transport, a->data, a->size); - status = a->func(a, status, status ? fb_get_error() : ""); + status = a->func(a, status, status ? fb_get_error().c_str() : ""); if (status) break; } else if (a->op == OP_COMMAND) { status = fb_command(transport, a->cmd); - status = a->func(a, status, status ? fb_get_error() : ""); + status = a->func(a, status, status ? fb_get_error().c_str() : ""); if (status) break; } else if (a->op == OP_QUERY) { status = fb_command_response(transport, a->cmd, resp); - status = a->func(a, status, status ? fb_get_error() : resp); + status = a->func(a, status, status ? fb_get_error().c_str() : resp); if (status) break; } else if (a->op == OP_NOTICE) { fprintf(stderr,"%s\n",(char*)a->data); } else if (a->op == OP_DOWNLOAD_SPARSE) { status = fb_download_data_sparse(transport, reinterpret_cast(a->data)); - status = a->func(a, status, status ? fb_get_error() : ""); + status = a->func(a, status, status ? fb_get_error().c_str() : ""); if (status) break; } else if (a->op == OP_WAIT_FOR_DISCONNECT) { transport->WaitForDisconnect(); diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index fa8f19a58..94efcc35b 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -108,12 +109,9 @@ static struct { {"vendor.img", "vendor.sig", "vendor", true}, }; -static char* find_item(const char* item, const char* product) { - char *dir; +static std::string find_item(const char* item, const char* product) { const char *fn; - char path[PATH_MAX + 128]; - - if(!strcmp(item,"boot")) { + if (!strcmp(item,"boot")) { fn = "boot.img"; } else if(!strcmp(item,"recovery")) { fn = "recovery.img"; @@ -129,24 +127,22 @@ static char* find_item(const char* item, const char* product) { fn = "android-info.txt"; } else { fprintf(stderr,"unknown partition '%s'\n", item); - return 0; + return ""; } - if(product) { - get_my_path(path); - sprintf(path + strlen(path), - "../../../target/product/%s/%s", product, fn); - return strdup(path); + if (product) { + std::string path = get_my_path(); + path.erase(path.find_last_of('/')); + return android::base::StringPrintf("%s/../../../target/product/%s/%s", + path.c_str(), product, fn); } - dir = getenv("ANDROID_PRODUCT_OUT"); - if((dir == 0) || (dir[0] == 0)) { + char* dir = getenv("ANDROID_PRODUCT_OUT"); + if (dir == nullptr || dir[0] == '\0') { die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); - return 0; } - sprintf(path, "%s/%s", dir, fn); - return strdup(path); + return android::base::StringPrintf("%s/%s", dir, fn); } static int64_t get_file_size(int fd) { @@ -179,8 +175,8 @@ oops: return 0; } -static void* load_file(const char* fn, int64_t* sz) { - int fd = open(fn, O_RDONLY | O_BINARY); +static void* load_file(const std::string& path, int64_t* sz) { + int fd = open(path.c_str(), O_RDONLY | O_BINARY); if (fd == -1) return nullptr; return load_fd(fd, sz); } @@ -964,18 +960,19 @@ static void do_update(Transport* transport, const char* filename, const char* sl CloseArchive(zip); } -static void do_send_signature(char* fn) { - char* xtn = strrchr(fn, '.'); - if (!xtn) return; +static void do_send_signature(const char* filename) { + if (android::base::EndsWith(filename, ".img") == false) { + return; + } - if (strcmp(xtn, ".img")) return; - - strcpy(xtn, ".sig"); + std::string sig_path = filename; + sig_path.erase(sig_path.size() - 4); + sig_path += ".sig"; int64_t sz; - void* data = load_file(fn, &sz); - strcpy(xtn, ".img"); + void* data = load_file(sig_path, &sz); if (data == nullptr) return; + fb_queue_download("signature", data, sz); fb_queue_command("signature", "installing signature"); } @@ -985,8 +982,8 @@ static void do_flashall(Transport* transport, const char* slot_override, int era fb_queue_query_save("product", cur_product, sizeof(cur_product)); - char* fname = find_item("info", product); - if (fname == nullptr) die("cannot find android-info.txt"); + std::string fname = find_item("info", product); + if (fname.empty()) die("cannot find android-info.txt"); int64_t sz; void* data = load_file(fname, &sz); @@ -997,14 +994,14 @@ static void do_flashall(Transport* transport, const char* slot_override, int era for (size_t i = 0; i < ARRAY_SIZE(images); i++) { fname = find_item(images[i].part_name, product); fastboot_buffer buf; - if (load_buf(transport, fname, &buf)) { + if (load_buf(transport, fname.c_str(), &buf)) { if (images[i].is_optional) continue; die("could not load %s\n", images[i].img_name); } auto flashall = [&](const std::string &partition) { - do_send_signature(fname); + do_send_signature(fname.c_str()); if (erase_first && needs_erase(transport, partition.c_str())) { fb_queue_erase(partition.c_str()); } @@ -1180,7 +1177,7 @@ failed: fprintf(stderr, "Erase successful, but not automatically formatting.\n"); if (errMsg) fprintf(stderr, "%s", errMsg); } - fprintf(stderr,"FAILED (%s)\n", fb_get_error()); + fprintf(stderr, "FAILED (%s)\n", fb_get_error().c_str()); } int main(int argc, char **argv) @@ -1441,8 +1438,8 @@ int main(int argc, char **argv) fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); } else if(!strcmp(*argv, "flash")) { - char *pname = argv[1]; - char *fname = 0; + char* pname = argv[1]; + std::string fname; require(2); if (argc > 2) { fname = argv[2]; @@ -1451,13 +1448,13 @@ int main(int argc, char **argv) fname = find_item(pname, product); skip(2); } - if (fname == 0) die("cannot determine image filename for '%s'", pname); + if (fname.empty()) die("cannot determine image filename for '%s'", pname); auto flash = [&](const std::string &partition) { if (erase_first && needs_erase(transport, partition.c_str())) { fb_queue_erase(partition.c_str()); } - do_flash(transport, partition.c_str(), fname); + do_flash(transport, partition.c_str(), fname.c_str()); }; do_for_partitions(transport, pname, slot_override.c_str(), flash, true); } else if(!strcmp(*argv, "flash:raw")) { diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h index 1932bab73..c2ea55136 100644 --- a/fastboot/fastboot.h +++ b/fastboot/fastboot.h @@ -43,7 +43,7 @@ int fb_command(Transport* transport, const char* cmd); int fb_command_response(Transport* transport, const char* cmd, char* response); int fb_download_data(Transport* transport, const void* data, uint32_t size); int fb_download_data_sparse(Transport* transport, struct sparse_file* s); -char *fb_get_error(void); +const std::string fb_get_error(); #define FB_COMMAND_SZ 64 #define FB_RESPONSE_SZ 64 @@ -72,7 +72,7 @@ double now(); char *mkmsg(const char *fmt, ...); __attribute__((__noreturn__)) void die(const char *fmt, ...); -void get_my_path(char *path); +std::string get_my_path(); /* Current product */ extern char cur_product[FB_RESPONSE_SZ + 1]; diff --git a/fastboot/protocol.cpp b/fastboot/protocol.cpp index 1785b7622..bfa83b041 100644 --- a/fastboot/protocol.cpp +++ b/fastboot/protocol.cpp @@ -36,16 +36,16 @@ #include +#include #include #include "fastboot.h" #include "transport.h" -static char ERROR[128]; +static std::string g_error; -char *fb_get_error(void) -{ - return ERROR; +const std::string fb_get_error() { + return g_error; } static int check_response(Transport* transport, uint32_t size, char* response) { @@ -54,14 +54,14 @@ static int check_response(Transport* transport, uint32_t size, char* response) { while (true) { int r = transport->Read(status, 64); if (r < 0) { - snprintf(ERROR, sizeof(ERROR), "status read failed (%s)", strerror(errno)); + g_error = android::base::StringPrintf("status read failed (%s)", strerror(errno)); transport->Close(); return -1; } status[r] = 0; if (r < 4) { - snprintf(ERROR, sizeof(ERROR), "status malformed (%d bytes)", r); + g_error = android::base::StringPrintf("status malformed (%d bytes)", r); transport->Close(); return -1; } @@ -80,9 +80,9 @@ static int check_response(Transport* transport, uint32_t size, char* response) { if (!memcmp(status, "FAIL", 4)) { if (r > 4) { - snprintf(ERROR, sizeof(ERROR), "remote: %s", status + 4); + g_error = android::base::StringPrintf("remote: %s", status + 4); } else { - strcpy(ERROR, "remote failure"); + g_error = "remote failure"; } return -1; } @@ -90,14 +90,14 @@ static int check_response(Transport* transport, uint32_t size, char* response) { if (!memcmp(status, "DATA", 4) && size > 0){ uint32_t dsize = strtol(status + 4, 0, 16); if (dsize > size) { - strcpy(ERROR, "data size too large"); + g_error = android::base::StringPrintf("data size too large (%d)", dsize); transport->Close(); return -1; } return dsize; } - strcpy(ERROR,"unknown status code"); + g_error = "unknown status code"; transport->Close(); break; } @@ -108,7 +108,7 @@ static int check_response(Transport* transport, uint32_t size, char* response) { static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) { size_t cmdsize = strlen(cmd); if (cmdsize > 64) { - snprintf(ERROR, sizeof(ERROR), "command too large"); + g_error = android::base::StringPrintf("command too large (%zu)", cmdsize); return -1; } @@ -117,7 +117,7 @@ static int _command_start(Transport* transport, const char* cmd, uint32_t size, } if (transport->Write(cmd, cmdsize) != static_cast(cmdsize)) { - snprintf(ERROR, sizeof(ERROR), "command write failed (%s)", strerror(errno)); + g_error = android::base::StringPrintf("command write failed (%s)", strerror(errno)); transport->Close(); return -1; } @@ -128,12 +128,12 @@ static int _command_start(Transport* transport, const char* cmd, uint32_t size, static int _command_data(Transport* transport, const void* data, uint32_t size) { int r = transport->Write(data, size); if (r < 0) { - snprintf(ERROR, sizeof(ERROR), "data transfer failure (%s)", strerror(errno)); + g_error = android::base::StringPrintf("data transfer failure (%s)", strerror(errno)); transport->Close(); return -1; } if (r != ((int) size)) { - snprintf(ERROR, sizeof(ERROR), "data transfer failure (short transfer)"); + g_error = "data transfer failure (short transfer)"; transport->Close(); return -1; } @@ -216,7 +216,7 @@ static int fb_download_data_sparse_write(void *priv, const void *data, int len) if (len > TRANSPORT_BUF_SIZE) { if (transport_buf_len > 0) { - snprintf(ERROR, sizeof(ERROR), "internal error: transport_buf not empty\n"); + g_error = "internal error: transport_buf not empty"; return -1; } to_write = round_down(len, TRANSPORT_BUF_SIZE); @@ -230,7 +230,7 @@ static int fb_download_data_sparse_write(void *priv, const void *data, int len) if (len > 0) { if (len > TRANSPORT_BUF_SIZE) { - snprintf(ERROR, sizeof(ERROR), "internal error: too much left for transport_buf\n"); + g_error = "internal error: too much left for transport_buf"; return -1; } memcpy(transport_buf, ptr, len); diff --git a/fastboot/util_linux.cpp b/fastboot/util_linux.cpp index b78819952..2c6aedb3e 100644 --- a/fastboot/util_linux.cpp +++ b/fastboot/util_linux.cpp @@ -28,27 +28,16 @@ #include "fastboot.h" -#include -#include -#include -#include -#include #include #include -void get_my_path(char *path) -{ - char proc[64]; - char *x; +#include - sprintf(proc, "/proc/%d/exe", getpid()); - int err = readlink(proc, path, PATH_MAX - 1); - - if(err <= 0) { - path[0] = 0; - } else { - path[err] = 0; - x = strrchr(path,'/'); - if(x) x[1] = 0; - } +std::string get_my_path() { + std::string proc = android::base::StringPrintf("/proc/%d/exe", getpid()); + char path[PATH_MAX + 1]; + int rc = readlink(proc.c_str(), path, sizeof(path) - 1); + if (rc == -1) return ""; + path[rc] = '\0'; + return path; } diff --git a/fastboot/util_osx.cpp b/fastboot/util_osx.cpp index ae0b02460..4bae7c406 100644 --- a/fastboot/util_osx.cpp +++ b/fastboot/util_osx.cpp @@ -31,19 +31,15 @@ #import #include -void get_my_path(char s[PATH_MAX]) -{ +std::string get_my_path() { CFBundleRef mainBundle = CFBundleGetMainBundle(); CFURLRef executableURL = CFBundleCopyExecutableURL(mainBundle); CFStringRef executablePathString = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle); CFRelease(executableURL); - CFStringGetFileSystemRepresentation(executablePathString, s, PATH_MAX-1); + char path[PATH_MAX + 1]; + CFStringGetFileSystemRepresentation(executablePathString, path, sizeof(PATH_MAX)-1); CFRelease(executablePathString); - char *x; - x = strrchr(s, '/'); - if(x) x[1] = 0; + return path; } - - diff --git a/fastboot/util_windows.cpp b/fastboot/util_windows.cpp index ec52f3988..3b22c55f0 100644 --- a/fastboot/util_windows.cpp +++ b/fastboot/util_windows.cpp @@ -38,14 +38,12 @@ #include -void get_my_path(char exe[PATH_MAX]) -{ - char* r; +std::string get_my_path() { + char path[PATH_MAX + 1]; - GetModuleFileName( NULL, exe, PATH_MAX-1 ); - exe[PATH_MAX-1] = 0; - r = strrchr( exe, '\\' ); - if (r) - *r = 0; + DWORD result = GetModuleFileName(NULL, path, sizeof(path) - 1); + if (result == 0 || result == sizeof(path) - 1) return ""; + path[PATH_MAX - 1] = 0; + + return path; } -