feat(php): live script

backup
flop 3 weeks ago
parent 3d73eca6f7
commit 82458df080
  1. 159
      ts/live.php

@ -0,0 +1,159 @@
<?php
session_start();
define('PASSWORD', 'cttue_avj2305_44');
define('FILES_DIR', __DIR__ . '/avj2305');
define('ACTIVE_FILE', __DIR__ . '/active.txt');
// -- helpers ------------------------------------------------------------------
function is_authed(): bool {
return !empty($_SESSION['auth']);
}
function require_auth(): void {
if (!is_authed()) {
header('Location: ?login');
exit;
}
}
function get_active(): string {
if (file_exists(ACTIVE_FILE)) {
$v = trim(file_get_contents(ACTIVE_FILE));
if ($v !== '') return $v;
}
return '';
}
function set_active(string $filename): void {
file_put_contents(ACTIVE_FILE, $filename);
}
function get_bin_files(): array {
$files = glob(FILES_DIR . '/*.bin');
if (!$files) return [];
return array_map('basename', $files);
}
function safe_filename(string $name): bool {
// basename only, no path traversal, must end in .bin
return $name === basename($name)
&& str_ends_with($name, '.bin')
&& !str_contains($name, "\0");
}
// -- routing ------------------------------------------------------------------
$q = array_key_first($_GET) ?? ''; // first query param key
// POST: login
if ($q === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') {
if (hash_equals(PASSWORD, $_POST['password'] ?? '')) {
$_SESSION['auth'] = true;
header('Location: ?edit');
} else {
header('Location: ?login&err=1');
}
exit;
}
// POST: set active file
if ($q === 'edit' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file'])) {
require_auth();
$f = $_POST['file'];
if (safe_filename($f) && file_exists(FILES_DIR . '/' . $f)) {
set_active($f);
}
header('Location: ?edit');
exit;
}
// GET: login page
if ($q === 'login') { ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Login</title>
<style>
body{font:14px monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#111;color:#eee}
form{display:flex;flex-direction:column;gap:8px;width:220px}
input[type=password]{padding:6px;background:#222;border:1px solid #555;color:#eee}
button{padding:6px;background:#444;border:none;color:#eee;cursor:pointer}
button:hover{background:#555}
.err{color:#f66;font-size:12px}
</style>
</head>
<body>
<form method="post" action="?login">
<label>Password</label>
<input type="password" name="password" autofocus>
<button type="submit">Login</button>
<?php if (!empty($_GET['err'])): ?><span class="err">Wrong password.</span><?php endif; ?>
</form>
</body></html>
<?php exit; }
// GET: edit page
if ($q === 'edit') {
require_auth();
$files = get_bin_files();
$active = get_active();
?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Select File</title>
<style>
body{font:14px monospace;background:#111;color:#eee;padding:24px;margin:0}
h2{margin:0 0 16px}
ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px}
li form{margin:0}
button{padding:6px 12px;background:#333;border:1px solid #555;color:#eee;cursor:pointer;width:100%;text-align:left}
button:hover{background:#444}
button.active{border-color:#6af;color:#6af}
.none{color:#888}
</style>
</head>
<body>
<h2>Live file selector</h2>
<p>Active: <strong><?= $active !== '' ? htmlspecialchars($active) : '<span class="none">none</span>' ?></strong></p>
<?php if ($files): ?>
<ul>
<?php foreach ($files as $f): ?>
<li>
<form method="post" action="?edit">
<input type="hidden" name="file" value="<?= htmlspecialchars($f) ?>">
<button type="submit" <?= $f === $active ? 'class="active"' : '' ?>><?= htmlspecialchars($f) ?></button>
</form>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="none">No .bin files found in avj2305/</p>
<?php endif; ?>
</body></html>
<?php exit; }
// DEFAULT: serve active .bin file
$active = get_active();
if ($active === '') {
http_response_code(404);
exit('No active file set.');
}
if (!safe_filename($active)) {
http_response_code(500);
exit('Invalid filename.');
}
$path = FILES_DIR . '/' . $active;
if (!file_exists($path)) {
http_response_code(404);
exit('File not found.');
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: inline; filename="' . addslashes($active) . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
Loading…
Cancel
Save