static struct selabel_handle* get_sehnd(const char* context_file) { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, context_file } }; struct selabel_handle* sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehnd) { perror("error running selabel_open"); exit(EXIT_FAILURE); } return sehnd; }
struct selabel_handle* selinux_android_prop_context_handle(void) { int policy_index = selinux_android_use_data_policy() ? 1 : 0; struct selabel_handle* sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP, &seopts_prop[policy_index], 1); if (!sehandle) { ERROR("SELinux: Could not load property_contexts: %s\n", strerror(errno)); return NULL; } INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[policy_index].value); return sehandle; }
/* * Open the label handle * returns 1 on success, 0 if no selinux, negative on error */ int selinux_util_open(void) { int retval = 0; retval = is_selinux_enabled(); if (retval <= 0) return retval; hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (!hnd) return -2; return 1; }
/* Set fcon to the appropriate label for path and mode, or return -1. */ static int getContext(const char *newpath, mode_t mode, security_context_t *fcon) { #if HAVE_SELINUX_LABEL_H struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0); int ret; if (handle == NULL) return -1; ret = selabel_lookup(handle, fcon, newpath, mode); selabel_close(handle); return ret; #else return matchpathcon(newpath, mode, fcon); #endif }
struct selabel_handle* selinux_android_prop_context_handle(void) { int i = 0; struct selabel_handle* sehandle = NULL; while ((sehandle == NULL) && seopts_prop[i].value) { sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP, &seopts_prop[i], 1); i++; } if (!sehandle) { ERROR("SELinux: Could not load property_contexts: %s\n", strerror(errno)); return NULL; } INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[i - 1].value); return sehandle; }
static void do_compare_and_die_on_error(struct selinux_opt opts[], unsigned int backend, char *paths[]) { enum selabel_cmp_result result; char *result_str[] = { "subset", "equal", "superset", "incomparable" }; int i; opts[0].value = NULL; /* not validating against a policy when comparing */ for (i = 0; i < SEHANDLE_CNT; i++) { opts[1].value = paths[i]; global_state.sepolicy.sehnd[i] = selabel_open(backend, opts, 2); if (!global_state.sepolicy.sehnd[i]) { fprintf(stderr, "Error: could not load context file from %s\n", paths[i]); exit(1); } } result = selabel_cmp(global_state.sepolicy.sehnd[0], global_state.sepolicy.sehnd[1]); printf("%s\n", result_str[result]); }
int main(int argc, char **argv) { struct statfs buf; int ret = 0; /* Files written only read/writable by root */ umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* initialize libmicroui */ #ifdef USE_GUI mui_init(); #endif pr_info(" -- UserFastBoot %s for %s --\n", USERFASTBOOT_VERSION, DEVICE_NAME); mui_set_background(BACKGROUND_ICON_INSTALLING); struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { pr_error("Warning: No file_contexts\n"); } load_volume_table(); aboot_register_commands(); register_userfastboot_plugins(); ret = statfs("/tmp", &buf); if (!ret){ unsigned long size = buf.f_bsize * buf.f_bfree; fastboot_init(size); } else pr_error("Error when acuiring tmpfs size:-%d\n", errno); /* Shouldn't get here */ exit(1); }
int label_init(void) { int r = 0; #ifdef HAVE_SELINUX if (!use_selinux()) return 0; if (label_hnd) return 0; label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (!label_hnd) { log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, "Failed to initialize SELinux context: %m"); r = security_getenforce() == 1 ? -errno : 0; } #endif return r; }
void dpkg_selabel_load(void) { #ifdef WITH_LIBSELINUX static int selinux_enabled = -1; if (selinux_enabled < 0) { int rc; /* Set selinux_enabled if it is not already set (singleton). */ selinux_enabled = (in_force(FORCE_SECURITY_MAC) && is_selinux_enabled() > 0); if (!selinux_enabled) return; /* Open the SELinux status notification channel, with fallback * enabled for older kernels. */ rc = selinux_status_open(1); if (rc < 0) ohshit(_("cannot open security status notification channel")); /* XXX: We could use selinux_set_callback() to redirect the * errors from the other SELinux calls, but that does not seem * worth it right now. */ } else if (selinux_enabled && selinux_status_updated()) { /* The SELinux policy got updated in the kernel, usually after * upgrading the package shipping it, we need to reload. */ selabel_close(sehandle); } else { /* SELinux is either disabled or it does not need a reload. */ return; } sehandle = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (sehandle == NULL && security_getenforce() == 1) ohshite(_("cannot get security labeling handle")); #endif }
int mac_selinux_init(const char *prefix) { int r = 0; #ifdef HAVE_SELINUX usec_t before_timestamp, after_timestamp; struct mallinfo before_mallinfo, after_mallinfo; if (!mac_selinux_use()) return 0; if (label_hnd) return 0; before_mallinfo = mallinfo(); before_timestamp = now(CLOCK_MONOTONIC); if (prefix) { struct selinux_opt options[] = { { .type = SELABEL_OPT_SUBSET, .value = prefix }, }; label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); } else
int mac_selinux_init(void) { int r = 0; #ifdef HAVE_SELINUX usec_t before_timestamp, after_timestamp; struct mallinfo before_mallinfo, after_mallinfo; if (label_hnd) return 0; if (!mac_selinux_use()) return 0; before_mallinfo = mallinfo(); before_timestamp = now(CLOCK_MONOTONIC); label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (!label_hnd) { log_enforcing("Failed to initialize SELinux context: %m"); r = security_getenforce() == 1 ? -errno : 0; } else { char timespan[FORMAT_TIMESPAN_MAX]; int l; after_timestamp = now(CLOCK_MONOTONIC); after_mallinfo = mallinfo(); l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.", format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0), (l+1023)/1024); } #endif return r; }
int main(int argc, char *argv[]) { int fixstats = 0; struct stat stats; int opt; char *image; char *dir; char *secontext = NULL; while ((opt = getopt(argc, argv, "fc:s:")) != -1) { switch (opt) { case 'f': fixstats = 1; break; case 'c': chunkSize = (unsigned)strtoul(optarg, NULL, 0); break; case 's': spareSize = (unsigned)strtoul(optarg, NULL, 0); break; default: usage(); exit(1); } } if (!chunkSize || !spareSize) { usage(); exit(1); } if ((argc - optind < 2) || (argc - optind > 4)) { usage(); exit(1); } dir = argv[optind]; seprefixlen = strlen(dir); image = argv[optind + 1]; if (optind + 2 < argc) { if (!strncmp(argv[optind + 2], "convert", strlen("convert"))) convert_endian = 1; else { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, argv[optind + 2] } }; sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehnd) { perror(argv[optind + 2]); usage(); exit(1); } if (optind + 3 >= argc) { usage(); exit(1); } mntpoint = argv[optind + 3]; if (optind + 4 < argc) { if (!strncmp(argv[optind + 4], "convert", strlen("convert"))) convert_endian = 1; } } } if(stat(dir,&stats) < 0) { fprintf(stderr,"Could not stat %s\n",dir); exit(1); } if(!S_ISDIR(stats.st_mode)) { fprintf(stderr," %s is not a directory\n",dir); exit(1); } outFile = open(image,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE); if(outFile < 0) { fprintf(stderr,"Could not open output file %s\n",image); exit(1); } if (fixstats) { int len = strlen(dir); if((len >= 4) && (!strcmp(dir + len - 4, "data"))) { source_path_len = len - 4; } else if((len >= 6) && (!strcmp(dir + len - 6, "system"))) { source_path_len = len - 6; } else { fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n"); exit(1); } fix_stat(dir, &stats); } //printf("Processing directory %s into image file %s\n",dir,image); if (sehnd) { char *sepath = NULL; if (mntpoint[0] == '/') sepath = strdup(mntpoint); else if (asprintf(&sepath, "/%s", mntpoint) < 0) sepath = NULL; if (!sepath) { perror("malloc"); exit(1); } if (selabel_lookup(sehnd, &secontext, sepath, stats.st_mode) < 0) { perror("selabel_lookup"); free(sepath); exit(1); } free(sepath); } error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL, secontext); if(error) error = process_directory(YAFFS_OBJECTID_ROOT,dir,fixstats); close(outFile); if(error < 0) { perror("operation incomplete"); exit(1); } else { /* printf("Operation complete.\n" "%d objects in %d directories\n" "%d NAND pages\n",nObjects, nDirectories, nPages); */ } close(outFile); exit(0); }
int main(int argc, char** argv) { // Various things log information to stdout or stderr more or less // at random (though we've tried to standardize on stdout). The // log file makes more sense if buffering is turned off so things // appear in the right order. setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc != 4) { printf("unexpected number of arguments (%d)\n", argc); return 1; } char* version = argv[1]; if ((version[0] != '1' && version[0] != '2' && version[0] != '3') || version[1] != '\0') { // We support version 1, 2, or 3. printf("wrong updater binary API; expected 1, 2, or 3; " "got %s\n", argv[1]); return 2; } // Set up the pipe for sending commands back to the parent process. int fd = atoi(argv[2]); FILE* cmd_pipe = fdopen(fd, "wb"); setlinebuf(cmd_pipe); // Extract the script from the package. const char* package_filename = argv[3]; MemMapping map; if (sysMapFile(package_filename, &map) != 0) { printf("failed to map package %s\n", argv[3]); return 3; } ZipArchive za; int err; err = mzOpenZipArchive(map.addr, map.length, &za); if (err != 0) { printf("failed to open package %s: %s\n", argv[3], strerror(err)); return 3; } const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME); if (script_entry == NULL) { printf("failed to find %s in %s\n", SCRIPT_NAME, package_filename); return 4; } char* script = malloc(script_entry->uncompLen+1); if (!mzReadZipEntry(&za, script_entry, script, script_entry->uncompLen)) { printf("failed to read script from package\n"); return 5; } script[script_entry->uncompLen] = '\0'; const ZipEntry* file_contexts_entry = mzFindZipEntry(&za, SELINUX_CONTEXTS_ZIP); if (file_contexts_entry != NULL) { int file_contexts_fd = creat(SELINUX_CONTEXTS_TMP, 0644); if (file_contexts_fd < 0) { fprintf(stderr, "Could not extract %s to '%s'\n", SELINUX_CONTEXTS_ZIP, SELINUX_CONTEXTS_TMP); return 3; } int ret_val = mzExtractZipEntryToFile(&za, file_contexts_entry, file_contexts_fd); close(file_contexts_fd); if (!ret_val) { fprintf(stderr, "Could not extract '%s'\n", SELINUX_CONTEXTS_ZIP); return 3; } } // Configure edify's functions. RegisterBuiltins(); RegisterInstallFunctions(); RegisterBlockImageFunctions(); RegisterDeviceExtensions(); FinishRegistration(); // Parse the script. Expr* root; int error_count = 0; int error = parse_string(script, &root, &error_count); if (error != 0 || error_count > 0) { printf("%d parse errors\n", error_count); return 6; } if (access(SELINUX_CONTEXTS_TMP, R_OK) == 0) { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, SELINUX_CONTEXTS_TMP } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); } else { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); } if (!sehandle) { fprintf(cmd_pipe, "ui_print Warning: No file_contexts\n"); } // Evaluate the parsed script. UpdaterInfo updater_info; updater_info.cmd_pipe = cmd_pipe; updater_info.package_zip = &za; updater_info.version = atoi(version); updater_info.package_zip_addr = map.addr; updater_info.package_zip_len = map.length; State state; state.cookie = &updater_info; state.script = script; state.errmsg = NULL; char* result = Evaluate(&state, root); if (result == NULL) { if (state.errmsg == NULL) { printf("script aborted (no error message)\n"); fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); } else { printf("script aborted: %s\n", state.errmsg); char* line = strtok(state.errmsg, "\n"); while (line) { fprintf(cmd_pipe, "ui_print %s\n", line); line = strtok(NULL, "\n"); } fprintf(cmd_pipe, "ui_print\n"); } free(state.errmsg); return 7; } else { fprintf(cmd_pipe, "ui_print script succeeded: result was [%s]\n", result); free(result); } if (updater_info.package_zip) { mzCloseZipArchive(updater_info.package_zip); } sysReleaseMap(&map); free(script); return 0; }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (!strcmp(command, "start")) { property_set("ctl.start", argv[1]); return 0; } if (!strcmp(command, "stop")) { property_set("ctl.stop", argv[1]); return 0; } /* Make sure stdout is not fully buffered, we don't want to * have issues when calling busybox commands */ setlinebuf(stdout); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s\n", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); #ifdef BOARD_RECOVERY_SWIPE #ifndef BOARD_TOUCH_RECOVERY //display directions for swipe controls ui_print("Swipe up/down to change selections.\n"); ui_print("Swipe to the right for enter.\n"); ui_print("Swipe to the left for back.\n"); #endif #endif load_volume_table(); process_volumes(); vold_client_start(&v_callbacks, 0); vold_set_automount(1); setup_legacy_storage_paths(); LOGI("Processing arguments.\n"); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; const char *update_ubuntu_package = NULL; const char *user_data_update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; int headless = 0; try_autodeploy(AUTODEPLOY_PACKAGE_FILE); try_autodeploy(AUTODEPLOY_PACKAGE_FILE_MULTI); LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'd': user_data_update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'h': ui_set_background(BACKGROUND_ICON_CID); ui_show_text(0); headless = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case 'v': update_ubuntu_package = UBUNTU_UPDATE_SCRIPT; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Installation aborted.\n"); } } else if (update_ubuntu_package != NULL) { LOGI("Performing Ubuntu update"); ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Installing Ubuntu update.\n"); char tmp[PATH_MAX]; sprintf(tmp, "%s %s", UBUNTU_UPDATE_SCRIPT, UBUNTU_COMMAND_FILE ); __system(tmp); LOGI("Ubuntu update complete"); ui_print("Ubuntu update complete.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; ignore_data_media_workaround(1); if (erase_volume("/data")) status = INSTALL_ERROR; ignore_data_media_workaround(0); if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Data wipe failed.\n"); } } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Cache wipe failed.\n"); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; if (!headless) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_UBUNTU); } if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (sideload) { signature_check_enabled = 0; if (!headless) ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } if (headless) { headless_wait(); } if (user_data_update_package != NULL) { status = install_package(user_data_update_package); if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } else if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // We reach here when in main menu we choose reboot main system or for some wipe commands on start // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); if (strcmp(basename(argv[0]), "recovery") != 0) { if (strstr(argv[0], "minizip") != NULL) return minizip_main(argc, argv); if (strstr(argv[0], "dedupe") != NULL) return dedupe_main(argc, argv); if (strstr(argv[0], "flash_image") != NULL) return flash_image_main(argc, argv); if (strstr(argv[0], "volume") != NULL) return volume_main(argc, argv); if (strstr(argv[0], "edify") != NULL) return edify_main(argc, argv); if (strstr(argv[0], "dump_image") != NULL) return dump_image_main(argc, argv); if (strstr(argv[0], "erase_image") != NULL) return erase_image_main(argc, argv); if (strstr(argv[0], "mkyaffs2image") != NULL) return mkyaffs2image_main(argc, argv); if (strstr(argv[0], "make_ext4fs") != NULL) return make_ext4fs_main(argc, argv); if (strstr(argv[0], "unyaffs") != NULL) return unyaffs_main(argc, argv); if (strstr(argv[0], "nandroid")) return nandroid_main(argc, argv); if (strstr(argv[0], "bu") == argv[0] + strlen(argv[0]) - 2) return bu_main(argc, argv); if (strstr(argv[0], "reboot")) return reboot_main(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount")) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (strstr(argv[0], "poweroff")){ return reboot_main(argc, argv); } if (strstr(argv[0], "setprop")) return setprop_main(argc, argv); if (strstr(argv[0], "getprop")) return getprop_main(argc, argv); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); load_volume_table(); process_volumes(); LOGI("Processing arguments.\n"); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); // ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("命令:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) ui_print("安装失败.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("清空data失败.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("清空cache失败.\n"); } else if (sideload) { signature_check_enabled = 0; ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_CLOCKWORK); if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } setup_adbd(); if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } verify_root_and_recovery(); // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); sync(); if(!poweroff) { ui_print("正在重启...\n"); android_reboot(ANDROID_RB_RESTART, 0, 0); } else { ui_print("正在关机...\n"); android_reboot(ANDROID_RB_POWEROFF, 0, 0); } return EXIT_SUCCESS; }
static void do_fc_check_and_die_on_error(struct selinux_opt opts[], unsigned int backend, filemode mode, const char *sepolicy_file, const char *context_file, bool allow_empty) { struct stat sb; if (stat(context_file, &sb) < 0) { perror("Error: could not get stat on file contexts file"); exit(1); } if (sb.st_size == 0) { /* Nothing to check on empty file_contexts file if allowed*/ if (allow_empty) { return; } /* else: We could throw the error here, but libselinux backend will catch it */ } global_state.sepolicy.file = fopen(sepolicy_file, "r"); if (!global_state.sepolicy.file) { perror("Error: could not open policy file"); exit(1); } global_state.sepolicy.handle = sepol_handle_create(); if (!global_state.sepolicy.handle) { fprintf(stderr, "Error: could not create policy handle: %s\n", strerror(errno)); exit(1); } if (sepol_policy_file_create(&global_state.sepolicy.pf) < 0) { perror("Error: could not create policy handle"); exit(1); } sepol_policy_file_set_fp(global_state.sepolicy.pf, global_state.sepolicy.file); sepol_policy_file_set_handle(global_state.sepolicy.pf, global_state.sepolicy.handle); int rc = sepol_policydb_create(&global_state.sepolicy.sdb); if (rc < 0) { perror("Error: could not create policy db"); exit(1); } rc = sepol_policydb_read(global_state.sepolicy.sdb, global_state.sepolicy.pf); if (rc < 0) { perror("Error: could not read file into policy db"); exit(1); } global_state.assert.attrs = filemode_to_assert_attrs(mode); bool ret = ebitmap_attribute_assertion_init(&global_state.assert.set, global_state.assert.attrs); if (!ret) { /* error messages logged by ebitmap_attribute_assertion_init() */ exit(1); } selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&validate); opts[1].value = context_file; global_state.sepolicy.sehnd[0] = selabel_open(backend, opts, 2); if (!global_state.sepolicy.sehnd[0]) { fprintf(stderr, "Error: could not load context file from %s\n", context_file); exit(1); } }
int main(int argc, char** argv) { // Various things log information to stdout or stderr more or less // at random. The log file makes more sense if buffering is // turned off so things appear in the right order. setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc != 4) { fprintf(stderr, "unexpected number of arguments (%d)\n", argc); return 1; } char* version = argv[1]; if ((version[0] != '1' && version[0] != '2' && version[0] != '3') || version[1] != '\0') { // We support version 1, 2, or 3. fprintf(stderr, "wrong updater binary API; expected 1, 2, or 3; " "got %s\n", argv[1]); //printf("Wrong updater binary API; expected 1, 2, or 3; we just got '%s' \n",argv[1]); return 2; } // Set up the pipe for sending commands back to the parent process. int fd = atoi(argv[2]); FILE* cmd_pipe = fdopen(fd, "wb"); setlinebuf(cmd_pipe); // Extract the script from the package. char* package_data = argv[3]; ZipArchive za; int err; err = mzOpenZipArchive(package_data, &za); if (err != 0) { fprintf(stderr, "failed to open package %s: %s\n", package_data, strerror(err)); return 3; } const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME); if (script_entry == NULL) { fprintf(stderr, "failed to find %s in %s\n", SCRIPT_NAME, package_data); return 4; } char* script = malloc(script_entry->uncompLen+1); if (!mzReadZipEntry(&za, script_entry, script, script_entry->uncompLen)) { fprintf(stderr, "failed to read script from package\n"); return 5; } script[script_entry->uncompLen] = '\0'; // Configure edify's functions. RegisterBuiltins(); RegisterInstallFunctions(); RegisterDeviceExtensions(); FinishRegistration(); // Parse the script. Expr* root; int error_count = 0; yy_scan_string(script); int error = yyparse(&root, &error_count); if (error != 0 || error_count > 0) { fprintf(stderr, "%d parse errors\n", error_count); return 6; } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); // fprintf(cmd_pipe, "ui_print Warning: No file_contexts\n"); } // Evaluate the parsed script. UpdaterInfo updater_info; updater_info.cmd_pipe = cmd_pipe; updater_info.package_zip = &za; updater_info.version = atoi(version); State state; state.cookie = &updater_info; state.script = script; state.errmsg = NULL; char* result = Evaluate(&state, root); if (result == NULL) { if (state.errmsg == NULL) { fprintf(stderr, "script aborted (no error message)\n"); fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); } else { fprintf(stderr, "script aborted: %s\n", state.errmsg); char* line = strtok(state.errmsg, "\n"); while (line) { fprintf(cmd_pipe, "ui_print %s\n", line); line = strtok(NULL, "\n"); } fprintf(cmd_pipe, "ui_print\n"); } free(state.errmsg); return 7; } else { fprintf(stderr, "script result was [%s]\n", result); free(result); } if (updater_info.package_zip) { mzCloseZipArchive(updater_info.package_zip); } free(script); return 0; }
int main(int argc, char **argv) { // Recovery needs to install world-readable files, so clear umask // set by init umask(0); Log_Offset = 0; // Set up temporary log file (/tmp/recovery.log) freopen(TMP_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TMP_LOG_FILE, "a", stderr); setbuf(stderr, NULL); signal(SIGPIPE, SIG_IGN); // Handle ADB sideload if (argc == 3 && strcmp(argv[1], "--adbd") == 0) { property_set("ctl.stop", "adbd"); adb_main(argv[2]); return 0; } #ifdef RECOVERY_SDCARD_ON_DATA datamedia = true; #endif char crash_prop_val[PROPERTY_VALUE_MAX]; int crash_counter; property_get("twrp.crash_counter", crash_prop_val, "-1"); crash_counter = atoi(crash_prop_val) + 1; snprintf(crash_prop_val, sizeof(crash_prop_val), "%d", crash_counter); property_set("twrp.crash_counter", crash_prop_val); property_set("ro.twrp.boot", "1"); property_set("ro.twrp.version", TW_VERSION_STR); time_t StartupTime = time(NULL); printf("Starting TWRP %s on %s (pid %d)\n", TW_VERSION_STR, ctime(&StartupTime), getpid()); // Load default values to set DataManager constants and handle ifdefs DataManager::SetDefaultValues(); printf("Starting the UI..."); gui_init(); printf("=> Linking mtab\n"); symlink("/proc/mounts", "/etc/mtab"); if (TWFunc::Path_Exists("/etc/twrp.fstab")) { if (TWFunc::Path_Exists("/etc/recovery.fstab")) { printf("Renaming regular /etc/recovery.fstab -> /etc/recovery.fstab.bak\n"); rename("/etc/recovery.fstab", "/etc/recovery.fstab.bak"); } printf("Moving /etc/twrp.fstab -> /etc/recovery.fstab\n"); rename("/etc/twrp.fstab", "/etc/recovery.fstab"); } printf("=> Processing recovery.fstab\n"); if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) { LOGERR("Failing out of recovery due to problem with recovery.fstab.\n"); return -1; } PartitionManager.Output_Partition_Logging(); // Load up all the resources gui_loadResources(); #ifdef HAVE_SELINUX if (TWFunc::Path_Exists("/prebuilt_file_contexts")) { if (TWFunc::Path_Exists("/file_contexts")) { printf("Renaming regular /file_contexts -> /file_contexts.bak\n"); rename("/file_contexts", "/file_contexts.bak"); } printf("Moving /prebuilt_file_contexts -> /file_contexts\n"); rename("/prebuilt_file_contexts", "/file_contexts"); } struct selinux_opt selinux_options[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; selinux_handle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1); if (!selinux_handle) printf("No file contexts for SELinux\n"); else printf("SELinux contexts loaded from /file_contexts\n"); { // Check to ensure SELinux can be supported by the kernel char *contexts = NULL; if (PartitionManager.Mount_By_Path("/cache", true) && TWFunc::Path_Exists("/cache/recovery")) { lgetfilecon("/cache/recovery", &contexts); if (!contexts) { lsetfilecon("/cache/recovery", "test"); lgetfilecon("/cache/recovery", &contexts); } } else { LOGINFO("Could not check /cache/recovery SELinux contexts, using /sbin/teamwin instead which may be inaccurate.\n"); lgetfilecon("/sbin/teamwin", &contexts); } if (!contexts) { gui_print_color("warning", "Kernel does not have support for reading SELinux contexts.\n"); } else { free(contexts); gui_print("Full SELinux support is present.\n"); } } #else gui_print_color("warning", "No SELinux support (no libselinux).\n"); #endif PartitionManager.Mount_By_Path("/cache", true); string Zip_File, Reboot_Value; bool Cache_Wipe = false, Factory_Reset = false, Perform_Backup = false, Shutdown = false; { TWPartition* misc = PartitionManager.Find_Partition_By_Path("/misc"); if (misc != NULL) { if (misc->Current_File_System == "emmc") { set_device_type('e'); set_device_name(misc->Actual_Block_Device.c_str()); } else if (misc->Current_File_System == "mtd") { set_device_type('m'); set_device_name(misc->MTD_Name.c_str()); } else { LOGERR("Unknown file system for /misc\n"); } } get_args(&argc, &argv); int index, index2, len; char* argptr; char* ptr; printf("Startup Commands: "); for (index = 1; index < argc; index++) { argptr = argv[index]; printf(" '%s'", argv[index]); len = strlen(argv[index]); if (*argptr == '-') {argptr++; len--;} if (*argptr == '-') {argptr++; len--;} if (*argptr == 'u') { ptr = argptr; index2 = 0; while (*ptr != '=' && *ptr != '\n') ptr++; // skip the = before grabbing Zip_File while (*ptr == '=') ptr++; if (*ptr) { Zip_File = ptr; } else LOGERR("argument error specifying zip file\n"); } else if (*argptr == 'w') { if (len == 9) Factory_Reset = true; else if (len == 10) Cache_Wipe = true; } else if (*argptr == 'n') { Perform_Backup = true; } else if (*argptr == 'p') { Shutdown = true; } else if (*argptr == 's') { ptr = argptr; index2 = 0; while (*ptr != '=' && *ptr != '\n') ptr++; if (*ptr) { Reboot_Value = *ptr; } } } printf("\n"); } if(crash_counter == 0) { property_list(Print_Prop, NULL); printf("\n"); } else { printf("twrp.crash_counter=%d\n", crash_counter); } // Check for and run startup script if script exists 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: TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot"); LOGINFO("Backing up TWRP ramdisk...\n"); if (Boot == NULL || Boot->Current_File_System != "emmc") TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img"); else { string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device; TWFunc::Exec_Cmd(injectcmd); } LOGINFO("Backup of TWRP ramdisk done.\n"); #endif bool Keep_Going = true; if (Perform_Backup) { DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)"); if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n")) Keep_Going = false; } if (Keep_Going && !Zip_File.empty()) { string ORSCommand = "install " + Zip_File; if (!OpenRecoveryScript::Insert_ORS_Command(ORSCommand)) Keep_Going = false; } if (Keep_Going) { if (Factory_Reset) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n")) Keep_Going = false; } else if (Cache_Wipe) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n")) Keep_Going = false; } } TWFunc::Update_Log_File(); // Offer to decrypt if the device is encrypted if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) { LOGINFO("Is encrypted, do decrypt page first\n"); if (gui_startPage("decrypt", 1, 1) != 0) { LOGERR("Failed to start decrypt GUI page.\n"); } else { // Check for and load custom theme if present gui_loadCustomResources(); } } else if (datamedia) { if (tw_get_default_metadata(DataManager::GetSettingsStoragePath().c_str()) != 0) { LOGINFO("Failed to get default contexts and file mode for storage files.\n"); } else { LOGINFO("Got default contexts and file mode for storage files.\n"); } } // Read the settings file #ifdef TW_HAS_MTP // We unmount partitions sometimes during early boot which may override // the default of MTP being enabled by auto toggling MTP off. This // will force it back to enabled then get overridden by the settings // file, assuming that an entry for tw_mtp_enabled is set. DataManager::SetValue("tw_mtp_enabled", 1); #endif DataManager::ReadSettingsFile(); // Fixup the RTC clock on devices which require it if(crash_counter == 0) TWFunc::Fixup_Time_On_Boot(); // Run any outstanding OpenRecoveryScript if (DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) { OpenRecoveryScript::Run_OpenRecoveryScript(); } #ifdef TW_HAS_MTP // Enable MTP? char mtp_crash_check[PROPERTY_VALUE_MAX]; property_get("mtp.crash_check", mtp_crash_check, "0"); if (strcmp(mtp_crash_check, "0") == 0) { property_set("mtp.crash_check", "1"); if (DataManager::GetIntValue("tw_mtp_enabled") == 1 && ((DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0 && DataManager::GetIntValue(TW_IS_DECRYPTED) != 0) || DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0)) { LOGINFO("Enabling MTP during startup\n"); if (!PartitionManager.Enable_MTP()) PartitionManager.Disable_MTP(); else gui_print("MTP Enabled\n"); } else { PartitionManager.Disable_MTP(); } property_set("mtp.crash_check", "0"); } else { gui_print_color("warning", "MTP Crashed, not starting MTP on boot.\n"); DataManager::SetValue("tw_mtp_enabled", 0); PartitionManager.Disable_MTP(); } #else PartitionManager.Disable_MTP(); #endif // Launch the main GUI gui_start(); // Disable flashing of stock recovery TWFunc::Disable_Stock_Recovery_Replace(); // Check for su to see if the device is rooted or not if (PartitionManager.Mount_By_Path("/system", false)) { if (TWFunc::Path_Exists("/supersu/su") && !TWFunc::Path_Exists("/system/bin/su") && !TWFunc::Path_Exists("/system/xbin/su") && !TWFunc::Path_Exists("/system/bin/.ext/.su")) { // Device doesn't have su installed DataManager::SetValue("tw_busy", 1); if (gui_startPage("installsu", 1, 1) != 0) { LOGERR("Failed to start SuperSU install page.\n"); } } sync(); PartitionManager.UnMount_By_Path("/system", false); } // Reboot TWFunc::Update_Intent_File(Reboot_Value); TWFunc::Update_Log_File(); gui_print("Rebooting...\n"); string Reboot_Arg; DataManager::GetValue("tw_reboot_arg", Reboot_Arg); if (Reboot_Arg == "recovery") TWFunc::tw_reboot(rb_recovery); else if (Reboot_Arg == "poweroff") TWFunc::tw_reboot(rb_poweroff); else if (Reboot_Arg == "bootloader") TWFunc::tw_reboot(rb_bootloader); else if (Reboot_Arg == "download") TWFunc::tw_reboot(rb_download); else TWFunc::tw_reboot(rb_system); return 0; }
int main(int argc, char **argv) { time_t start = time(NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main(); return 0; } // Handle alternative invocations char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (strstr(argv[0], "start")) { property_set("ctl.start", argv[1]); return 0; } if (strstr(argv[0], "stop")) { property_set("ctl.stop", argv[1]); return 0; } return busybox_driver(argc, argv); } // devices can run specific tasks on recovery start __system("/sbin/postrecoveryboot.sh"); // Clear umask for packages that copy files out to /tmp and then over // to /system without properly setting all permissions (eg. gapps). umask(0); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); load_volume_table(); setup_data_media(1); vold_client_start(&v_callbacks, 0); vold_set_automount(1); setup_legacy_storage_paths(); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0, wipe_media = 0, show_text = 0, sideload = 0; bool just_exit = false; bool shutdown_after = false; printf("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'm': wipe_media = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'a': sideload = 1; break; case 'p': shutdown_after = true; break; case 'g': { if (stage == NULL || *stage == '\0') { char buffer[20] = "1/"; strncat(buffer, optarg, sizeof(buffer)-3); stage = strdup(buffer); } break; } case '?': LOGE("Invalid command argument\n"); continue; } } printf("stage is [%s]\n", stage); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_MOD_VERSION_BUILD) "\n"); ui_print("ClockworkMod " EXPAND(CWM_BASE_VERSION) "\n"); LOGI("Device target: " EXPAND(TARGET_COMMON_NAME) "\n"); #ifdef PHILZ_TOUCH_RECOVERY print_libtouch_version(0); #endif int st_cur, st_max; if (stage != NULL && sscanf(stage, "%d/%d", &st_cur, &st_max) == 2) { ui_SetStage(st_cur, st_max); } // ui_SetStage(5, 8); // debug if (show_text) ui_ShowText(true); struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed.\n"); } } if (status != INSTALL_SUCCESS) { ui_print("Installation aborted.\n"); // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error // message is visible. char buffer[PROPERTY_VALUE_MAX+1]; property_get("ro.build.fingerprint", buffer, ""); if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) { ui_ShowText(true); } } } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else if (wipe_media) { if (is_data_media() && erase_volume("/data/media")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Media wipe failed.\n"); } else if (sideload) { status = enter_sideload_mode(status); } else if (!just_exit) { // let's check recovery start up scripts (openrecoveryscript and ROM Manager extendedcommands) status = INSTALL_NONE; // No command specified, it is a normal recovery boot unless we find a boot script to run LOGI("Checking for extendedcommand & OpenRecoveryScript...\n"); // we need show_text to show boot scripts log bool text_visible = ui_IsTextVisible(); ui_SetShowText(true); if (0 == check_boot_script_file(EXTENDEDCOMMAND_SCRIPT)) { LOGI("Running extendedcommand...\n"); status = INSTALL_ERROR; if (0 == run_and_remove_extendedcommand()) status = INSTALL_SUCCESS; } if (0 == check_boot_script_file(ORS_BOOT_SCRIPT_FILE)) { LOGI("Running openrecoveryscript....\n"); status = INSTALL_ERROR; if (0 == run_ors_boot_script()) status = INSTALL_SUCCESS; } ui_SetShowText(text_visible); } if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) { copy_logs(); // ui_set_background(BACKGROUND_ICON_ERROR); // will be set in prompt_and_wait() after recovery lock check handle_failure(); } if (status != INSTALL_SUCCESS || ui_IsTextVisible()) { ui_SetShowText(true); #ifdef PHILZ_TOUCH_RECOVERY check_recovery_lock(); #endif prompt_and_wait(status); } // We reach here when in main menu we choose reboot main system or on success install of boot scripts and recovery commands finish_recovery(send_intent); if (shutdown_after) { ui_print("Shutting down...\n"); reboot_main_system(ANDROID_RB_POWEROFF, 0, 0); } else { ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { // Recovery needs to install world-readable files, so clear umask // set by init umask(0); time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 3 && strcmp(argv[1], "--adbd") == 0) { adb_main(argv[2]); return 0; } printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&start)); Device* device = make_device(); ui = device->GetUI(); //ui->Init(); //ui->SetBackground(RecoveryUI::NONE); //load_volume_table(); // Load default values to set DataManager constants and handle ifdefs DataManager_LoadDefaults(); printf("Starting the UI..."); gui_init(); printf("=> Linking mtab\n"); symlink("/proc/mounts", "/etc/mtab"); printf("=> Processing recovery.fstab\n"); if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) { LOGE("Failing out of recovery due to problem with recovery.fstab.\n"); //return -1; } PartitionManager.Output_Partition_Logging(); // Load up all the resources gui_loadResources(); PartitionManager.Mount_By_Path("/cache", true); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; bool just_exit = false; bool perform_backup = false; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': ui->ShowText(true); break; case 'x': just_exit = true; break; case 'n': perform_backup = true; LOGI("nandroid\n"); break; case '?': LOGE("Invalid command argument\n"); continue; } } #ifdef HAVE_SELINUX struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui->Print("Warning: No file_contexts\n"); } #endif //device->StartRecovery(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); // Check for and run startup script if script exists 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: TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot"); string result; LOGI("Backing up TWRP ramdisk...\n"); if (Boot == NULL || Boot->Current_File_System != "emmc") TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img", result); else { string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device; TWFunc::Exec_Cmd(injectcmd, result); } LOGI("Backup of TWRP ramdisk done.\n"); #endif int status = INSTALL_SUCCESS; string ORSCommand; if (perform_backup) { char empt[50]; gui_console_only(); strcpy(empt, "(Current Date)"); DataManager_SetStrValue(TW_BACKUP_NAME, empt); if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n")) status = INSTALL_ERROR; } if (status == INSTALL_SUCCESS) { // Prevent other actions if backup failed if (update_package != NULL) { ORSCommand = "install "; ORSCommand += update_package; ORSCommand += "\n"; if (OpenRecoveryScript::Insert_ORS_Command(ORSCommand)) status = INSTALL_SUCCESS; else status = INSTALL_ERROR; /* status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n"); */ } else if (wipe_data) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n")) status = INSTALL_ERROR; /* if (device->WipeData()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; */ if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); } else if (wipe_cache) { if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n"); } else if (!just_exit) { status = INSTALL_ERROR; // No command specified } } finish_recovery(NULL); // Offer to decrypt if the device is encrypted if (DataManager_GetIntValue(TW_IS_ENCRYPTED) != 0) { LOGI("Is encrypted, do decrypt page first\n"); if (gui_startPage("decrypt") != 0) { LOGE("Failed to start decrypt GUI page.\n"); } } // Read the settings file DataManager_ReadSettingsFile(); // Run any outstanding OpenRecoveryScript if (DataManager_GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) { OpenRecoveryScript::Run_OpenRecoveryScript(); } // Launch the main GUI gui_start(); // Check for su to see if the device is rooted or not if (PartitionManager.Mount_By_Path("/system", false)) { // Disable flashing of stock recovery if (TWFunc::Path_Exists("/system/recovery-from-boot.p")) { rename("/system/recovery-from-boot.p", "/system/recovery-from-boot.bak"); ui_print("Renamed stock recovery file in /system to prevent\nthe stock ROM from replacing TWRP.\n"); } if (TWFunc::Path_Exists("/supersu/su") && !TWFunc::Path_Exists("/system/bin/su") && !TWFunc::Path_Exists("/system/xbin/su") && !TWFunc::Path_Exists("/system/bin/.ext/.su")) { // Device doesn't have su installed DataManager_SetIntValue("tw_busy", 1); if (gui_startPage("installsu") != 0) { LOGE("Failed to start decrypt GUI page.\n"); } } else if (TWFunc::Check_su_Perms() > 0) { // su perms are set incorrectly DataManager_SetIntValue("tw_busy", 1); if (gui_startPage("fixsu") != 0) { LOGE("Failed to start decrypt GUI page.\n"); } } sync(); PartitionManager.UnMount_By_Path("/system", false); } // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui->Print("Rebooting...\n"); char backup_arg_char[50]; strcpy(backup_arg_char, DataManager_GetStrValue("tw_reboot_arg")); string backup_arg = backup_arg_char; if (backup_arg == "recovery") TWFunc::tw_reboot(rb_recovery); else if (backup_arg == "poweroff") TWFunc::tw_reboot(rb_poweroff); else if (backup_arg == "bootloader") TWFunc::tw_reboot(rb_bootloader); else if (backup_arg == "download") TWFunc::tw_reboot(rb_download); else TWFunc::tw_reboot(rb_system); #ifdef ANDROID_RB_RESTART android_reboot(ANDROID_RB_RESTART, 0, 0); #else reboot(RB_AUTOBOOT); #endif return EXIT_SUCCESS; }
int main(int argc, char **argv) { // Recovery needs to install world-readable files, so clear umask // set by init umask(0); time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 3 && strcmp(argv[1], "--adbd") == 0) { adb_main(argv[2]); return 0; } printf("Starting TWRP %s on %s", TW_VERSION_STR, ctime(&start)); Device* device = make_device(); ui = device->GetUI(); //ui->Init(); //ui->SetBackground(RecoveryUI::NONE); //load_volume_table(); // Load default values to set DataManager constants and handle ifdefs DataManager_LoadDefaults(); printf("Starting the UI..."); gui_init(); printf("=> Linking mtab\n"); system("ln -s /proc/mounts /etc/mtab"); // Link mtab for mke2fs printf("=> Processing recovery.fstab\n"); if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) { LOGE("Failing out of recovery due to problem with recovery.fstab.\n"); //return -1; } PartitionManager.Output_Partition_Logging(); // Load up all the resources gui_loadResources(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; bool just_exit = false; bool perform_backup = false; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': ui->ShowText(true); break; case 'x': just_exit = true; break; case 'n': perform_backup = true; LOGI("nandroid\n"); break; case '?': LOGE("Invalid command argument\n"); continue; } } #ifdef HAVE_SELINUX struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui->Print("Warning: No file_contexts\n"); } #endif //device->StartRecovery(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); // Check for and run startup script if script exists 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: LOGI("Backing up TWRP ramdisk...\n"); system("injecttwrp --backup /tmp/backup_recovery_ramdisk.img"); LOGI("Backup of TWRP ramdisk done.\n"); #endif int status = INSTALL_SUCCESS; if (perform_backup) { char empt[50]; gui_console_only(); strcpy(empt, "(Current Date)"); DataManager_SetStrValue(TW_BACKUP_NAME, empt); if (OpenRecoveryScript::Backup_Command("BSDCAE") != 0) status = INSTALL_ERROR; } if (status == INSTALL_SUCCESS) { // Prevent other actions if backup failed if (update_package != NULL) { gui_console_only(); if (OpenRecoveryScript::Install_Command(update_package) == 0) status = INSTALL_SUCCESS; else status = INSTALL_ERROR; /* status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n"); */ } else if (wipe_data) { gui_console_only(); if (!PartitionManager.Factory_Reset()) status = INSTALL_ERROR; /* if (device->WipeData()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; */ if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); } else if (wipe_cache) { gui_console_only(); if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n"); } else if (!just_exit) { status = INSTALL_ERROR; // No command specified } } //if (status != INSTALL_SUCCESS) ui->SetBackground(RecoveryUI::ERROR); if (status != INSTALL_SUCCESS /*|| ui->IsTextVisible()*/) { finish_recovery(NULL); DataManager_ReadSettingsFile(); if (PartitionManager.Mount_By_Path("/system", false) && TWFunc::Path_Exists("/system/recovery-from-boot.p")) { system("mv /system/recovery-from-boot.p /system/recovery-from-boot.bak"); ui_print("Renamed stock recovery file in /system to prevent\nthe stock ROM from replacing TWRP.\n"); } PartitionManager.UnMount_By_Path("/system", false); if (DataManager_GetIntValue(TW_IS_ENCRYPTED) == 0 && OpenRecoveryScript::check_for_script_file()) { gui_console_only(); if (OpenRecoveryScript::run_script_file() != 0) { // There was an error, boot the recovery gui_start(); } else { usleep(2000000); // Sleep for 2 seconds before rebooting } } else gui_start(); //prompt_and_wait(device); } // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui->Print("Rebooting...\n"); #ifdef ANDROID_RB_RESTART android_reboot(ANDROID_RB_RESTART, 0, 0); #else reboot(RB_AUTOBOOT); #endif return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct selinux_opt opts[] = { { SELABEL_OPT_VALIDATE, (void*)1 }, { SELABEL_OPT_PATH, NULL } }; // Default backend unless changed by input argument. unsigned int backend = SELABEL_CTX_FILE; FILE *fp; struct selabel_handle *sehnd; char c; while ((c = getopt(argc, argv, "ph")) != -1) { switch (c) { case 'p': backend = SELABEL_CTX_ANDROID_PROP; break; case 'h': default: usage(argv[0]); break; } } int index = optind; if (argc - optind != 2) { fprintf(stderr, "Expected sepolicy file and context file as arguments.\n"); usage(argv[0]); } // remaining args are sepolicy file and context file char *sepolicyFile = argv[index]; char *contextFile = argv[index + 1]; fp = fopen(sepolicyFile, "r"); if (!fp) { perror(sepolicyFile); exit(2); } if (sepol_set_policydb_from_file(fp) < 0) { fprintf(stderr, "Error loading policy from %s\n", sepolicyFile); exit(3); } selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&validate); opts[1].value = contextFile; sehnd = selabel_open(backend, opts, 2); if (!sehnd) { fprintf(stderr, "Error loading context file from %s\n", contextFile); exit(4); } if (nerr) { fprintf(stderr, "Invalid context file found in %s\n", contextFile); exit(5); } exit(0); }
int main(int argc, char **argv) { time_t start = time(NULL); char firmware[50] = {0}; property_get("ro.reversion.aw_sdk_tag", firmware, "unknow"); strcat(reversion,firmware); char storage_type[50] = {0}; property_get("ro.sys.storage_type",storage_type,""); if(!strcmp(storage_type,"emulated")){ internal_storage_type = 1; } // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main(); return 0; } printf("Starting recovery on %s", ctime(&start)); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0, show_text = 0; bool just_exit = false; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'l': locale = optarg; break; case '?': LOGE("Invalid command argument\n"); continue; } } if (locale == NULL) { load_locale_from_cache(); } printf("locale is [%s]\n", locale); Device* device = make_device(); ui = device->GetUI(); ui->Init(); ui->SetLocale(locale); ui->SetBackground(RecoveryUI::NONE); if (show_text) ui->ShowText(true); #ifdef HAVE_SELINUX struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui->Print("Warning: No file_contexts\n"); } #endif device->StartRecovery(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n"); } else if (wipe_data) { if (device->WipeData()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; copy_databk_to_data(); if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n"); } else if (!just_exit) { status = INSTALL_NONE; // No command specified // ui->SetBackground(RecoveryUI::NO_COMMAND); // modify by cjcheng } if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) { ui->SetBackground(RecoveryUI::ERROR); } if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { ui->ShowText(false); // modify by cjcheng ui->SetTipTitle(RecoveryUI::TIP_TITLE_READY); // add by cjcheng prompt_and_wait(device, status); /* add by cjcheng start... */ if (install_flag == INSTALL_SUCCESS){ ui->SetTipTitle(RecoveryUI::TIP_TITLE_SUCCESS); status = INSTALL_SUCCESS; } /* add by cjcheng end... */ } /* add by cjcheng start... */ if (status != INSTALL_SUCCESS){ ui->SetBackground(RecoveryUI::ERROR); ui->SetTipTitle(RecoveryUI::TIP_TITLE_ERROR); } /* add by cjcheng end... */ sleep(2); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui->Print("Rebooting...\n"); sync(); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (!strcmp(command, "start")) { property_set("ctl.start", argv[1]); return 0; } if (!strcmp(command, "stop")) { property_set("ctl.stop", argv[1]); return 0; } return busybox_driver(argc, argv); } //__system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s\n", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); ui_print("Builder: "EXPAND(RECOVERY_BUILDER)"\n"); ui_print("Date: "EXPAND(RECOVERY_BUILD_TIME)"\n"); ui_print("weibo:@nx-baby\n"); __system("/sbin/postrecoveryboot.sh"); //#ifdef BOARD_RECOVERY_SWIPE //#ifndef BOARD_TOUCH_RECOVERY //display directions for swipe controls ui_print("Swipe up/down to change selections.\n"); ui_print("Swipe to the right for enter.\n"); ui_print("Swipe to the left for back.\n"); //#endif //#endif load_volume_table(); process_volumes(); vold_init(); setup_legacy_storage_paths(); #ifdef QCOM_HARDWARE parse_t_daemon_data_files(); apply_time_zone(); #endif LOGI("Processing arguments.\n"); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; int headless = 0; int shutdown_after = 0; LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 's': send_intent = optarg; break; case 'u': if (update_package == NULL) update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'h': ui_set_background(BACKGROUND_ICON_CID); ui_show_text(0); headless = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case 'p': shutdown_after = 1; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); //ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Installation aborted.\n"); } else if (!strcmp(TARGET_DEVICE, "A0001")) { //hack for a0001 ota if (strstr(update_package, "/.OTA/")) send_intent = "0"; } } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; preserve_data_media(0); if (erase_volume("/data")) status = INSTALL_ERROR; preserve_data_media(1); if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Data wipe failed.\n"); } } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Cache wipe failed.\n"); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; is_user_initiated_recovery = 1; if (!headless) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_CLOCKWORK); } if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (sideload) { signature_check_enabled = 0; if (!headless) ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } if (headless) { headless_wait(); } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } else if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // We reach here when in main menu we choose reboot main system or for some wipe commands on start // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); if (shutdown_after) { ui_print("Shutting down...\n"); reboot_main_system(ANDROID_RB_POWEROFF, 0, 0); } else { ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { int backend = 0, rc, opt, validate = 0; char *baseonly = NULL, *file = NULL, *digest = (char *)1; char **specfiles = NULL; unsigned char *sha1_digest = NULL; size_t i, num_specfiles; char cmd_buf[4096]; char *cmd_ptr; char *sha1_buf; struct selabel_handle *hnd; struct selinux_opt selabel_option[] = { { SELABEL_OPT_PATH, file }, { SELABEL_OPT_BASEONLY, baseonly }, { SELABEL_OPT_DIGEST, digest } }; if (argc < 3) usage(argv[0]); while ((opt = getopt(argc, argv, "ib:Bvf:")) > 0) { switch (opt) { case 'b': if (!strcasecmp(optarg, "file")) { backend = SELABEL_CTX_FILE; } else if (!strcmp(optarg, "media")) { backend = SELABEL_CTX_MEDIA; } else if (!strcmp(optarg, "x")) { backend = SELABEL_CTX_X; } else if (!strcmp(optarg, "db")) { backend = SELABEL_CTX_DB; } else if (!strcmp(optarg, "prop")) { backend = SELABEL_CTX_ANDROID_PROP; } else if (!strcmp(optarg, "service")) { backend = SELABEL_CTX_ANDROID_SERVICE; } else { fprintf(stderr, "Unknown backend: %s\n", optarg); usage(argv[0]); } break; case 'B': baseonly = (char *)1; break; case 'v': validate = 1; break; case 'i': digest = NULL; break; case 'f': file = optarg; break; default: usage(argv[0]); } } memset(cmd_buf, 0, sizeof(cmd_buf)); selabel_option[0].value = file; selabel_option[1].value = baseonly; selabel_option[2].value = digest; hnd = selabel_open(backend, selabel_option, 3); if (!hnd) { switch (errno) { case EOVERFLOW: fprintf(stderr, "ERROR Number of specfiles or specfile" " buffer caused an overflow.\n"); break; default: fprintf(stderr, "ERROR: selabel_open: %s\n", strerror(errno)); } return -1; } rc = selabel_digest(hnd, &sha1_digest, &digest_len, &specfiles, &num_specfiles); if (rc) { switch (errno) { case EINVAL: fprintf(stderr, "No digest available.\n"); break; default: fprintf(stderr, "selabel_digest ERROR: %s\n", strerror(errno)); } goto err; } sha1_buf = malloc(digest_len * 2 + 1); if (!sha1_buf) { fprintf(stderr, "Could not malloc buffer ERROR: %s\n", strerror(errno)); rc = -1; goto err; } printf("SHA1 digest: "); for (i = 0; i < digest_len; i++) sprintf(&(sha1_buf[i * 2]), "%02x", sha1_digest[i]); printf("%s\n", sha1_buf); printf("calculated using the following specfile(s):\n"); if (specfiles) { cmd_ptr = &cmd_buf[0]; sprintf(cmd_ptr, "/usr/bin/cat "); cmd_ptr = &cmd_buf[0] + strlen(cmd_buf); for (i = 0; i < num_specfiles; i++) { sprintf(cmd_ptr, "%s ", specfiles[i]); cmd_ptr += strlen(specfiles[i]) + 1; printf("%s\n", specfiles[i]); } sprintf(cmd_ptr, "| /usr/bin/openssl dgst -sha1 -hex"); if (validate) rc = run_check_digest(cmd_buf, sha1_buf); } free(sha1_buf); err: selabel_close(hnd); return rc; }
Datum sepgsql_restorecon(PG_FUNCTION_ARGS) { struct selabel_handle *sehnd; struct selinux_opt seopts; /* * SELinux has to be enabled on the running platform. */ if (!sepgsql_is_enabled()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("sepgsql is not currently enabled"))); /* * Check DAC permission. Only superuser can set up initial * security labels, like root-user in filesystems */ if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("SELinux: must be superuser to restore initial contexts"))); /* * Open selabel_lookup(3) stuff. It provides a set of mapping * between an initial security label and object class/name due * to the system setting. */ if (PG_ARGISNULL(0)) { seopts.type = SELABEL_OPT_UNUSED; seopts.value = NULL; } else { seopts.type = SELABEL_OPT_PATH; seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0)); } sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1); if (!sehnd) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: failed to initialize labeling handle: %m"))); PG_TRY(); { /* * Right now, we have no support labeling on the shared * database objects, such as database, role, or tablespace. */ exec_object_restorecon(sehnd, NamespaceRelationId); exec_object_restorecon(sehnd, RelationRelationId); exec_object_restorecon(sehnd, AttributeRelationId); exec_object_restorecon(sehnd, ProcedureRelationId); } PG_CATCH(); { selabel_close(sehnd); PG_RE_THROW(); } PG_END_TRY(); selabel_close(sehnd); PG_RETURN_BOOL(true); }
int main(int argc, char **argv) { time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main(); return 0; } printf("Starting recovery on %s", ctime(&start)); load_volume_table(); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0, show_text = 0; bool just_exit = false; bool shutdown_after = false; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'l': locale = optarg; break; case 'g': { if (stage == NULL || *stage == '\0') { char buffer[20] = "1/"; strncat(buffer, optarg, sizeof(buffer)-3); stage = strdup(buffer); } break; } case 'p': shutdown_after = true; break; case '?': LOGE("Invalid command argument\n"); continue; } } if (locale == NULL) { load_locale_from_cache(); } printf("locale is [%s]\n", locale); printf("stage is [%s]\n", stage, stage); Device* device = make_device(); ui = device->GetUI(); gCurrentUI = ui; ui->SetLocale(locale); ui->Init(); int st_cur, st_max; if (stage != NULL && sscanf(stage, "%d/%d", &st_cur, &st_max) == 2) { ui->SetStage(st_cur, st_max); } ui->SetBackground(RecoveryUI::NONE); if (show_text) ui->ShowText(true); struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { ui->Print("Warning: No file_contexts\n"); } device->StartRecovery(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); property_get("ro.build.display.id", recovery_version, ""); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) { ui->Print("Installation aborted.\n"); // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error // message is visible. char buffer[PROPERTY_VALUE_MAX+1]; property_get("ro.build.fingerprint", buffer, ""); if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) { ui->ShowText(true); } } } else if (wipe_data) { if (device->WipeData()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n"); } else if (!just_exit) { status = INSTALL_NONE; // No command specified ui->SetBackground(RecoveryUI::NO_COMMAND); } if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) { copy_logs(); ui->SetBackground(RecoveryUI::ERROR); } if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { prompt_and_wait(device, status); } // Otherwise, get ready to boot the main system... finish_recovery(send_intent); if (shutdown_after) { ui->Print("Shutting down...\n"); property_set(ANDROID_RB_PROPERTY, "shutdown,"); } else { ui->Print("Rebooting...\n"); property_set(ANDROID_RB_PROPERTY, "reboot,"); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { int opt; const char *filename = NULL; const char *directory = NULL; char *mountpoint = NULL; fs_config_func_t fs_config_func = NULL; int gzip = 0; int sparse = 0; int crc = 0; int wipe = 0; int fd; int exitcode; int verbose = 0; struct selabel_handle *sehnd = NULL; #ifndef USE_MINGW struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "" } }; #endif while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:S:fwzJsctv")) != -1) { switch (opt) { case 'l': info.len = parse_num(optarg); break; case 'j': info.journal_blocks = parse_num(optarg); break; case 'b': info.block_size = parse_num(optarg); break; case 'g': info.blocks_per_group = parse_num(optarg); break; case 'i': info.inodes = parse_num(optarg); break; case 'I': info.inode_size = parse_num(optarg); break; case 'L': info.label = optarg; break; case 'f': force = 1; break; case 'a': #ifdef ANDROID fs_config_func = fs_config; mountpoint = optarg; #else fprintf(stderr, "can't set android permissions - built without android support\n"); usage(argv[0]); exit(EXIT_FAILURE); #endif break; case 'w': wipe = 1; break; case 'z': gzip = 1; break; case 'J': info.no_journal = 1; break; case 'c': crc = 1; break; case 's': sparse = 1; break; case 't': fprintf(stderr, "Warning: -t (initialize inode tables) is deprecated\n"); break; case 'S': #ifndef USE_MINGW seopts[0].value = optarg; sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehnd) { perror(optarg); exit(EXIT_FAILURE); } #endif break; case 'v': verbose = 1; break; default: /* '?' */ usage(argv[0]); exit(EXIT_FAILURE); } } #if !defined(HOST) // Use only if -S option not requested if (!sehnd && mountpoint) { sehnd = selinux_android_file_context_handle(); if (!sehnd) { perror(optarg); exit(EXIT_FAILURE); } } #endif if (wipe && sparse) { fprintf(stderr, "Cannot specifiy both wipe and sparse\n"); usage(argv[0]); exit(EXIT_FAILURE); } if (wipe && gzip) { fprintf(stderr, "Cannot specifiy both wipe and gzip\n"); usage(argv[0]); exit(EXIT_FAILURE); } if (optind >= argc) { fprintf(stderr, "Expected filename after options\n"); usage(argv[0]); exit(EXIT_FAILURE); } filename = argv[optind++]; if (optind < argc) directory = argv[optind++]; if (optind < argc) { fprintf(stderr, "Unexpected argument: %s\n", argv[optind]); usage(argv[0]); exit(EXIT_FAILURE); } if (strcmp(filename, "-")) { fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd < 0) { perror("open"); return EXIT_FAILURE; } } else { fd = STDOUT_FILENO; } exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip, sparse, crc, wipe, sehnd, verbose); close(fd); if (exitcode && strcmp(filename, "-")) unlink(filename); return exitcode; }