diff --git a/DEBUG_INI.md b/DEBUG_INI.md new file mode 100644 index 0000000..85e29f3 --- /dev/null +++ b/DEBUG_INI.md @@ -0,0 +1,90 @@ +# Debug configuration (`debug.ini`) + +Optional file to **skip parts of the install** for testing (e.g. run only deletion and inspect the SD card). If the file is **missing**, the installer ignores debug entirely and runs the full flow. + +## Location + +``` +sd:/config/omninx/debug.ini +``` + +Create the folder `sd:/config/omninx/` on the SD card if it does not exist. Same parent directory as `manifest.ini` and `ram_config.ini`. + +## Format + +- Section name must be exactly **`[Debug]`** (case-sensitive in the parser). +- One key per line: `name=value`. +- **Enabling a skip:** set the value so it **starts** with one of: `1`, `t`, `T`, `y`, `Y` + Examples: `1`, `true`, `yes`, `True` — all enable that skip. +- **Disabling:** `0`, `false`, `no`, or omit the key. + +## Parameters + +### Clean install mode (`INSTALL_MODE_CLEAN`) + +| Key | What is skipped | +|-----|-----------------| +| `skip_clean_backup` | Step 1 — backup of `sd:/switch/DBI/dbi.config`, `sd:/switch/prod.keys` to `sd:/temp_backup` | +| `skip_clean_wipe` | Step 2 — all cleanup from `deletion_lists_clean.h` (deletion / wipe) | +| `skip_clean_restore` | Step 3 — restore from `sd:/temp_backup` and post-restore paths (e.g. delete `sd:/switch/tinfoil/db`) | +| `skip_clean_install` | Step 4 — copy files from the OmniNX staging folder to the SD root | +| `skip_clean_staging_cleanup` | After install: do not remove the staging directory or other variant staging folders | + +### Update mode (`INSTALL_MODE_UPDATE`) + +| Key | What is skipped | +|-----|-----------------| +| `skip_update_cleanup` | Step 1 — selective deletion from `deletion_lists_update.h` | +| `skip_update_install` | Step 2 — copy from staging to SD | +| `skip_update_staging_cleanup` | End: do not remove staging / other variant folders | +| `skip_update_horizon_oc` | **OC variant only:** HorizonOC config backup before update, restore and cleanup after (entire HorizonOC update side path) | + +### Both modes + +| Key | What is skipped | +|-----|-----------------| +| `skip_hekate_8gb_post_copy` | After a successful copy: the optional `hekate_8GB` / RAM menu and related file moves (see `install_hekate_8gb_post_copy` in `install.c`) | + +## Behaviour + +- On startup, if `debug.ini` exists and parses successfully, the payload prints a **DEBUG-MODUS** banner listing which skips are active. +- If the file is absent, unreadable, or has no `[Debug]` section, **no** skips apply — behaviour matches a release install. +- Skipping steps can leave the SD in an inconsistent state; this is **for developers/testers only**. + +## Examples + +### Wipe only (test deletion, no backup/restore/copy) + +Inspect leftovers after the clean-install wipe, without backing up, restoring, installing, or cleaning staging: + +```ini +[Debug] +skip_clean_backup=1 +skip_clean_restore=1 +skip_clean_install=1 +skip_clean_staging_cleanup=1 +skip_hekate_8gb_post_copy=1 +``` + +Do **not** set `skip_clean_wipe` (leave unset or `0`). + +### Update: deletion only + +```ini +[Debug] +skip_update_install=1 +skip_update_staging_cleanup=1 +skip_hekate_8gb_post_copy=1 +``` + +### OC update without touching HorizonOC backup/restore + +```ini +[Debug] +skip_update_horizon_oc=1 +``` + +## Implementation + +- Parsed in `install.c`: `install_debug_load()`, `perform_installation()`. +- Uses the same INI parser as `ram_config.ini` (`ini_parse` from BDK). diff --git a/source/install.c b/source/install.c index 21bbf2a..5afde0d 100644 --- a/source/install.c +++ b/source/install.c @@ -868,12 +868,120 @@ static void install_hekate_8gb_post_copy(void) } } +#define INSTALL_DEBUG_INI "sd:/config/omninx/debug.ini" + +typedef struct { + bool active; + bool skip_clean_backup; + bool skip_clean_wipe; + bool skip_clean_restore; + bool skip_clean_install; + bool skip_clean_staging_cleanup; + bool skip_update_cleanup; + bool skip_update_install; + bool skip_update_staging_cleanup; + bool skip_update_horizon_oc; + bool skip_hekate_8gb_post_copy; +} install_debug_opts_t; + +static bool install_ini_truth(const char *val) +{ + if (!val || !val[0]) + return false; + char c = val[0]; + return c == '1' || c == 't' || c == 'T' || c == 'y' || c == 'Y'; +} + +static void install_debug_load(install_debug_opts_t *d) +{ + memset(d, 0, sizeof(*d)); + if (!install_path_exists(INSTALL_DEBUG_INI)) + return; + + link_t sections; + list_init(§ions); + if (ini_parse(§ions, (char *)INSTALL_DEBUG_INI, false) != 1) { + ram_config_free_sections(§ions); + return; + } + + LIST_FOREACH_ENTRY(ini_sec_t, sec, §ions, link) { + if (!sec->name || strcmp(sec->name, "Debug") != 0) + continue; + LIST_FOREACH_ENTRY(ini_kv_t, kv, &sec->kvs, link) { + if (!kv->key || !kv->val) + continue; + if (strcmp(kv->key, "skip_clean_backup") == 0) + d->skip_clean_backup = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_clean_wipe") == 0) + d->skip_clean_wipe = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_clean_restore") == 0) + d->skip_clean_restore = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_clean_install") == 0) + d->skip_clean_install = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_clean_staging_cleanup") == 0) + d->skip_clean_staging_cleanup = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_update_cleanup") == 0) + d->skip_update_cleanup = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_update_install") == 0) + d->skip_update_install = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_update_staging_cleanup") == 0) + d->skip_update_staging_cleanup = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_update_horizon_oc") == 0) + d->skip_update_horizon_oc = install_ini_truth(kv->val); + else if (strcmp(kv->key, "skip_hekate_8gb_post_copy") == 0) + d->skip_hekate_8gb_post_copy = install_ini_truth(kv->val); + } + break; + } + ram_config_free_sections(§ions); + + d->active = d->skip_clean_backup || d->skip_clean_wipe || d->skip_clean_restore + || d->skip_clean_install || d->skip_clean_staging_cleanup || d->skip_update_cleanup + || d->skip_update_install || d->skip_update_staging_cleanup || d->skip_update_horizon_oc + || d->skip_hekate_8gb_post_copy; +} + +static void install_debug_print_banner(const install_debug_opts_t *d) +{ + if (!d->active) + return; + install_set_color(COLOR_RED); + gfx_printf("*** DEBUG-MODUS: %s ***\n", INSTALL_DEBUG_INI); + install_set_color(COLOR_ORANGE); + if (d->skip_clean_backup) + gfx_printf(" ueberspringe: Clean Schritt 1 (Backup)\n"); + if (d->skip_clean_wipe) + gfx_printf(" ueberspringe: Clean Schritt 2 (Bereinigung)\n"); + if (d->skip_clean_restore) + gfx_printf(" ueberspringe: Clean Schritt 3 (Restore)\n"); + if (d->skip_clean_install) + gfx_printf(" ueberspringe: Clean Schritt 4 (Kopieren)\n"); + if (d->skip_clean_staging_cleanup) + gfx_printf(" ueberspringe: Clean Staging-Aufraeumen\n"); + if (d->skip_update_cleanup) + gfx_printf(" ueberspringe: Update Schritt 1 (Bereinigung)\n"); + if (d->skip_update_install) + gfx_printf(" ueberspringe: Update Schritt 2 (Kopieren)\n"); + if (d->skip_update_staging_cleanup) + gfx_printf(" ueberspringe: Update Staging-Aufraeumen\n"); + if (d->skip_update_horizon_oc) + gfx_printf(" ueberspringe: HorizonOC Update (Backup/Restore)\n"); + if (d->skip_hekate_8gb_post_copy) + gfx_printf(" ueberspringe: hekate 8GB RAM Auswahl / Post-Copy\n"); + install_set_color(COLOR_WHITE); + gfx_printf("\n"); +} + // Main installation function int perform_installation(omninx_variant_t pack_variant, install_mode_t mode) { int res; - + install_debug_opts_t dbg; + install_debug_load(&dbg); + install_debug_print_banner(&dbg); + if (mode == INSTALL_MODE_UPDATE) { - if (pack_variant == VARIANT_OC) { + if (pack_variant == VARIANT_OC && !dbg.skip_update_horizon_oc) { bool had_horizon_cfg = install_path_exists(HORIZON_OC_CONFIG_PATH); install_set_color(COLOR_YELLOW); gfx_printf("HorizonOC: Sichere config.ini...\n"); @@ -886,26 +994,48 @@ int perform_installation(omninx_variant_t pack_variant, install_mode_t mode) { gfx_printf(" [OK] Bestehende config.ini gesichert.\n"); install_set_color(COLOR_WHITE); } + } else if (pack_variant == VARIANT_OC && dbg.skip_update_horizon_oc) { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] HorizonOC Backup uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + + if (!dbg.skip_update_cleanup) { + install_set_color(COLOR_YELLOW); + gfx_printf("Schritt 1: Bereinigung...\n"); + install_set_color(COLOR_WHITE); + res = update_mode_cleanup(pack_variant); + if (res != FR_OK) return res; + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 1 (Bereinigung) uebersprungen.\n"); + install_set_color(COLOR_WHITE); } - // Update mode: selective cleanup then install - install_set_color(COLOR_YELLOW); - gfx_printf("Schritt 1: Bereinigung...\n"); - install_set_color(COLOR_WHITE); - res = update_mode_cleanup(pack_variant); - if (res != FR_OK) return res; - install_check_and_clear_screen_if_needed(); gfx_printf("\n"); - install_set_color(COLOR_YELLOW); - gfx_printf("Schritt 2: Dateien kopieren...\n"); - install_set_color(COLOR_WHITE); - res = update_mode_install(pack_variant); - if (res != FR_OK) return res; - install_hekate_8gb_post_copy(); + if (!dbg.skip_update_install) { + install_set_color(COLOR_YELLOW); + gfx_printf("Schritt 2: Dateien kopieren...\n"); + install_set_color(COLOR_WHITE); + res = update_mode_install(pack_variant); + if (res != FR_OK) return res; + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 2 (Kopieren) uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } - if (pack_variant == VARIANT_OC) { + if (!dbg.skip_hekate_8gb_post_copy) + install_hekate_8gb_post_copy(); + else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] hekate 8GB Post-Copy uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + + if (pack_variant == VARIANT_OC && !dbg.skip_update_horizon_oc) { bool had_horizon_bak = install_path_exists(HORIZON_OC_UPDATE_BACKUP_INI); install_check_and_clear_screen_if_needed(); install_set_color(COLOR_YELLOW); @@ -923,55 +1053,99 @@ int perform_installation(omninx_variant_t pack_variant, install_mode_t mode) { res = cleanup_horizon_oc_update_backup(); if (res != FR_OK) return res; + } else if (pack_variant == VARIANT_OC && dbg.skip_update_horizon_oc) { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] HorizonOC Restore uebersprungen.\n"); + install_set_color(COLOR_WHITE); } install_check_and_clear_screen_if_needed(); - // Remove staging directory (installed pack) - res = cleanup_staging_directory(pack_variant); - if (res != FR_OK) return res; - // Remove other detected install directories (Standard/Light/OC) that were on SD - res = cleanup_other_staging_directories(pack_variant); - return res; - } else { - // Clean mode: backup, wipe, restore, install + if (!dbg.skip_update_staging_cleanup) { + res = cleanup_staging_directory(pack_variant); + if (res != FR_OK) return res; + res = cleanup_other_staging_directories(pack_variant); + return res; + } + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Staging-Aufraeumen uebersprungen.\n"); + install_set_color(COLOR_WHITE); + return FR_OK; + } + + if (!dbg.skip_clean_backup) { install_set_color(COLOR_YELLOW); gfx_printf("Schritt 1: Sichere Benutzerdaten...\n"); install_set_color(COLOR_WHITE); res = clean_mode_backup(); if (res != FR_OK) return res; - - install_check_and_clear_screen_if_needed(); - gfx_printf("\n"); + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 1 (Backup) uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + + install_check_and_clear_screen_if_needed(); + gfx_printf("\n"); + + if (!dbg.skip_clean_wipe) { install_set_color(COLOR_YELLOW); gfx_printf("Schritt 2: Bereinige alte Installation...\n"); install_set_color(COLOR_WHITE); res = clean_mode_wipe(); if (res != FR_OK) return res; - - install_check_and_clear_screen_if_needed(); - gfx_printf("\n"); + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 2 (Bereinigung) uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + + install_check_and_clear_screen_if_needed(); + gfx_printf("\n"); + + if (!dbg.skip_clean_restore) { install_set_color(COLOR_YELLOW); gfx_printf("Schritt 3: Stelle Benutzerdaten wieder her...\n"); install_set_color(COLOR_WHITE); res = clean_mode_restore(); if (res != FR_OK) return res; - - install_check_and_clear_screen_if_needed(); - gfx_printf("\n"); + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 3 (Restore) uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + + install_check_and_clear_screen_if_needed(); + gfx_printf("\n"); + + if (!dbg.skip_clean_install) { install_set_color(COLOR_YELLOW); gfx_printf("Schritt 4: Dateien kopieren...\n"); install_set_color(COLOR_WHITE); res = clean_mode_install(pack_variant); if (res != FR_OK) return res; + } else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Schritt 4 (Kopieren) uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } + if (!dbg.skip_hekate_8gb_post_copy) install_hekate_8gb_post_copy(); + else { + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] hekate 8GB Post-Copy uebersprungen.\n"); + install_set_color(COLOR_WHITE); + } - install_check_and_clear_screen_if_needed(); - // Remove staging directory (installed pack) + install_check_and_clear_screen_if_needed(); + if (!dbg.skip_clean_staging_cleanup) { res = cleanup_staging_directory(pack_variant); if (res != FR_OK) return res; - // Remove other detected install directories (Standard/Light/OC) that were on SD res = cleanup_other_staging_directories(pack_variant); return res; } + install_set_color(COLOR_ORANGE); + gfx_printf("[DEBUG] Staging-Aufraeumen uebersprungen.\n"); + install_set_color(COLOR_WHITE); + return FR_OK; } diff --git a/source/install.h b/source/install.h index 67c659f..3e0a2d8 100644 --- a/source/install.h +++ b/source/install.h @@ -16,7 +16,7 @@ typedef enum { // If a sub-menu aborts to Hekate / update.bin (does not return if launch succeeds) void installer_launch_hekate_payload(void); -// Main installation function +// Main installation function (optional debug: see DEBUG_INI.md in repo root) int perform_installation(omninx_variant_t pack_variant, install_mode_t mode); // Update mode operations (install_update.c)