mirror of
https://github.com/TheCriicom/omega-dashboard-ps5.git
synced 2026-10-17 10:01:25 +02:00
- Il demone legge lo stato di alimentazione dai flag del kernel SceSystemStateMgrInfo e SceSystemStateMgrStatus (come ShadowMountPlus e OnionHEN) e, prima che la console si spenga o si addormenti, ferma musica, voce del party, server di controllo e download di PatchDL e smonta i giochi avviati da un disco esterno (in riposo resta montato quello in primo piano). Al risveglio riparte da solo (power.c). - Spegni, Riavvia e Modalità riposo dal menu di Omega aspettano installazioni, copie e salvataggi online, smontano i giochi esterni e chiedono al demone di fermarsi prima. - /system_ex non resta più montato in scrittura dopo l'avvio di un gioco da disco esterno. - Demone: niente più giri a vuoto se l'uscita audio si rompe; party e notifiche interrogati meno spesso e con attese crescenti senza rete; caricamenti di musica e comandi della voce non bloccano più il server di controllo; la UI riavvia il demone solo se è bloccato davvero; gestore dei crash con stack proprio, SIGTERM gestito, registri sotto 1 MB. - fsync prima di ogni rename (aggiornamenti, caricatori, libreria, lettore, copie dei giochi); le copie interrotte vengono riconosciute e pulite. - Installer: ogni passo di rete finisce in omega-installer.log, incluso nella diagnostica.
130 lines
6.0 KiB
C
130 lines
6.0 KiB
C
// Omega UI — funzioni di servizio condivise: file, codifica degli URL, SHA-256.
|
|
#include "app.h"
|
|
#include <stdlib.h>
|
|
|
|
char *file_read(const char *path, size_t max, size_t *len) {
|
|
FILE *f = fopen(path, "rb");
|
|
if (!f) return NULL;
|
|
char *b = malloc(max + 1);
|
|
size_t n = b ? fread(b, 1, max, f) : 0;
|
|
fclose(f);
|
|
if (!b) return NULL;
|
|
b[n] = 0;
|
|
if (len) *len = n;
|
|
return b;
|
|
}
|
|
|
|
void url_encode(char *dst, size_t n, const char *src, const char *keep) {
|
|
static const char HEX[] = "0123456789ABCDEF";
|
|
size_t o = 0;
|
|
for (const unsigned char *p = (const unsigned char *)src; *p && o + 4 < n; p++) {
|
|
if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || (keep && strchr(keep, *p)))
|
|
dst[o++] = (char)*p;
|
|
else { dst[o++] = '%'; dst[o++] = HEX[*p >> 4]; dst[o++] = HEX[*p & 15]; }
|
|
}
|
|
dst[o] = 0;
|
|
}
|
|
|
|
// ------------------------------------------------------------------- date --
|
|
// Le date si compongono da modelli tradotti con segnaposto {nome}: ogni lingua
|
|
// mette giorno, mese e anno nell'ordine che vuole (es. "{month}{day}日").
|
|
void tmpl_fill(char *out, size_t n, const char *tmpl, const char *const *kv, int nkv) {
|
|
size_t o = 0;
|
|
for (const char *p = tmpl; *p && o + 1 < n;) {
|
|
if (*p == '{') {
|
|
const char *e = strchr(p, '}'); int done = 0;
|
|
for (int i = 0; e && i + 1 < nkv * 2; i += 2)
|
|
if (strlen(kv[i]) == (size_t)(e - p - 1) && !strncmp(p + 1, kv[i], (size_t)(e - p - 1))) {
|
|
o += (size_t)snprintf(out + o, n - o, "%s", kv[i + 1]); if (o >= n) o = n - 1;
|
|
p = e + 1; done = 1; break;
|
|
}
|
|
if (done) continue;
|
|
}
|
|
out[o++] = *p++;
|
|
}
|
|
out[o] = 0;
|
|
}
|
|
|
|
static const char *const MONTH[12] = { N_("gennaio"), N_("febbraio"), N_("marzo"), N_("aprile"), N_("maggio"), N_("giugno"),
|
|
N_("luglio"), N_("agosto"), N_("settembre"), N_("ottobre"), N_("novembre"), N_("dicembre") };
|
|
static const char *const MONTH_ABBR[12] = { N_("gen"), N_("feb"), N_("mar"), N_("apr"), N_("mag"), N_("giu"),
|
|
N_("lug"), N_("ago"), N_("set"), N_("ott"), N_("nov"), N_("dic") };
|
|
static const char *const WDAY[7] = { N_("domenica"), N_("luned\xC3\xAC"), N_("marted\xC3\xAC"), N_("mercoled\xC3\xAC"),
|
|
N_("gioved\xC3\xAC"), N_("venerd\xC3\xAC"), N_("sabato") };
|
|
|
|
void date_long(char *out, size_t n, int wday, int day, int mon) {
|
|
char d[8]; snprintf(d, sizeof d, "%d", day);
|
|
const char *kv[] = { "weekday", _(WDAY[(wday % 7 + 7) % 7]), "day", d, "month", _(MONTH[(mon % 12 + 12) % 12]) };
|
|
tmpl_fill(out, n, _("{weekday} {day} {month}"), kv, 3);
|
|
}
|
|
|
|
void date_short(char *out, size_t n, int day, int mon, int year) {
|
|
char d[8], y[8]; snprintf(d, sizeof d, "%d", day); snprintf(y, sizeof y, "%d", year);
|
|
const char *kv[] = { "day", d, "mon", _(MONTH_ABBR[(mon % 12 + 12) % 12]), "year", y };
|
|
tmpl_fill(out, n, _("{day} {mon} {year}"), kv, 3);
|
|
}
|
|
|
|
uint32_t fnv1a(const char *s) {
|
|
uint32_t h = 2166136261u;
|
|
for (; *s; s++) h = (h ^ (unsigned char)*s) * 16777619u;
|
|
return h;
|
|
}
|
|
|
|
// ------------------------------------------------------------------ SHA-256 --
|
|
|
|
static const uint32_t K256[64] = {
|
|
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,
|
|
0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
|
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,
|
|
0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
|
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
|
|
0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 };
|
|
#define ROR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
|
|
|
|
static void sha_block(Sha256 *c, const unsigned char *p) {
|
|
uint32_t w[64];
|
|
for (int i = 0; i < 16; i++) w[i] = (uint32_t)p[i * 4] << 24 | (uint32_t)p[i * 4 + 1] << 16 | (uint32_t)p[i * 4 + 2] << 8 | p[i * 4 + 3];
|
|
for (int i = 16; i < 64; i++) {
|
|
uint32_t s0 = ROR(w[i - 15], 7) ^ ROR(w[i - 15], 18) ^ (w[i - 15] >> 3), s1 = ROR(w[i - 2], 17) ^ ROR(w[i - 2], 19) ^ (w[i - 2] >> 10);
|
|
w[i] = w[i - 16] + s0 + w[i - 7] + s1;
|
|
}
|
|
uint32_t a = c->s[0], b = c->s[1], cc = c->s[2], d = c->s[3], e = c->s[4], f = c->s[5], g = c->s[6], h = c->s[7];
|
|
for (int i = 0; i < 64; i++) {
|
|
uint32_t t1 = h + (ROR(e, 6) ^ ROR(e, 11) ^ ROR(e, 25)) + ((e & f) ^ (~e & g)) + K256[i] + w[i];
|
|
uint32_t t2 = (ROR(a, 2) ^ ROR(a, 13) ^ ROR(a, 22)) + ((a & b) ^ (a & cc) ^ (b & cc));
|
|
h = g; g = f; f = e; e = d + t1; d = cc; cc = b; b = a; a = t1 + t2;
|
|
}
|
|
c->s[0] += a; c->s[1] += b; c->s[2] += cc; c->s[3] += d; c->s[4] += e; c->s[5] += f; c->s[6] += g; c->s[7] += h;
|
|
}
|
|
|
|
void sha_init(Sha256 *c) {
|
|
static const uint32_t iv[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
|
|
memcpy(c->s, iv, sizeof iv); c->len = 0; c->n = 0;
|
|
}
|
|
|
|
void sha_update(Sha256 *c, const unsigned char *p, size_t n) {
|
|
c->len += n;
|
|
while (n) {
|
|
size_t k = 64 - c->n; if (k > n) k = n;
|
|
memcpy(c->buf + c->n, p, k); c->n += k; p += k; n -= k;
|
|
if (c->n == 64) { sha_block(c, c->buf); c->n = 0; }
|
|
}
|
|
}
|
|
|
|
void sha_hex(Sha256 *c, char out[65]) {
|
|
uint64_t bits = c->len * 8; unsigned char pad = 0x80, z = 0;
|
|
sha_update(c, &pad, 1);
|
|
while (c->n != 56) sha_update(c, &z, 1);
|
|
unsigned char L[8]; for (int i = 0; i < 8; i++) L[i] = (unsigned char)(bits >> (56 - 8 * i));
|
|
sha_update(c, L, 8);
|
|
for (int i = 0; i < 8; i++) snprintf(out + i * 8, 9, "%08x", c->s[i]);
|
|
}
|
|
|
|
int file_sha256(const char *path, char out[65]) {
|
|
FILE *f = fopen(path, "rb"); if (!f) return -1;
|
|
unsigned char *b = malloc(65536); if (!b) { fclose(f); return -1; } // anche dai thread: niente 64 KB sullo stack
|
|
Sha256 c; sha_init(&c); size_t k;
|
|
while ((k = fread(b, 1, 65536, f)) > 0) sha_update(&c, b, k);
|
|
free(b); fclose(f); sha_hex(&c, out); return 0;
|
|
}
|