Files
2026-10-19 23:10:28 +03:30

163 lines
4.7 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
#include <ps5/kernel.h>
int sceKernelDebugOutText(int class, const char *text);
#define DBG_CLASS 0x80
static void
dbg(const char *fmt, ...)
{
char buf[512];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof buf, fmt, args);
va_end(args);
sceKernelDebugOutText(DBG_CLASS, buf);
}
typedef struct notify_request {
char useless1[45];
char message[3075];
} notify_request_t;
int sceKernelSendNotificationRequest(int, notify_request_t *, size_t, int);
static void
notify(const char *fmt, ...)
{
notify_request_t req;
char buf[512];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof buf, fmt, args);
va_end(args);
sceKernelDebugOutText(DBG_CLASS, buf);
__builtin_memset(&req, 0, sizeof req);
snprintf(req.message, sizeof req.message, "%s", buf);
sceKernelSendNotificationRequest(0, &req, sizeof req, 0);
}
typedef struct {
const char *label;
const char *relative_path;
} cache_file_t;
static const cache_file_t CACHE_FILES[] = {
// cookies
{ "Cookies", "webkit/shell/NKCookie.jar.db" },
{ "Cookies", "webkit/shell/NKCookie.jar.db-shm" },
{ "Cookies", "webkit/shell/NKCookie.jar.db-wal" },
// appcache
{ "AppCache", "webkit/shell/appcache/ApplicationCache.db" },
{ "AppCache", "webkit/shell/appcache/ApplicationCache.db-shm" },
{ "AppCache", "webkit/shell/appcache/ApplicationCache.db-wal" },
// localstorage
{ "Local", "webkit/shell/local/https_manuals.playstation.net_0.localstorage" },
{ "Local", "webkit/shell/local/https_manuals.playstation.net_0.localstorage-shm" },
{ "Local", "webkit/shell/local/https_manuals.playstation.net_0.localstorage-wal" },
// resource stats
{ "ResStats", "webkit/shell/resourceloadstatistics/full_browsing_session_resourceLog.plist" },
};
#define NUM_FILES (sizeof(CACHE_FILES) / sizeof(CACHE_FILES[0]))
static int
delete_user_files(const char *userfolder)
{
char path[512];
struct stat st;
int removed = 0;
const char *last_label = NULL;
dbg("[appcache] processing user: %s\n", userfolder);
notify("AppCache Remove\nRemoving for user: %s", userfolder);
for (size_t i = 0; i < NUM_FILES; i++) {
const cache_file_t *f = &CACHE_FILES[i];
int n = snprintf(path, sizeof path, "/user/home/%s/%s",
userfolder, f->relative_path);
if (n < 0 || (size_t)n >= sizeof path) {
dbg("[appcache] skip (path too long): %s/%s\n", userfolder, f->relative_path);
continue;
}
// toast once per label group
if (!last_label || strcmp(last_label, f->label) != 0) {
notify("AppCache Remove\nRemoving %s...", f->label);
last_label = f->label;
}
if (stat(path, &st) != 0) {
dbg("[appcache] not found: %s\n", path);
continue;
}
if (remove(path) == 0) {
dbg("[appcache] deleted: %s\n", path);
removed++;
} else {
dbg("[appcache] failed (errno %d): %s\n", errno, path);
notify("AppCache Remove\nFailed to remove %s\n(errno %d)", f->label, errno);
}
}
dbg("[appcache] user %s: %d file(s) removed\n", userfolder, removed);
return removed;
}
static void
process_all_users(void)
{
DIR *dir;
struct dirent *entry;
int total = 0, users = 0;
dir = opendir("/user/home");
if (!dir) {
dbg("[appcache] opendir failed, errno %d\n", errno);
notify("AppCache Remove\nFailed to open /user/home\n(errno %d)", errno);
return;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.' &&
(entry->d_name[1] == '\0' ||
(entry->d_name[1] == '.' && entry->d_name[2] == '\0')))
continue;
users++;
total += delete_user_files(entry->d_name);
}
closedir(dir);
if (!users) {
notify("AppCache Remove\nNo user folders found under /user/home.");
} else {
dbg("[appcache] done: %d file(s) across %d user(s)\n", total, users);
notify("AppCache Remove: Done!\nRemoved %d file(s) across %d user(s).", total, users);
}
}
int
main(void)
{
dbg("[appcache] started\n");
notify("AppCache Remove " VERSION_STR "\nRemoving for all Users...");
process_all_users();
dbg("[appcache] done\n");
return 0;
}