static int clear_bcb(const std::string& status_file) { unique_fd status_fd(open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)); if (!status_fd) { ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno)); return 1; } bootloader_message boot = {}; if (write_bootloader_message(&boot) != 0) { android::base::WriteStringToFd("-1\n", status_fd.get()); return 1; } android::base::WriteStringToFd("100\n", status_fd.get()); return 0; }
int clear_recovery_flag(void) { int ret = 0, i = 0; int len = sizeof(struct bootloader_message); struct bootloader_message *bm = (struct bootloader_message *)malloc(len); printf("clear recovery flag...\n"); memset((void *)bm, 0, len); ret = write_bootloader_message((void *)bm, len); if(ret != 0) { printf("[Lenovo] Fail to clear recovery flag\n"); return -1; } return 0; }
static bool setup_bcb(const int socket) { // c5. receive message length int length; if (!android::base::ReadFully(socket, &length, 4)) { PLOG(ERROR) << "failed to read the length"; return false; } length = ntohl(length); // c7. receive message std::string content; content.resize(length); if (!android::base::ReadFully(socket, &content[0], length)) { PLOG(ERROR) << "failed to read the message"; return false; } LOG(INFO) << " received command: [" << content << "] (" << content.size() << ")"; std::vector<std::string> options = android::base::Split(content, "\n"); std::string wipe_package; for (auto& option : options) { if (android::base::StartsWith(option, "--wipe_package=")) { std::string path = option.substr(strlen("--wipe_package=")); if (!android::base::ReadFileToString(path, &wipe_package)) { PLOG(ERROR) << "failed to read " << path; return false; } option = android::base::StringPrintf("--wipe_package_size=%zu", wipe_package.size()); } } // c8. setup the bcb command std::string err; if (!write_bootloader_message(options, &err)) { LOG(ERROR) << "failed to set bootloader message: " << err; write_status_to_socket(-1, socket); return false; } if (!wipe_package.empty() && !write_wipe_package(wipe_package, &err)) { PLOG(ERROR) << "failed to set wipe package: " << err; write_status_to_socket(-1, socket); return false; } // c10. send "100" status write_status_to_socket(100, socket); return true; }
int set_bootloader_message(void) { int ret = 0, i = 0; int len = sizeof(struct bootloader_message); struct bootloader_message *bm = (struct bootloader_message *)malloc(len); printf("set recovery flag...\n"); memset((void *)bm, 0, len); strncpy(bm->command, "boot-recovery", sizeof(bm->command)); strncpy(bm->recovery, "recovery\n" RECOVERY_SHOW_TEXT, sizeof(bm->recovery)); printf("%s:%s\n", bm->command, bm->recovery); ret = write_bootloader_message((void *)bm, len); if(ret != 0) { printf("[Lenovo] Fail to set recovery flag\n"); return -1; } return 0; }
static bool reboot_service_impl(int fd, const char* arg) { const char* reboot_arg = arg; bool auto_reboot = false; if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) { auto_reboot = true; reboot_arg = "sideload"; } // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot" // in the command file. if (strcmp(reboot_arg, "sideload") == 0) { if (getuid() != 0) { WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n"); return false; } const std::vector<std::string> options = { auto_reboot ? "--sideload_auto_reboot" : "--sideload" }; std::string err; if (!write_bootloader_message(options, &err)) { D("Failed to set bootloader message: %s", err.c_str()); return false; } reboot_arg = "recovery"; } sync(); std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg); if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) { WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str()); return false; } return true; }
static int setup_bcb(const std::string& command_file, const std::string& status_file) { unique_fd status_fd(open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR)); if (!status_fd) { ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno)); return 1; } std::string content; if (!android::base::ReadFileToString(command_file, &content)) { ALOGE("failed to read \"%s\": %s", command_file.c_str(), strerror(errno)); android::base::WriteStringToFd("-1\n", status_fd.get()); return 1; } bootloader_message boot = {}; strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); strlcat(boot.recovery, content.c_str(), sizeof(boot.recovery)); if (write_bootloader_message(&boot) != 0) { ALOGE("failed to set bootloader message"); android::base::WriteStringToFd("-1\n", status_fd.get()); return 1; } android::base::WriteStringToFd("100\n", status_fd.get()); return 0; }