From a58beade0a4f5342f5dcd3b3a597f9183de92260 Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Thu, 27 Sep 2012 09:49:29 -0400 Subject: Port reboot functions to C++ --- Android.mk | 4 +- common.h | 2 + data.cpp | 12 ++--- extra-functions.c | 93 -------------------------------------- extra-functions.h | 4 -- gui/action.cpp | 23 +++++----- partition.cpp | 1 - reboot.c | 71 ----------------------------- recovery.cpp | 5 ++- tw_reboot.h | 42 ------------------ twrp-functions.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ twrp-functions.hpp | 17 +++++++ 12 files changed, 166 insertions(+), 236 deletions(-) delete mode 100644 reboot.c delete mode 100644 tw_reboot.h diff --git a/Android.mk b/Android.mk index e13af68be..bd4902d39 100644 --- a/Android.mk +++ b/Android.mk @@ -39,9 +39,7 @@ LOCAL_SRC_FILES += \ twrp-functions.cpp \ openrecoveryscript.cpp -ifeq ($(TARGET_RECOVERY_REBOOT_SRC),) - LOCAL_SRC_FILES += reboot.c -else +ifneq ($(TARGET_RECOVERY_REBOOT_SRC),) LOCAL_SRC_FILES += $(TARGET_RECOVERY_REBOOT_SRC) endif diff --git a/common.h b/common.h index 37c0e4cff..7bd769a34 100644 --- a/common.h +++ b/common.h @@ -23,6 +23,8 @@ extern "C" { #endif +static long tmplog_offset = 0; + #define ui_print(...) gui_print(__VA_ARGS__) #define ui_print_overwrite(...) gui_print_overwrite(__VA_ARGS__) diff --git a/data.cpp b/data.cpp index 9c53c46f1..ab240a7a4 100644 --- a/data.cpp +++ b/data.cpp @@ -44,13 +44,9 @@ extern "C" { #include "common.h" #include "data.h" - #include "tw_reboot.h" - #include "roots.h" #include "gui/pages.h" void gui_notifyVarChange(const char *name, const char* value); - - int __system(const char *command); } #define FILE_VERSION 0x00010001 @@ -627,17 +623,17 @@ void DataManager::SetDefaultValues() #endif #endif - mConstValues.insert(make_pair(TW_REBOOT_SYSTEM, tw_isRebootCommandSupported(rb_system) ? "1" : "0")); + mConstValues.insert(make_pair(TW_REBOOT_SYSTEM, "1")); #ifdef TW_NO_REBOOT_RECOVERY mConstValues.insert(make_pair(TW_REBOOT_RECOVERY, "0")); #else - mConstValues.insert(make_pair(TW_REBOOT_RECOVERY, tw_isRebootCommandSupported(rb_recovery) ? "1" : "0")); + mConstValues.insert(make_pair(TW_REBOOT_RECOVERY, "1")); #endif - mConstValues.insert(make_pair(TW_REBOOT_POWEROFF, tw_isRebootCommandSupported(rb_poweroff) ? "1" : "0")); + mConstValues.insert(make_pair(TW_REBOOT_POWEROFF, "1")); #ifdef TW_NO_REBOOT_BOOTLOADER mConstValues.insert(make_pair(TW_REBOOT_BOOTLOADER, "0")); #else - mConstValues.insert(make_pair(TW_REBOOT_BOOTLOADER, tw_isRebootCommandSupported(rb_bootloader) ? "1" : "0")); + mConstValues.insert(make_pair(TW_REBOOT_BOOTLOADER, "1")); #endif #ifdef RECOVERY_SDCARD_ON_DATA mConstValues.insert(make_pair(TW_HAS_DATA_MEDIA, "1")); diff --git a/extra-functions.c b/extra-functions.c index 763098da3..f202aff33 100644 --- a/extra-functions.c +++ b/extra-functions.c @@ -55,21 +55,6 @@ void run_script(const char *str1, const char *str2, const char *str3, const char } } -void check_and_run_script(const char* script_file, const char* display_name) -{ - // Check for and run startup script if script exists - struct stat st; - if (stat(script_file, &st) == 0) { - ui_print("Running %s script...\n", display_name); - char command[255]; - strcpy(command, "chmod 755 "); - strcat(command, script_file); - system(command); - system(script_file); - ui_print("\nFinished running %s script.\n", display_name); - } -} - int check_backup_name(int show_error) { // Check the backup name to ensure that it is the correct size and contains only valid characters // and that a backup with that name doesn't already exist @@ -118,81 +103,3 @@ int check_backup_name(int show_error) { // No problems found, return 0 return 0; } - -static const char *COMMAND_FILE = "/cache/recovery/command"; -static const char *INTENT_FILE = "/cache/recovery/intent"; -static const char *LOG_FILE = "/cache/recovery/log"; -static const char *LAST_LOG_FILE = "/cache/recovery/last_log"; -static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install"; -static const char *CACHE_ROOT = "/cache"; -static const char *SDCARD_ROOT = "/sdcard"; -static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; -static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install"; - -// close a file, log an error if the error indicator is set -static void check_and_fclose(FILE *fp, const char *name) { - fflush(fp); - if (ferror(fp)) LOGE("Error in %s\n(%s)\n", name, strerror(errno)); - fclose(fp); -} - -static void copy_log_file(const char* source, const char* destination, int append) { - FILE *log = fopen_path(destination, append ? "a" : "w"); - if (log == NULL) { - LOGE("Can't open %s\n", destination); - } else { - FILE *tmplog = fopen(source, "r"); - if (tmplog != NULL) { - if (append) { - fseek(tmplog, tmplog_offset, SEEK_SET); // Since last write - } - char buf[4096]; - while (fgets(buf, sizeof(buf), tmplog)) fputs(buf, log); - if (append) { - tmplog_offset = ftell(tmplog); - } - check_and_fclose(tmplog, source); - } - check_and_fclose(log, destination); - } -} - -// clear the recovery command and prepare to boot a (hopefully working) system, -// copy our log file to cache as well (for the system to read), and -// record any intent we were asked to communicate back to the system. -// this function is idempotent: call it as many times as you like. -void twfinish_recovery(const char *send_intent) { - // By this point, we're ready to return to the main system... - if (send_intent != NULL) { - FILE *fp = fopen_path(INTENT_FILE, "w"); - if (fp == NULL) { - LOGE("Can't open %s\n", INTENT_FILE); - } else { - fputs(send_intent, fp); - check_and_fclose(fp, INTENT_FILE); - } - } - - // Copy logs to cache so the system can find out what happened. - copy_log_file(TEMPORARY_LOG_FILE, LOG_FILE, true); - copy_log_file(TEMPORARY_LOG_FILE, LAST_LOG_FILE, false); - copy_log_file(TEMPORARY_INSTALL_FILE, LAST_INSTALL_FILE, false); - chmod(LOG_FILE, 0600); - chown(LOG_FILE, 1000, 1000); // system user - chmod(LAST_LOG_FILE, 0640); - chmod(LAST_INSTALL_FILE, 0644); - - // Reset to normal system boot so recovery won't cycle indefinitely. - struct bootloader_message boot; - memset(&boot, 0, sizeof(boot)); - set_bootloader_message(&boot); - - // Remove the command file, so recovery won't repeat indefinitely. - if (system("mount /cache") != 0 || - (unlink(COMMAND_FILE) && errno != ENOENT)) { - LOGW("Can't unlink %s\n", COMMAND_FILE); - } - - system("umount /cache"); - sync(); // For good measure. -} diff --git a/extra-functions.h b/extra-functions.h index f355cdc45..114c9022b 100644 --- a/extra-functions.h +++ b/extra-functions.h @@ -4,12 +4,8 @@ #include "mincrypt/rsa.h" #include "minzip/Zip.h" -static long tmplog_offset = 0; - void run_script(const char *str1, const char *str2, const char *str3, const char *str4, const char *str5, const char *str6, const char *str7, int request_confirm); -void check_and_run_script(const char* script_file, const char* display_name); int check_backup_name(int show_error); -void twfinish_recovery(const char *send_intent); #endif // _EXTRAFUNCTIONS_HEADER diff --git a/gui/action.cpp b/gui/action.cpp index d63693440..7d6686121 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -27,7 +27,6 @@ extern "C" { #include "../common.h" -#include "../tw_reboot.h" #include "../minuitwrp/minui.h" #include "../recovery_ui.h" #include "../extra-functions.h" @@ -314,16 +313,16 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) sync(); - if (arg == "recovery") - tw_reboot(rb_recovery); - else if (arg == "poweroff") - tw_reboot(rb_poweroff); - else if (arg == "bootloader") - tw_reboot(rb_bootloader); - else if (arg == "download") - tw_reboot(rb_download); - else - tw_reboot(rb_system); + if (arg == "recovery") + TWFunc::tw_reboot(rb_recovery); + else if (arg == "poweroff") + TWFunc::tw_reboot(rb_poweroff); + else if (arg == "bootloader") + TWFunc::tw_reboot(rb_bootloader); + else if (arg == "download") + TWFunc::tw_reboot(rb_download); + else + TWFunc::tw_reboot(rb_system); // This should never occur return -1; @@ -1051,7 +1050,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) ui_print("Processing OpenRecoveryScript file...\n"); if (OpenRecoveryScript::run_script_file() == 0) { usleep(2000000); // Sleep for 2 seconds before rebooting - tw_reboot(rb_system); + TWFunc::tw_reboot(rb_system); load_theme = 0; } } diff --git a/partition.cpp b/partition.cpp index 4d1c9c5ad..12e1f5339 100644 --- a/partition.cpp +++ b/partition.cpp @@ -42,7 +42,6 @@ extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" - #include "extra-functions.h" } TWPartition::TWPartition(void) { diff --git a/reboot.c b/reboot.c deleted file mode 100644 index 9d87ff21d..000000000 --- a/reboot.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -//#include -#include - -#include "tw_reboot.h" -#include "recovery_ui.h" -#include "roots.h" -#include "extra-functions.h" -#include "data.h" -#include "variables.h" - -// isRebootCommandSupported: Return 1 if command is supported, 0 if the command is not supported, -1 on error -int tw_isRebootCommandSupported(RebootCommand command) -{ - switch (command) - { - case rb_system: - case rb_recovery: - case rb_poweroff: - case rb_bootloader: - case rb_download: - return 1; - - default: - return 0; - } - return -1; -} - -// setRebootMode: Set the reboot state (without rebooting). Return 0 on success, -1 on error or unsupported -int tw_setRebootMode(RebootCommand command) -{ - return -1; -} - -// reboot: Reboot the system. Return -1 on error, no return on success -int tw_reboot(RebootCommand command) -{ - // Always force a sync before we reboot - sync(); - - switch (command) - { - case rb_current: - case rb_system: - twfinish_recovery("s"); - sync(); - check_and_run_script("/sbin/rebootsystem.sh", "reboot system"); - return reboot(RB_AUTOBOOT); - case rb_recovery: - check_and_run_script("/sbin/rebootrecovery.sh", "reboot recovery"); - return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "recovery"); - case rb_bootloader: - check_and_run_script("/sbin/rebootbootloader.sh", "reboot bootloader"); - return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "bootloader"); - case rb_poweroff: - check_and_run_script("/sbin/poweroff.sh", "power off"); - return reboot(RB_POWER_OFF); - case rb_download: - check_and_run_script("/sbin/rebootdownload.sh", "reboot download"); - return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "download"); - return 1; - default: - return -1; - } - return -1; -} - diff --git a/recovery.cpp b/recovery.cpp index d6ed79c7e..35e61162e 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -57,6 +57,7 @@ extern "C" { #include "partitions.hpp" #include "variables.h" #include "openrecoveryscript.hpp" +#include "twrp-functions.hpp" TWPartitionManager PartitionManager; @@ -887,8 +888,8 @@ main(int argc, char **argv) { printf("\n"); // Check for and run startup script if script exists - check_and_run_script("/sbin/runatboot.sh", "boot"); - check_and_run_script("/sbin/postrecoveryboot.sh", "boot"); + TWFunc::check_and_run_script("/sbin/runatboot.sh", "boot"); + TWFunc::check_and_run_script("/sbin/postrecoveryboot.sh", "boot"); #ifdef TW_INCLUDE_INJECTTWRP // Back up TWRP Ramdisk if needed: diff --git a/tw_reboot.h b/tw_reboot.h deleted file mode 100644 index e04c0a76c..000000000 --- a/tw_reboot.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef REBOOT_H_ -#define REBOOT_H_ - -typedef enum -{ - rb_current = 0, - rb_system, - rb_recovery, - rb_poweroff, - rb_bootloader, // May also be fastboot - rb_download, -} RebootCommand; - -// tw_isRebootCommandSupported: Return 1 if command is supported, 0 if the command is not supported, -1 on error -int tw_isRebootCommandSupported(RebootCommand command); - -// tw_setRebootMode: Set the reboot state (without rebooting). Return 0 on success, -1 on error or unsupported -int tw_setRebootMode(RebootCommand command); - -// tw_reboot: Reboot the system. Return -1 on error, no return on success -int tw_reboot(RebootCommand command); - -#endif // REBOOT_H_ - - - diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 066e6e57b..28d0ba58e 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -8,11 +8,13 @@ #include #include #include +#include #include "twrp-functions.hpp" #include "partitions.hpp" #include "common.h" #include "data.hpp" +#include "bootloader.h" /* Checks md5 for a path Return values: @@ -257,4 +259,130 @@ unsigned long TWFunc::Get_File_Size(string Path) { if (stat(Path.c_str(), &st) != 0) return 0; return st.st_size; +} + +static const char *COMMAND_FILE = "/cache/recovery/command"; +static const char *INTENT_FILE = "/cache/recovery/intent"; +static const char *LOG_FILE = "/cache/recovery/log"; +static const char *LAST_LOG_FILE = "/cache/recovery/last_log"; +static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install"; +static const char *CACHE_ROOT = "/cache"; +static const char *SDCARD_ROOT = "/sdcard"; +static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; +static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install"; + +// close a file, log an error if the error indicator is set +void TWFunc::check_and_fclose(FILE *fp, const char *name) { + fflush(fp); + if (ferror(fp)) LOGE("Error in %s\n(%s)\n", name, strerror(errno)); + fclose(fp); +} + +void TWFunc::copy_log_file(const char* source, const char* destination, int append) { + FILE *log = fopen_path(destination, append ? "a" : "w"); + if (log == NULL) { + LOGE("Can't open %s\n", destination); + } else { + FILE *tmplog = fopen(source, "r"); + if (tmplog != NULL) { + if (append) { + fseek(tmplog, tmplog_offset, SEEK_SET); // Since last write + } + char buf[4096]; + while (fgets(buf, sizeof(buf), tmplog)) fputs(buf, log); + if (append) { + tmplog_offset = ftell(tmplog); + } + check_and_fclose(tmplog, source); + } + check_and_fclose(log, destination); + } +} + +// clear the recovery command and prepare to boot a (hopefully working) system, +// copy our log file to cache as well (for the system to read), and +// record any intent we were asked to communicate back to the system. +// this function is idempotent: call it as many times as you like. +void TWFunc::twfinish_recovery(const char *send_intent) { + // By this point, we're ready to return to the main system... + if (send_intent != NULL) { + FILE *fp = fopen_path(INTENT_FILE, "w"); + if (fp == NULL) { + LOGE("Can't open %s\n", INTENT_FILE); + } else { + fputs(send_intent, fp); + check_and_fclose(fp, INTENT_FILE); + } + } + + // Copy logs to cache so the system can find out what happened. + copy_log_file(TEMPORARY_LOG_FILE, LOG_FILE, true); + copy_log_file(TEMPORARY_LOG_FILE, LAST_LOG_FILE, false); + copy_log_file(TEMPORARY_INSTALL_FILE, LAST_INSTALL_FILE, false); + chmod(LOG_FILE, 0600); + chown(LOG_FILE, 1000, 1000); // system user + chmod(LAST_LOG_FILE, 0640); + chmod(LAST_INSTALL_FILE, 0644); + + // Reset to normal system boot so recovery won't cycle indefinitely. + struct bootloader_message boot; + memset(&boot, 0, sizeof(boot)); + set_bootloader_message(&boot); + + // Remove the command file, so recovery won't repeat indefinitely. + if (system("mount /cache") != 0 || + (unlink(COMMAND_FILE) && errno != ENOENT)) { + LOGW("Can't unlink %s\n", COMMAND_FILE); + } + + system("umount /cache"); + sync(); // For good measure. +} + +// reboot: Reboot the system. Return -1 on error, no return on success +int TWFunc::tw_reboot(RebootCommand command) +{ + // Always force a sync before we reboot + sync(); + + switch (command) + { + case rb_current: + case rb_system: + twfinish_recovery("s"); + sync(); + check_and_run_script("/sbin/rebootsystem.sh", "reboot system"); + return reboot(RB_AUTOBOOT); + case rb_recovery: + check_and_run_script("/sbin/rebootrecovery.sh", "reboot recovery"); + return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "recovery"); + case rb_bootloader: + check_and_run_script("/sbin/rebootbootloader.sh", "reboot bootloader"); + return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "bootloader"); + case rb_poweroff: + check_and_run_script("/sbin/poweroff.sh", "power off"); + return reboot(RB_POWER_OFF); + case rb_download: + check_and_run_script("/sbin/rebootdownload.sh", "reboot download"); + return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "download"); + return 1; + default: + return -1; + } + return -1; +} + +void TWFunc::check_and_run_script(const char* script_file, const char* display_name) +{ + // Check for and run startup script if script exists + struct stat st; + if (stat(script_file, &st) == 0) { + ui_print("Running %s script...\n", display_name); + char command[255]; + strcpy(command, "chmod 755 "); + strcat(command, script_file); + system(command); + system(script_file); + ui_print("\nFinished running %s script.\n", display_name); + } } \ No newline at end of file diff --git a/twrp-functions.hpp b/twrp-functions.hpp index aebd7c3ef..7bda28725 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -5,6 +5,16 @@ using namespace std; +typedef enum +{ + rb_current = 0, + rb_system, + rb_recovery, + rb_poweroff, + rb_bootloader, // May also be fastboot + rb_download, +} RebootCommand; + // Partition class class TWFunc { @@ -23,6 +33,13 @@ public: static void GUI_Operation_Text(string Read_Value, string Default_Text); // Updates text for display in the GUI, e.g. Backing up %partition name% static void GUI_Operation_Text(string Read_Value, string Partition_Name, string Default_Text); // Same as above but includes partition name static unsigned long Get_File_Size(string Path); // Returns the size of a file + static void twfinish_recovery(const char *send_intent); + static int tw_reboot(RebootCommand command); + static void check_and_run_script(const char* script_file, const char* display_name); + +private: + static void check_and_fclose(FILE *fp, const char *name); + static void copy_log_file(const char* source, const char* destination, int append); }; -- cgit v1.2.3