mirror of
https://github.com/knutwurst/patchdl.git
synced 2026-10-10 21:00:28 +02:00
Standalone PS5 payload with an embedded web UI on :12880, no etaHEN. - Scans installed titles and classifies the source (genuine install, ShadowMountPlus mount, preinstall, unknown) from the on-disk layout. - Reads name, installed version and the Sony version.xml URL from the PS5 app database (vendored SQLite). - Resolves version.xml past nanoDNS via a raw DNS query, TLS pinned to the SCEI DNAS root. - Filters patches to the newest one compatible with the current firmware. - Downloads the patch and installs it through AppInstUtil (sysmodule loaded at runtime), gated to genuine installs with a package title-id match guard. - Action-based UI filters and an on-screen startup notification with the URL.
72 lines
1.8 KiB
C
72 lines
1.8 KiB
C
#include "patchdl_notify.h"
|
|
#include "patchdl_version.h"
|
|
|
|
#include <arpa/inet.h>
|
|
#include <ifaddrs.h>
|
|
#include <netinet/in.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
|
|
/* Standard PS5/PS4 on-screen notification (same layout ftpsrv uses). */
|
|
typedef struct {
|
|
char useless1[45];
|
|
char message[3075];
|
|
} notify_request_t;
|
|
|
|
extern int sceKernelSendNotificationRequest(int, notify_request_t *,
|
|
unsigned long, int);
|
|
|
|
static void
|
|
notify(const char *fmt, ...) {
|
|
notify_request_t req;
|
|
va_list ap;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
va_start(ap, fmt);
|
|
vsnprintf(req.message, sizeof(req.message), fmt, ap);
|
|
va_end(ap);
|
|
|
|
sceKernelSendNotificationRequest(0, &req, sizeof(req), 0);
|
|
puts(req.message);
|
|
}
|
|
|
|
/* First non-loopback IPv4 address of the console. */
|
|
static void
|
|
local_ip(char *out, size_t n) {
|
|
struct ifaddrs *ifa = NULL, *p;
|
|
|
|
out[0] = '\0';
|
|
if (getifaddrs(&ifa))
|
|
return;
|
|
|
|
for (p = ifa; p; p = p->ifa_next) {
|
|
char ip[INET_ADDRSTRLEN];
|
|
struct sockaddr_in *s;
|
|
|
|
if (!p->ifa_addr || p->ifa_addr->sa_family != AF_INET)
|
|
continue;
|
|
s = (struct sockaddr_in *)p->ifa_addr;
|
|
if (!inet_ntop(AF_INET, &s->sin_addr, ip, sizeof(ip)))
|
|
continue;
|
|
if (strcmp(ip, "127.0.0.1") && strncmp(ip, "0.", 2)) {
|
|
strncpy(out, ip, n - 1);
|
|
out[n - 1] = '\0';
|
|
break;
|
|
}
|
|
}
|
|
freeifaddrs(ifa);
|
|
}
|
|
|
|
void
|
|
patchdl_notify_startup(unsigned short port) {
|
|
char ip[INET_ADDRSTRLEN] = {0};
|
|
|
|
local_ip(ip, sizeof(ip));
|
|
if (ip[0])
|
|
notify("PatchDL %s by Knutwurst\nhttp://%s:%u/", PATCHDL_VERSION, ip, port);
|
|
else
|
|
notify("PatchDL %s by Knutwurst\nWeb UI on port %u", PATCHDL_VERSION, port);
|
|
}
|