mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
Implement getservbyname (H1bArJPagV0) in libScePosixForWebKit. Cloud Play (PPSA99600) imports it from this library only (registry index 408, call site 0x1042124); once fnmatch (#3545) is in, its predicted load stop is: FAIL: unresolved ELF import H1bArJPagV0 from libScePosixForWebKit.prx The ps5-payload-dev SDK stubs (f5d40f02, sce_stubs/) declare getservbyname in libScePosixForWebKit.c and not in libkernel.c or libSceLibcInternal.c. The call site is the service-name branch of a getaddrinfo inside the title: a non-numeric service is looked up with protocol "tcp", "udp" or "sctp" and the port is read big-endian at offset 16 of the result, which fixes the servent layout used here (name, aliases, 32-bit port, protocol at 0, 8, 16, 24). The guest has no /etc/services and the console's file is unknown, so the function searches 37 lines of FreeBSD 11.4 etc/services (8c639945): ftp-data, ftp, ssh, telnet, smtp, domain, tftp, http, pop3, ntp, imap, https, rtsp, submission, imaps and pop3s with their aliases and protocols, in file order. None of their names or aliases appears on an earlier line of the full file, so these lookups answer as the full file would. The search follows files_servent in lib/libc/net/getservent.c (8c639945): exact, case-sensitive match on the name or an alias, a null protocol takes the first match, the port in network byte order, the result in per-thread storage like getserv's NSS TLS state. Any other name returns null without touching errno, as for a name the file lacks. The repository's getaddrinfo still resolves service names through the host, so there was no table to share; this is recorded in TechnicalDebt.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
63 lines
2.7 KiB
C++
63 lines
2.7 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include "prx/libScePosixForWebKit/GuestResolver.hpp"
|
|
#include <cerrno>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <source_location>
|
|
#include <thread>
|
|
|
|
extern "C" GuestResolver::ServiceEntry* APS5_VABI getservbyname_nid_postfix(const char*, const char*);
|
|
|
|
void Require(bool condition, std::source_location location = std::source_location::current()) {
|
|
if (!condition) {
|
|
std::fprintf(stderr, "Service database check failed at line %u\n", location.line());
|
|
std::abort();
|
|
}
|
|
}
|
|
|
|
bool NetworkPort(const GuestResolver::ServiceEntry* entry, std::uint16_t port) {
|
|
unsigned char bytes[4];
|
|
std::memcpy(bytes, &entry->port, sizeof(bytes));
|
|
return bytes[0] == port >> 8 && bytes[1] == (port & 0xff) && bytes[2] == 0 && bytes[3] == 0;
|
|
}
|
|
|
|
int main() {
|
|
auto* http = getservbyname_nid_postfix("http", "tcp");
|
|
Require(http && std::strcmp(http->name, "http") == 0 && std::strcmp(http->protocol, "tcp") == 0);
|
|
Require(NetworkPort(http, 80));
|
|
Require(http->aliases && std::strcmp(http->aliases[0], "www") == 0);
|
|
Require(std::strcmp(http->aliases[1], "www-http") == 0 && http->aliases[2] == nullptr);
|
|
|
|
auto* https = getservbyname_nid_postfix("https", nullptr);
|
|
Require(https && std::strcmp(https->name, "https") == 0 && std::strcmp(https->protocol, "tcp") == 0);
|
|
Require(NetworkPort(https, 443) && https->aliases && https->aliases[0] == nullptr);
|
|
|
|
auto* domain = getservbyname_nid_postfix("domain", "udp");
|
|
Require(domain && std::strcmp(domain->name, "domain") == 0 && std::strcmp(domain->protocol, "udp") == 0);
|
|
Require(NetworkPort(domain, 53));
|
|
|
|
auto* www = getservbyname_nid_postfix("www", "sctp");
|
|
Require(www && std::strcmp(www->name, "http") == 0 && std::strcmp(www->protocol, "sctp") == 0);
|
|
Require(NetworkPort(www, 80));
|
|
|
|
auto* mail = getservbyname_nid_postfix("mail", nullptr);
|
|
Require(mail && std::strcmp(mail->name, "smtp") == 0 && NetworkPort(mail, 25));
|
|
|
|
errno = 0;
|
|
Require(getservbyname_nid_postfix("no-such-service", nullptr) == nullptr && errno == 0);
|
|
Require(getservbyname_nid_postfix("domain", "sctp") == nullptr);
|
|
Require(getservbyname_nid_postfix("ntp", "TCP") == nullptr);
|
|
Require(getservbyname_nid_postfix("HTTP", "tcp") == nullptr);
|
|
|
|
auto* ntp = getservbyname_nid_postfix("ntp", "udp");
|
|
Require(ntp && NetworkPort(ntp, 123));
|
|
std::thread([] {
|
|
auto* ssh = getservbyname_nid_postfix("ssh", "tcp");
|
|
Require(ssh && std::strcmp(ssh->name, "ssh") == 0 && NetworkPort(ssh, 22));
|
|
}).join();
|
|
Require(std::strcmp(ntp->name, "ntp") == 0 && std::strcmp(ntp->protocol, "udp") == 0 && NetworkPort(ntp, 123));
|
|
return 0;
|
|
}
|