int main(int argc, char *argv[]) { enum { OPT_NO_LOG_FILE = 1000, }; static struct option long_options[] = { { "no-log-file", no_argument, 0, OPT_NO_LOG_FILE }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; int opt; int long_index = 0; bool no_log_file = false; while ((opt = getopt_long(argc, argv, "h", long_options, &long_index)) != -1) { switch (opt) { case OPT_NO_LOG_FILE: no_log_file = true; break; case 'h': usage(stdout); return EXIT_SUCCESS; default: usage(stderr); return EXIT_FAILURE; } } // There should be one other argument if (argc - optind != 1) { usage(stderr); return EXIT_FAILURE; } umask(0); if (!mb::util::mkdir_recursive(MBBOOTUI_BASE_PATH, 0755)) { LOGE("%s: Failed to create directory: %s", MBBOOTUI_BASE_PATH, strerror(errno)); return EXIT_FAILURE; } // Rotate log if it is too large struct stat sb; if (stat(MBBOOTUI_LOG_PATH, &sb) == 0 && sb.st_size > MAX_LOG_SIZE) { rename(MBBOOTUI_LOG_PATH, MBBOOTUI_LOG_PATH ".prev"); } if (!no_log_file && !redirect_output_to_file(MBBOOTUI_LOG_PATH, 0600)) { return EXIT_FAILURE; } signal(SIGPIPE, SIG_IGN); // Set paths tw_resource_path = MBBOOTUI_THEME_PATH; tw_settings_path = MBBOOTUI_SETTINGS_PATH; tw_screenshots_path = MBBOOTUI_SCREENSHOTS_PATH; // Disallow custom themes, which could manipulate variables in such as way // as to execute malicious code tw_theme_zip_path = ""; if (!detect_device()) { return EXIT_FAILURE; } // Check if device supports the boot UI if (!device->twOptions()->supported) { LOGW("Boot UI is not supported for the device"); return EXIT_FAILURE; } // Load device configuration options load_device_config(); load_other_config(); log_startup(); if (!extract_theme(argv[optind], MBBOOTUI_THEME_PATH, device->twOptions()->theme)) { LOGE("Failed to extract theme"); return EXIT_FAILURE; } // Connect to daemon if (!mbtool_connection.connect()) { LOGE("Failed to connect to mbtool"); return EXIT_FAILURE; } mbtool_interface = mbtool_connection.interface(); LOGV("Loading default values..."); DataManager::SetDefaultValues(); // Set daemon version std::string mbtool_version; mbtool_interface->version(&mbtool_version); DataManager::SetValue(TW_MBTOOL_VERSION, mbtool_version); LOGV("Loading graphics system..."); if (gui_init() < 0) { LOGE("Failed to load graphics system"); return EXIT_FAILURE; } LOGV("Loading resources..."); gui_loadResources(); LOGV("Checking for encryption..."); char crypto_state[PROP_VALUE_MAX]; mb::util::property_get(PROP_CRYPTO_STATE, crypto_state, CRYPTO_STATE_DECRYPTED); if (strcmp(crypto_state, CRYPTO_STATE_ENCRYPTED) == 0) { LOGV("Data appears to be encrypted"); int is_encrypted = 1; // Ask mbtool for password type std::string pw_type; if (!mbtool_interface->crypto_get_pw_type(&pw_type)) { LOGE("Failed to ask mbtool for the crypto password type"); return EXIT_FAILURE; } // If password type is unknown, assume "password" if (pw_type.empty()) { LOGW("Crypto password type is unknown. Assuming 'password'"); pw_type = "password"; } // Try default password if (pw_type == "default") { bool ret; if (!mbtool_interface->crypto_decrypt("default_password", &ret)) { LOGE("Failed to ask mbtool to decrypt userdata"); return EXIT_FAILURE; } if (ret) { LOGV("Successfully decrypted device with default password"); is_encrypted = 0; } else { LOGW("Failed to decrypt device with default password despite " "password type being 'default'"); pw_type = "password"; } } DataManager::SetValue(TW_IS_ENCRYPTED, is_encrypted); DataManager::SetValue(TW_CRYPTO_PWTYPE, pw_type); DataManager::SetValue(TW_CRYPTO_PASSWORD, ""); DataManager::SetValue("tw_crypto_display", ""); if (is_encrypted) { LOGV("Showing decrypt page first due to encrypted device"); gui_startPage("decrypt", 1, 1); } if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) { LOGE("Decrypt page exited, but device is still encrypted"); mb::util::property_set(PROP_CRYPTO_STATE, CRYPTO_STATE_ERROR); return EXIT_FAILURE; } else { LOGV("Decrypt page exited and device was successfully decrypted"); mb::util::property_set(PROP_CRYPTO_STATE, CRYPTO_STATE_DECRYPTED); } } // Set ROM ID. This must happen after decryption or else the current ROM // will not be detected if it is a data-slot. mbtool's ROM detection code // doesn't fully trust the "ro.multiboot.romid" property and will do some // additional checks to ensure that the value is correct. std::string rom_id; mbtool_interface->get_booted_rom_id(&rom_id); if (rom_id.empty()) { LOGW("Could not determine ROM ID"); } DataManager::SetValue(TW_ROM_ID, rom_id); LOGV("Loading user settings..."); DataManager::ReadSettingsFile(); LOGV("Loading language..."); PageManager::LoadLanguage(DataManager::GetStrValue(TW_LANGUAGE)); GUIConsole::Translate_Now(); LOGV("Fixing time..."); TWFunc::Fixup_Time_On_Boot(); LOGV("Loading main UI..."); //gui_start(); gui_startPage("autoboot", 1, 0); // Exit action std::string exit_action; DataManager::GetValue(TW_EXIT_ACTION, exit_action); std::vector<std::string> args = mb::util::split(exit_action, ","); // Save settings DataManager::Flush(); if (args.size() > 0) { if (args[0] == "reboot") { std::string reboot_arg; if (args.size() > 1) { reboot_arg = args[1]; } bool result; mbtool_interface->reboot(reboot_arg, &result); wait_forever(); } else if (args[0] == "shutdown") { bool result; mbtool_interface->shutdown(&result); wait_forever(); } } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { enum { OPT_NO_LOG_FILE = 1000, }; static struct option long_options[] = { { "no-log-file", no_argument, 0, OPT_NO_LOG_FILE }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; int opt; int long_index = 0; bool no_log_file = false; while ((opt = getopt_long(argc, argv, "h", long_options, &long_index)) != -1) { switch (opt) { case OPT_NO_LOG_FILE: no_log_file = true; break; case 'h': usage(stdout); return EXIT_SUCCESS; default: usage(stderr); return EXIT_FAILURE; } } // There should be one other argument if (argc - optind != 1) { usage(stderr); return EXIT_FAILURE; } umask(0); if (!mb::util::mkdir_recursive(MBBOOTUI_BASE_PATH, 0755)) { LOGE("%s: Failed to create directory: %s", MBBOOTUI_BASE_PATH, strerror(errno)); return EXIT_FAILURE; } if (!no_log_file && !redirect_output_to_file(MBBOOTUI_LOG_PATH, 0600)) { return EXIT_FAILURE; } signal(SIGPIPE, SIG_IGN); // Set paths tw_resource_path = MBBOOTUI_THEME_PATH; tw_settings_path = MBBOOTUI_SETTINGS_PATH; tw_screenshots_path = MBBOOTUI_SCREENSHOTS_PATH; // Disallow custom themes, which could manipulate variables in such as way // as to execute malicious code tw_theme_zip_path = ""; if (!detect_device()) { return EXIT_FAILURE; } // Check if device supports the boot UI if (!device->twOptions()->supported) { LOGW("Boot UI is not supported for the device"); return EXIT_FAILURE; } // Load device configuration options load_device_config(); log_startup(); if (!extract_theme(argv[optind], MBBOOTUI_THEME_PATH, device->twOptions()->theme)) { LOGE("Failed to extract theme"); return EXIT_FAILURE; } // Connect to daemon if (!mbtool_connection.connect()) { LOGE("Failed to connect to mbtool"); return EXIT_FAILURE; } mbtool_interface = mbtool_connection.interface(); LOGV("Loading default values..."); DataManager::SetDefaultValues(); // Set daemon version std::string mbtool_version; mbtool_interface->version(&mbtool_version); DataManager::SetValue(TW_MBTOOL_VERSION, mbtool_version); // Set ROM ID std::string rom_id; mbtool_interface->get_booted_rom_id(&rom_id); DataManager::SetValue(TW_ROM_ID, rom_id); LOGV("Loading graphics system..."); if (gui_init() < 0) { LOGE("Failed to load graphics system"); return EXIT_FAILURE; } LOGV("Loading resources..."); gui_loadResources(); LOGV("Loading user settings..."); DataManager::ReadSettingsFile(); LOGV("Loading language..."); PageManager::LoadLanguage(DataManager::GetStrValue(TW_LANGUAGE)); GUIConsole::Translate_Now(); LOGV("Fixing time..."); TWFunc::Fixup_Time_On_Boot(); LOGV("Loading main UI..."); //gui_start(); gui_startPage("autoboot", 1, 0); // Exit action std::string exit_action; DataManager::GetValue(TW_EXIT_ACTION, exit_action); std::vector<std::string> args = mb::util::split(exit_action, ","); // Save settings DataManager::Flush(); if (args.size() > 0) { if (args[0] == "reboot") { std::string reboot_arg; if (args.size() > 1) { reboot_arg = args[1]; } bool result; mbtool_interface->reboot(reboot_arg, &result); wait_forever(); } else if (args[0] == "shutdown") { bool result; mbtool_interface->shutdown(&result); wait_forever(); } } return EXIT_SUCCESS; }