Rename project to BFpilot

This commit is contained in:
ItsBlurf committed 2026-06-02 14:27:18 +01:00
1 parent 4fe9cc4dc7
commit 968fee8601
20 files changed
+114 -108

No files matched your search

+3 -3
View File
@@ -1,4 +1,4 @@
# BS5FileManager - minimal PS5 browser file manager payload.
# BFpilot - minimal PS5 browser file manager payload.
PS5_HOST ?= ps5
PS5_PORT ?= 9021
@@ -9,7 +9,7 @@ else
$(error PS5_PAYLOAD_SDK is undefined)
endif
VERSION_TAG := bs5fm-v0.2.0
VERSION_TAG := bfpilot-v0.2.0
BUILD_VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
PYTHON ?= python3
HOST_LLVM_BINDIR ?= $(shell dirname "$$(command -v llvm-strip 2>/dev/null || command -v llvm-strip.exe 2>/dev/null || echo llvm-strip)" 2>/dev/null)
@@ -21,7 +21,7 @@ export LLVM_CONFIG ?= $(UNIX_CURDIR)/build-tools/llvm-config
BUILD_PATH := $(UNIX_CURDIR)/build-tools:$(HOST_LLVM_BINDIR):/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Users/Blurf/scoop/shims
BUILD_ENV := cd "$(UNIX_CURDIR)"; export LLVM_CONFIG="$(LLVM_CONFIG)"; export LLVM_BINDIR="$(LLVM_BINDIR)"; export PATH="$(BUILD_PATH):$$PATH"
BIN := bs5filemanager.elf
BIN := bfpilot.elf
SRCS := src/lite_main.c
SRCS += src/websrv_lite.c
+16 -16
View File
@@ -1,7 +1,7 @@
# BS5FileManager
# BFpilot
BS5FileManager is a small PS5 payload that gives you a browser-based file
manager on port `5905`.
BFpilot is a small PS5 payload that gives you a browser-based file manager on
port `5905`.
It is meant to stay simple: no PKG installer, no FTP daemon, no mounting tools,
and no extra payload bundle. The payload starts one web server, refreshes a PS5
@@ -12,7 +12,7 @@ Current release: `v0.2.0`
## What It Does
- Runs a file-manager web UI at `http://<PS5_IP>:5905/`
- Installs or refreshes a `BS5FileManager` launcher tile on the PS5 home screen
- Installs or refreshes a `BFpilot` launcher tile on the PS5 home screen
- Uses a dark-only UI
- Uses the same folder-and-sword icon for the PS5 launcher and web UI
- Browses, uploads, downloads, copies, moves, renames, creates folders, and deletes
@@ -44,18 +44,18 @@ http://<PS5_IP>:5905/
The payload stores launcher marker data in:
```text
/data/BS5fm
/data/BFpilot
```
The PS5 launcher app itself is installed under:
```text
/user/app/BSFM00001
/user/app/BFPILOT01
```
The installer also removes the older experimental launcher title ID
`BS5F00001` before registering `BSFM00001`, so old tiles from earlier builds do
not get in the way.
The installer removes older launcher title IDs from previous names before
registering `BFPILOT01`, so stale tiles from earlier builds do not get in the
way.
## Project Layout
@@ -93,7 +93,7 @@ make
Output:
```text
bs5filemanager.elf
bfpilot.elf
```
Deploy helper:
@@ -104,13 +104,13 @@ make deploy PS5_HOST=<PS5_IP> PS5_PORT=9021
## Extra Notes
BS5FileManager avoids kernel-level cleanup and does not force-unload other
payloads.
BFpilot avoids kernel-level cleanup and does not force-unload other payloads.
If you reinject while an older BS5FileManager is already running, the new payload
checks whether a file job is active. If the old instance is idle, it asks it to
shut down cleanly and then takes over port `5905`. If a copy, move, or delete is
running, the new injection exits instead of interrupting the active job.
If you reinject while an older BFpilot or BS5FileManager instance is already
running, the new payload checks whether a file job is active. If the old
instance is idle, it asks it to shut down cleanly and then takes over port
`5905`. If a copy, move, or delete is running, the new injection exits instead
of interrupting the active job.
Cancel is cooperative. Large operations may take a moment to stop, especially on
external USB drives, but the job code checks for cancellation during scan, copy,
+2 -2
View File
@@ -1,11 +1,11 @@
{
"applicationCategoryType": 0,
"titleId": "BSFM00001",
"titleId": "BFPILOT01",
"deeplinkUri": "http://127.0.0.1:5905/",
"localizedParameters": {
"defaultLanguage": "en-US",
"en-US": {
"titleName": "BS5FileManager"
"titleName": "BFpilot"
}
}
}
+3 -3
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/icon.png">
<title>BS5FileManager</title>
<title>BFpilot</title>
<style>
:root {
--paper: #090d12;
@@ -563,7 +563,7 @@
<div class="top-inner">
<img class="brand" src="/icon.png" alt="">
<div class="title">
<strong>BS5FileManager</strong>
<strong>BFpilot</strong>
<span id="build">File Manager</span>
</div>
<div class="status" id="status"><span class="dot"></span><span>Connecting</span></div>
@@ -1370,7 +1370,7 @@
const status = el('status');
status.classList.add('ready');
status.querySelector('span:last-child').textContent = 'Ready';
el('build').textContent = (info.tag || 'bs5fm') + ' / port 5905';
el('build').textContent = (info.tag || 'bfpilot') + ' / port 5905';
}).catch(() => {
el('status').querySelector('span:last-child').textContent = 'Offline';
});
+47 -42
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - install the PS5 home-screen web launcher tile.
* BFpilot - install the PS5 home-screen web launcher tile.
*/
#include <errno.h>
@@ -15,13 +15,14 @@
#include "app_installer.h"
#include "notify.h"
#define BS5FM_APP_TITLE_ID "BSFM00001"
#define BS5FM_LEGACY_APP_TITLE_ID "BS5F00001"
#define BS5FM_APP_ROOT "/user/app"
#define BS5FM_APP_PARENT BS5FM_APP_ROOT "/"
#define BS5FM_DATA_DIR "/data/BS5fm"
#define BS5FM_MARKER_PATH BS5FM_DATA_DIR "/launcher.ok"
#define BS5FM_INSTALL_MARKER "bs5filemanager-launcher-v5\n"
#define BFPILOT_APP_TITLE_ID "BFPILOT01"
#define BFPILOT_LEGACY_APP_TITLE_ID "BSFM00001"
#define BFPILOT_OLD_LEGACY_APP_TITLE_ID "BS5F00001"
#define BFPILOT_APP_ROOT "/user/app"
#define BFPILOT_APP_PARENT BFPILOT_APP_ROOT "/"
#define BFPILOT_DATA_DIR "/data/BFpilot"
#define BFPILOT_MARKER_PATH BFPILOT_DATA_DIR "/launcher.ok"
#define BFPILOT_INSTALL_MARKER "bfpilot-launcher-v1\n"
#define INCASSET(name, file) \
__asm__(".section .rodata\n" \
@@ -35,8 +36,8 @@
extern const uint8_t name[]; \
extern const size_t name##_size
INCASSET(bs5fm_param_json, "assets-app/param.json");
INCASSET(bs5fm_icon0_png, "assets-app/icon0.png");
INCASSET(bfpilot_param_json, "assets-app/param.json");
INCASSET(bfpilot_icon0_png, "assets-app/icon0.png");
int sceAppInstUtilInitialize(void);
int sceAppInstUtilAppInstallAll(void *);
@@ -45,7 +46,7 @@ int sceAppInstUtilAppUnInstall(const char *);
typedef int (*app_install_title_dir_fn)(const char *, const char *, void *);
static const uint8_t g_install_marker[] = BS5FM_INSTALL_MARKER;
static const uint8_t g_install_marker[] = BFPILOT_INSTALL_MARKER;
static int
@@ -118,12 +119,12 @@ mkdir_if_needed(const char *path) {
static int
ensure_data_dir(void) {
if(mkdir_if_needed("/data") != 0) return -1;
return mkdir_if_needed(BS5FM_DATA_DIR);
return mkdir_if_needed(BFPILOT_DATA_DIR);
}
int
bs5fm_install_app_if_needed(void) {
bfpilot_install_app_if_needed(void) {
char app_dir[256];
char sce_sys_dir[256];
char param_path[256];
@@ -131,78 +132,82 @@ bs5fm_install_app_if_needed(void) {
char msg[128];
struct stat st;
snprintf(app_dir, sizeof(app_dir), BS5FM_APP_ROOT "/%s", BS5FM_APP_TITLE_ID);
snprintf(app_dir, sizeof(app_dir), BFPILOT_APP_ROOT "/%s",
BFPILOT_APP_TITLE_ID);
snprintf(sce_sys_dir, sizeof(sce_sys_dir), "%s/sce_sys", app_dir);
snprintf(param_path, sizeof(param_path), "%s/param.json", sce_sys_dir);
snprintf(icon_path, sizeof(icon_path), "%s/icon0.png", sce_sys_dir);
int app_exists = stat(app_dir, &st) == 0;
int assets_changed = !app_exists ||
file_differs(param_path, bs5fm_param_json,
bs5fm_param_json_size) ||
file_differs(icon_path, bs5fm_icon0_png,
bs5fm_icon0_png_size) ||
file_differs(BS5FM_MARKER_PATH, g_install_marker,
sizeof(g_install_marker) - 1);
file_differs(param_path, bfpilot_param_json,
bfpilot_param_json_size) ||
file_differs(icon_path, bfpilot_icon0_png,
bfpilot_icon0_png_size) ||
file_differs(BFPILOT_MARKER_PATH, g_install_marker,
sizeof(g_install_marker) - 1);
if(app_exists && assets_changed) {
bs5fm_notify("BS5FileManager app", "Updating PS5 home-screen launcher");
bfpilot_notify("BFpilot app", "Updating PS5 home-screen launcher");
} else if(app_exists) {
bs5fm_notify("BS5FileManager app", "Refreshing PS5 home-screen launcher");
bfpilot_notify("BFpilot app", "Refreshing PS5 home-screen launcher");
} else {
bs5fm_notify("BS5FileManager app", "Installing PS5 home-screen launcher");
bfpilot_notify("BFpilot app", "Installing PS5 home-screen launcher");
}
int err = sceAppInstUtilInitialize();
if(err) {
printf(" launcher install: sceAppInstUtilInitialize failed 0x%08x\n", err);
snprintf(msg, sizeof(msg), "AppInst init failed 0x%08x", err);
bs5fm_notify("BS5FileManager app failed", msg);
bfpilot_notify("BFpilot app failed", msg);
return -1;
}
int uninstall_err = sceAppInstUtilAppUnInstall(BS5FM_APP_TITLE_ID);
printf(" launcher install: refresh old tile 0x%08x\n", uninstall_err);
uninstall_err = sceAppInstUtilAppUnInstall(BS5FM_LEGACY_APP_TITLE_ID);
printf(" launcher install: remove legacy tile 0x%08x\n", uninstall_err);
int uninstall_err = sceAppInstUtilAppUnInstall(BFPILOT_APP_TITLE_ID);
printf(" launcher install: refresh BFpilot tile 0x%08x\n", uninstall_err);
uninstall_err = sceAppInstUtilAppUnInstall(BFPILOT_LEGACY_APP_TITLE_ID);
printf(" launcher install: remove BS5FileManager tile 0x%08x\n",
uninstall_err);
uninstall_err = sceAppInstUtilAppUnInstall(BFPILOT_OLD_LEGACY_APP_TITLE_ID);
printf(" launcher install: remove old legacy tile 0x%08x\n", uninstall_err);
if(mkdir_if_needed(app_dir) != 0 || mkdir_if_needed(sce_sys_dir) != 0) {
printf(" launcher install: mkdir failed errno %d\n", errno);
snprintf(msg, sizeof(msg), "mkdir failed errno %d", errno);
bs5fm_notify("BS5FileManager app failed", msg);
bfpilot_notify("BFpilot app failed", msg);
return -1;
}
if(write_file(param_path, bs5fm_param_json, bs5fm_param_json_size) != 0) {
if(write_file(param_path, bfpilot_param_json, bfpilot_param_json_size) != 0) {
printf(" launcher install: failed writing %s\n", param_path);
bs5fm_notify("BS5FileManager app failed", "could not write param.json");
bfpilot_notify("BFpilot app failed", "could not write param.json");
return -1;
}
if(write_file(icon_path, bs5fm_icon0_png, bs5fm_icon0_png_size) != 0) {
if(write_file(icon_path, bfpilot_icon0_png, bfpilot_icon0_png_size) != 0) {
printf(" launcher install: failed writing %s\n", icon_path);
bs5fm_notify("BS5FileManager app failed", "could not write icon0.png");
bfpilot_notify("BFpilot app failed", "could not write icon0.png");
return -1;
}
err = install_app(BS5FM_APP_TITLE_ID, BS5FM_APP_PARENT);
err = install_app(BFPILOT_APP_TITLE_ID, BFPILOT_APP_PARENT);
if(err) {
printf(" launcher install: install_app failed 0x%08x\n", err);
snprintf(msg, sizeof(msg), "register BSFM00001 failed 0x%08x", err);
bs5fm_notify("BS5FileManager app failed", msg);
snprintf(msg, sizeof(msg), "register BFPILOT01 failed 0x%08x", err);
bfpilot_notify("BFpilot app failed", msg);
return -1;
}
if(ensure_data_dir() != 0) {
printf(" launcher install: warning, failed creating %s errno %d\n",
BS5FM_DATA_DIR, errno);
} else if(write_file(BS5FM_MARKER_PATH, g_install_marker,
sizeof(g_install_marker) - 1) != 0) {
BFPILOT_DATA_DIR, errno);
} else if(write_file(BFPILOT_MARKER_PATH, g_install_marker,
sizeof(g_install_marker) - 1) != 0) {
printf(" launcher install: warning, failed writing %s\n",
BS5FM_MARKER_PATH);
BFPILOT_MARKER_PATH);
}
bs5fm_notify("BS5FileManager app ready",
"Tile BSFM00001 opens http://127.0.0.1:5905/");
bfpilot_notify("BFpilot app ready",
"Tile BFPILOT01 opens http://127.0.0.1:5905/");
return 1;
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - PS5 home-screen launcher installer.
* BFpilot - PS5 home-screen launcher installer.
*
* Returns 1 when the launcher was installed/updated, 0 when it was already
* current, and -1 on failure.
@@ -7,4 +7,4 @@
#pragma once
int bs5fm_install_app_if_needed(void);
int bfpilot_install_app_if_needed(void);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - embedded static assets.
* BFpilot - embedded static assets.
*/
#include <limits.h>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - embedded asset registry.
* BFpilot - embedded asset registry.
*/
#pragma once
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - direct file and directory serving.
* BFpilot - direct file and directory serving.
*/
#include <dirent.h>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - direct file serving helpers.
* BFpilot - direct file serving helpers.
*/
#pragma once
+23 -22
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - minimal PS5 browser file manager payload.
* BFpilot - minimal PS5 browser file manager payload.
*
* Runtime surface is intentionally small: one HTTP file-manager server,
* startup notification, and no companion side services.
@@ -25,8 +25,8 @@
#include "version.h"
#include "websrv.h"
#define BS5FM_WEB_PORT 5905
#define BS5FM_RELOAD_TOKEN "bs5fm-local-reload"
#define BFPILOT_WEB_PORT 5905
#define BFPILOT_RELOAD_TOKEN "bs5fm-local-reload"
int sceNetCtlInit(void);
int sceUserServiceInitialize(void *);
@@ -90,7 +90,7 @@ local_http_get(const char *path, char *out, size_t out_size) {
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(BS5FM_WEB_PORT);
addr.sin_port = htons(BFPILOT_WEB_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if(connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
@@ -104,7 +104,7 @@ local_http_get(const char *path, char *out, size_t out_size) {
"Host: 127.0.0.1:%u\r\n"
"Connection: close\r\n"
"\r\n",
path, (unsigned int)BS5FM_WEB_PORT);
path, (unsigned int)BFPILOT_WEB_PORT);
if(n < 0 || (size_t)n >= sizeof(request) ||
websrv_write_all(fd, request, (size_t)n) != 0) {
close(fd);
@@ -173,7 +173,8 @@ handoff_existing_server(void) {
if(local_http_get("/api/status", response, sizeof(response)) != 0) {
return 0;
}
if(!strstr(response, "\"name\":\"BS5FileManager\"")) {
if(!strstr(response, "\"name\":\"BFpilot\"") &&
!strstr(response, "\"name\":\"BS5FileManager\"")) {
return 0;
}
@@ -183,36 +184,36 @@ handoff_existing_server(void) {
}
if(old_server_busy()) {
bs5fm_notify("BS5FileManager reload skipped",
"Old file operation is still running");
bfpilot_notify("BFpilot reload skipped",
"Old file operation is still running");
return -1;
}
snprintf(response, sizeof(response),
"/api/control/shutdown?token=%s", BS5FM_RELOAD_TOKEN);
"/api/control/shutdown?token=%s", BFPILOT_RELOAD_TOKEN);
char shutdown_response[512];
if(local_http_get(response, shutdown_response,
sizeof(shutdown_response)) == 0 &&
strstr(shutdown_response, "200 OK") &&
strstr(shutdown_response, "\"ok\":true") &&
wait_for_old_server_down()) {
bs5fm_notify("BS5FileManager reloaded", "Old listener stopped cleanly");
bfpilot_notify("BFpilot reloaded", "Old listener stopped cleanly");
return 1;
}
if(kill((pid_t)old_pid, SIGTERM) == 0 && wait_for_old_server_down()) {
bs5fm_notify("BS5FileManager reloaded", "Old listener stopped");
bfpilot_notify("BFpilot reloaded", "Old listener stopped");
return 1;
}
kill((pid_t)old_pid, SIGKILL);
if(wait_for_old_server_down()) {
bs5fm_notify("BS5FileManager reloaded", "Old listener was replaced");
bfpilot_notify("BFpilot reloaded", "Old listener was replaced");
return 1;
}
bs5fm_notify("BS5FileManager reload failed",
"Could not stop old listener on port 5905");
bfpilot_notify("BFpilot reload failed",
"Could not stop old listener on port 5905");
return -1;
}
@@ -228,7 +229,7 @@ on_web_ready(unsigned short port, void *arg) {
printf(" web ui ready: http://%s:%u/\n", state->ip, (unsigned int)port);
if(!state->notified) {
bs5fm_notify("BS5FileManager started", url);
bfpilot_notify("BFpilot started", url);
state->notified = 1;
}
}
@@ -244,14 +245,14 @@ main(int argc, char **argv) {
detect_lan_ip(ready.ip, sizeof(ready.ip));
puts(".----------------------------------------------.");
puts("| BS5FileManager |");
puts("| BFpilot |");
printf("| %-18s browser file manager |\n", VERSION_TAG);
puts("'----------------------------------------------'");
puts("");
puts(" active: standalone web file manager");
puts(" scope: browse, upload, download, copy, move, delete, rename, mkdir");
puts(" ps5 app: BS5FileManager opens http://127.0.0.1:5905/");
printf(" web ui: http://%s:%u/\n", ready.ip, (unsigned int)BS5FM_WEB_PORT);
puts(" ps5 app: BFpilot opens http://127.0.0.1:5905/");
printf(" web ui: http://%s:%u/\n", ready.ip, (unsigned int)BFPILOT_WEB_PORT);
puts(" inject/deploy port: 9021");
puts("");
@@ -260,7 +261,7 @@ main(int argc, char **argv) {
init_ps5_services();
int app_install_status = bs5fm_install_app_if_needed();
int app_install_status = bfpilot_install_app_if_needed();
if(app_install_status >= 0) {
puts(" ps5 app: ready");
} else {
@@ -274,7 +275,7 @@ main(int argc, char **argv) {
}
while(1) {
int rc = websrv_listen(BS5FM_WEB_PORT, on_web_ready, &ready);
int rc = websrv_listen(BFPILOT_WEB_PORT, on_web_ready, &ready);
if(websrv_exit_requested()) {
puts(" web ui: shutdown requested");
break;
@@ -282,8 +283,8 @@ main(int argc, char **argv) {
if(!ready.notified) {
char msg[128];
snprintf(msg, sizeof(msg), "port %u error %d, retrying",
(unsigned int)BS5FM_WEB_PORT, -rc);
bs5fm_notify("BS5FileManager could not start", msg);
(unsigned int)BFPILOT_WEB_PORT, -rc);
bfpilot_notify("BFpilot could not start", msg);
ready.notified = 1;
}
sleep(rc == -EADDRINUSE || rc == -EACCES ? 5 : 2);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - small MIME helper for direct downloads.
* BFpilot - small MIME helper for direct downloads.
*
* The UI only needs enough types for browser previews and common archives.
* Unknown extensions fall back to application/octet-stream in the caller.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - MIME lookup.
* BFpilot - MIME lookup.
*/
#pragma once
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - PS5 notification helpers.
* BFpilot - PS5 notification helpers.
*/
#include <stdbool.h>
@@ -39,9 +39,9 @@ notify_debug(const char *message, const char *submessage) {
void
bs5fm_notify(const char *message, const char *submessage) {
bfpilot_notify(const char *message, const char *submessage) {
char payload[4096];
const char *msg = message ? message : "BS5FileManager";
const char *msg = message ? message : "BFpilot";
const char *sub = submessage ? submessage : "";
snprintf(payload, sizeof(payload),
+2 -2
View File
@@ -1,8 +1,8 @@
/*
* BS5FileManager - PS5 notification helpers.
* BFpilot - PS5 notification helpers.
*/
#pragma once
void bs5fm_notify(const char *message, const char *submessage);
void bfpilot_notify(const char *message, const char *submessage);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - file-manager copy/move/delete primitives and API.
* BFpilot - file-manager copy/move/delete primitives and API.
*/
#include <ctype.h>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - file-manager API.
* BFpilot - file-manager API.
*/
#pragma once
+2 -2
View File
@@ -1,11 +1,11 @@
/*
* BS5FileManager - build version tags.
* BFpilot - build version tags.
*/
#pragma once
#ifndef VERSION_TAG
#define VERSION_TAG "bs5fm-v0.2.0"
#define VERSION_TAG "bfpilot-v0.2.0"
#endif
#ifndef BUILD_VERSION
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - tiny HTTP server helpers.
* BFpilot - tiny HTTP server helpers.
*/
#pragma once
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* BS5FileManager - tiny single-purpose HTTP server.
* BFpilot - tiny single-purpose HTTP server.
*/
#include <ctype.h>
@@ -273,7 +273,7 @@ status_request(const http_request_t *req) {
time_t now = time(NULL);
int n = snprintf(body, sizeof(body),
"{\"ok\":true,"
"\"name\":\"BS5FileManager\","
"\"name\":\"BFpilot\","
"\"tag\":\"%s\","
"\"version\":\"%s\","
"\"pid\":%ld,"