Preserve.ini for update cleanup, Hekate UI strings, docs
All checks were successful
Build / Build (push) Successful in 17s
All checks were successful
Build / Build (push) Successful in 17s
- Load sd:/config/omninx/preserve.ini during update mode cleanup to skip delete paths that overlap user-preserved prefixes (heap-backed path list). - Document preserve.ini in PRESERVE_INI.md, README, and INSTALLATION_PROCESS. - Prefer Hekate wording in main.c user messages for bootloader launch/errors. - Extend update deletion list for exefs_patches (audio_mastervolume, SaltyNX_Fixes, logo).
This commit is contained in:
191
source/install.c
191
source/install.c
@@ -21,6 +21,8 @@
|
||||
|
||||
#define GROUPED_DELETE_MAX_ENTRIES 512
|
||||
|
||||
static bool install_path_blocked_by_user_preserve(const char *path);
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "1.0.0"
|
||||
#endif
|
||||
@@ -463,7 +465,7 @@ int delete_path_lists_grouped(const char *folder_display_name, ...) {
|
||||
const char **list;
|
||||
while (n_entries < GROUPED_DELETE_MAX_ENTRIES && (list = va_arg(ap, const char **)) != NULL) {
|
||||
for (int i = 0; list[i] != NULL && n_entries < GROUPED_DELETE_MAX_ENTRIES; i++) {
|
||||
if (install_path_exists(list[i]))
|
||||
if (install_path_exists(list[i]) && !install_path_blocked_by_user_preserve(list[i]))
|
||||
entries[n_entries++] = list[i];
|
||||
}
|
||||
}
|
||||
@@ -538,9 +540,9 @@ int delete_path_list(const char* paths[], const char* description) {
|
||||
u32 start_x, start_y;
|
||||
int last_percent = -1;
|
||||
|
||||
// Count total paths first
|
||||
// Count total paths first (only those we will delete)
|
||||
for (int i = 0; paths[i] != NULL; i++) {
|
||||
if (install_path_exists(paths[i])) {
|
||||
if (install_path_exists(paths[i]) && !install_path_blocked_by_user_preserve(paths[i])) {
|
||||
total_paths++;
|
||||
}
|
||||
}
|
||||
@@ -558,7 +560,7 @@ int delete_path_list(const char* paths[], const char* description) {
|
||||
install_set_color(COLOR_WHITE);
|
||||
|
||||
for (int i = 0; paths[i] != NULL; i++) {
|
||||
if (install_path_exists(paths[i])) {
|
||||
if (install_path_exists(paths[i]) && !install_path_blocked_by_user_preserve(paths[i])) {
|
||||
FILINFO fno;
|
||||
f_stat(paths[i], &fno);
|
||||
|
||||
@@ -686,6 +688,159 @@ static void ram_config_free_sections(link_t *sections)
|
||||
}
|
||||
}
|
||||
|
||||
#define INSTALL_PRESERVE_INI "sd:/config/omninx/preserve.ini"
|
||||
#define INSTALL_PRESERVE_MAX 96
|
||||
#define INSTALL_PRESERVE_PATH_BYTES 224
|
||||
|
||||
static bool install_ini_kv_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 preserve_strip_outer_quotes(char *s)
|
||||
{
|
||||
size_t n = strlen(s);
|
||||
if (n >= 2 &&
|
||||
((s[0] == '\'' && s[n - 1] == '\'') || (s[0] == '"' && s[n - 1] == '"'))) {
|
||||
memmove(s, s + 1, n - 2);
|
||||
s[n - 2] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void preserve_normalize_trailing_slashes(char *s)
|
||||
{
|
||||
size_t n = strlen(s);
|
||||
while (n > 1 && s[n - 1] == '/')
|
||||
s[--n] = '\0';
|
||||
}
|
||||
|
||||
static bool path_is_same_or_descendant(const char *base, const char *path)
|
||||
{
|
||||
size_t lb = strlen(base);
|
||||
if (strncmp(path, base, lb) != 0)
|
||||
return false;
|
||||
if (path[lb] == '\0')
|
||||
return true;
|
||||
if (path[lb] == '/')
|
||||
return true;
|
||||
if (lb == 4 && base[0] == 's' && base[1] == 'd' && base[2] == ':' && base[3] == '/')
|
||||
return path[lb] != '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool path_delete_overlaps_preserve(const char *del, const char *pres)
|
||||
{
|
||||
return path_is_same_or_descendant(pres, del) || path_is_same_or_descendant(del, pres);
|
||||
}
|
||||
|
||||
static bool g_preserve_update_active;
|
||||
/** Rows stored in DRAM (heap); avoids ~21KB BSS in tight IPL IRAM around 0x40008000. */
|
||||
static char *g_preserve_block;
|
||||
static int g_preserve_count;
|
||||
|
||||
static const char *preserve_get_row(int i)
|
||||
{
|
||||
return g_preserve_block + (size_t)i * INSTALL_PRESERVE_PATH_BYTES;
|
||||
}
|
||||
|
||||
static bool install_path_blocked_by_user_preserve(const char *delete_path)
|
||||
{
|
||||
if (!g_preserve_update_active || !g_preserve_block || !delete_path)
|
||||
return false;
|
||||
for (int i = 0; i < g_preserve_count; i++) {
|
||||
if (path_delete_overlaps_preserve(delete_path, preserve_get_row(i)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void install_preserve_update_cleanup_begin(void)
|
||||
{
|
||||
if (g_preserve_block) {
|
||||
free(g_preserve_block);
|
||||
g_preserve_block = NULL;
|
||||
}
|
||||
g_preserve_count = 0;
|
||||
g_preserve_update_active = false;
|
||||
|
||||
if (!install_path_exists(INSTALL_PRESERVE_INI))
|
||||
return;
|
||||
|
||||
g_preserve_block = calloc(INSTALL_PRESERVE_MAX, INSTALL_PRESERVE_PATH_BYTES);
|
||||
if (!g_preserve_block)
|
||||
return;
|
||||
|
||||
link_t sections;
|
||||
list_init(§ions);
|
||||
if (ini_parse(§ions, (char *)INSTALL_PRESERVE_INI, false) != 1) {
|
||||
ram_config_free_sections(§ions);
|
||||
free(g_preserve_block);
|
||||
g_preserve_block = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, sec, §ions, link) {
|
||||
if (!sec->name || strcmp(sec->name, "Preserve") != 0)
|
||||
continue;
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &sec->kvs, link) {
|
||||
if (!kv->key || !kv->val || g_preserve_count >= INSTALL_PRESERVE_MAX)
|
||||
continue;
|
||||
if (!install_ini_kv_truth(kv->val))
|
||||
continue;
|
||||
char buf[INSTALL_PRESERVE_PATH_BYTES];
|
||||
strncpy(buf, kv->key, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
preserve_strip_outer_quotes(buf);
|
||||
preserve_normalize_trailing_slashes(buf);
|
||||
if (strlen(buf) < 5 || strncmp(buf, "sd:/", 4) != 0)
|
||||
continue;
|
||||
if (strcmp(buf, "sd:/") == 0)
|
||||
continue;
|
||||
|
||||
bool dup = false;
|
||||
for (int j = 0; j < g_preserve_count; j++) {
|
||||
if (strcmp(preserve_get_row(j), buf) == 0) {
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dup)
|
||||
continue;
|
||||
|
||||
char *row = (char *)preserve_get_row(g_preserve_count);
|
||||
strncpy(row, buf, INSTALL_PRESERVE_PATH_BYTES - 1);
|
||||
row[INSTALL_PRESERVE_PATH_BYTES - 1] = '\0';
|
||||
g_preserve_count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ram_config_free_sections(§ions);
|
||||
|
||||
if (g_preserve_count == 0) {
|
||||
free(g_preserve_block);
|
||||
g_preserve_block = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
g_preserve_update_active = true;
|
||||
install_set_color(COLOR_CYAN);
|
||||
gfx_printf(" preserve.ini: %d Pfad(e) von Update-Bereinigung ausgenommen\n", g_preserve_count);
|
||||
install_set_color(COLOR_WHITE);
|
||||
}
|
||||
|
||||
void install_preserve_update_cleanup_end(void)
|
||||
{
|
||||
if (g_preserve_block) {
|
||||
free(g_preserve_block);
|
||||
g_preserve_block = NULL;
|
||||
}
|
||||
g_preserve_count = 0;
|
||||
g_preserve_update_active = false;
|
||||
}
|
||||
|
||||
/* Valid [Ram] 8gb=0|1 → silent; missing file or invalid → menu. */
|
||||
static int read_ram_config_silent(const char *path, bool *use_8gb)
|
||||
{
|
||||
@@ -884,14 +1039,6 @@ typedef struct {
|
||||
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));
|
||||
@@ -912,25 +1059,25 @@ static void install_debug_load(install_debug_opts_t *d)
|
||||
if (!kv->key || !kv->val)
|
||||
continue;
|
||||
if (strcmp(kv->key, "skip_clean_backup") == 0)
|
||||
d->skip_clean_backup = install_ini_truth(kv->val);
|
||||
d->skip_clean_backup = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_clean_wipe") == 0)
|
||||
d->skip_clean_wipe = install_ini_truth(kv->val);
|
||||
d->skip_clean_wipe = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_clean_restore") == 0)
|
||||
d->skip_clean_restore = install_ini_truth(kv->val);
|
||||
d->skip_clean_restore = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_clean_install") == 0)
|
||||
d->skip_clean_install = install_ini_truth(kv->val);
|
||||
d->skip_clean_install = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_clean_staging_cleanup") == 0)
|
||||
d->skip_clean_staging_cleanup = install_ini_truth(kv->val);
|
||||
d->skip_clean_staging_cleanup = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_update_cleanup") == 0)
|
||||
d->skip_update_cleanup = install_ini_truth(kv->val);
|
||||
d->skip_update_cleanup = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_update_install") == 0)
|
||||
d->skip_update_install = install_ini_truth(kv->val);
|
||||
d->skip_update_install = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_update_staging_cleanup") == 0)
|
||||
d->skip_update_staging_cleanup = install_ini_truth(kv->val);
|
||||
d->skip_update_staging_cleanup = install_ini_kv_truth(kv->val);
|
||||
else if (strcmp(kv->key, "skip_update_horizon_oc") == 0)
|
||||
d->skip_update_horizon_oc = install_ini_truth(kv->val);
|
||||
d->skip_update_horizon_oc = install_ini_kv_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);
|
||||
d->skip_hekate_8gb_post_copy = install_ini_kv_truth(kv->val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user