SUCCESS: Asterisk service restarted successfully.';
} else {
echo 'Failed to restart Asterisk.
' . htmlspecialchars($out);
}
exit;
}
// ==========================================================
// File Listing
// ==========================================================
if (isset($_GET['action']) && $_GET['action'] === 'list') {
$uploadDir = freeloader_validate_dir($_GET['dir'] ?? '/my_uploads');
if ($uploadDir === false) {
echo "
Directory not permitted or not found.
";
exit;
}
$files = @scandir($uploadDir);
if ($files === false) {
echo "Cannot read directory.
";
exit;
}
echo '';
echo '';
echo '| File | ';
echo 'Size | ';
echo 'Modified | ';
echo 'Action | ';
echo '
';
foreach ($files as $f) {
if ($f === '.' || $f === '..') {
continue;
}
// Hide dotfiles (.htaccess, .htpasswd, .git, etc.)
if (isset($f[0]) && $f[0] === '.') {
continue;
}
$full = $uploadDir . '/' . $f;
if (is_dir($full)) {
continue;
}
$size = round(@filesize($full) / 1024, 2) . ' KB';
$mtime = date('Y-m-d H:i', @filemtime($full) ?: time());
$isEditable = freeloader_is_editable_filename($f)
&& !freeloader_is_dangerous_filename($f);
$safeName = htmlspecialchars($f, ENT_QUOTES, 'UTF-8');
$jsName = json_encode($f, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
echo "";
echo "| {$safeName} | ";
echo "{$size} | ";
echo "{$mtime} | ";
echo "";
echo "";
if ($isEditable) {
echo "";
}
echo "";
echo ' |
';
}
echo '
';
exit;
}
// ==========================================================
// Get file content for editing
// ==========================================================
if (isset($_GET['action']) && $_GET['action'] === 'get') {
$filename = freeloader_validate_filename($_GET['file'] ?? '');
$targetDir = freeloader_validate_dir($_GET['dir'] ?? '');
if ($filename === false || $targetDir === false) {
header('Content-Type: text/plain; charset=utf-8');
echo 'ERROR: Invalid directory or filename.';
exit;
}
if (freeloader_is_dangerous_filename($filename) || !freeloader_is_editable_filename($filename)) {
header('Content-Type: text/plain; charset=utf-8');
echo 'ERROR: File type is not editable.';
exit;
}
$path = $targetDir . '/' . $filename;
if (!is_file($path)) {
header('Content-Type: text/plain; charset=utf-8');
echo 'ERROR: File not found.';
exit;
}
$content = @file_get_contents($path);
if ($content === false) {
[$ok, $out] = freeloader_helper('cat', [$path]);
if (!$ok) {
header('Content-Type: text/plain; charset=utf-8');
echo 'ERROR: Cannot read file.';
exit;
}
$content = $out;
}
header('Content-Type: text/plain; charset=utf-8');
echo $content;
exit;
}
// ==========================================================
// Save edited file
// ==========================================================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'save') {
if (!freeloader_verify_csrf($_POST['csrf'] ?? null)) {
http_response_code(403);
die('Invalid CSRF token.');
}
$filename = freeloader_validate_filename($_POST['file'] ?? '');
$targetDir = freeloader_validate_dir($_POST['dir'] ?? '');
$content = $_POST['content'] ?? '';
if ($filename === false || $targetDir === false) {
echo 'Invalid parameters.';
exit;
}
if (freeloader_is_dangerous_filename($filename)) {
echo 'Saving executable / dangerous file types is blocked.';
exit;
}
if (!freeloader_is_editable_filename($filename)) {
echo 'Filename does not match an allowed editable pattern.';
exit;
}
$path = $targetDir . '/' . $filename;
$tmp = tempnam(sys_get_temp_dir(), 'freeloader_');
if ($tmp === false || file_put_contents($tmp, $content) === false) {
echo 'Failed to create temporary file.';
exit;
}
chmod($tmp, 0644);
[$ok, $out] = freeloader_helper('cp', [$tmp, $path]);
@unlink($tmp);
if ($ok) {
echo 'SUCCESS: ' . htmlspecialchars($filename) . ' saved to ' . htmlspecialchars($targetDir);
} else {
echo 'Failed to save file. ' . htmlspecialchars($out);
}
exit;
}
// ==========================================================
// Upload handling
// ==========================================================
if (!isset($_FILES['file'])) {
echo 'No file uploaded.';
exit;
}
if (!freeloader_verify_csrf($_POST['csrf'] ?? null)) {
http_response_code(403);
die('Invalid CSRF token.');
}
$file = $_FILES['file'];
$filename = freeloader_validate_filename($file['name'] ?? '');
if ($filename === false) {
echo 'Invalid filename.';
exit;
}
if (($file['size'] ?? 0) > 50 * 1024 * 1024) {
echo 'File too large (maximum 50 MB).';
exit;
}
if (freeloader_is_dangerous_filename($filename)) {
echo 'Uploading executable / dangerous file types is blocked for security.';
exit;
}
$targetDir = freeloader_validate_dir($_POST['target_dir'] ?? '/my_uploads');
if ($targetDir === false) {
echo 'Target directory not permitted.';
exit;
}
if (!is_dir($targetDir)) {
echo 'Target directory does not exist.';
exit;
}
$targetFile = $targetDir . '/' . $filename;
$tmpFile = $file['tmp_name'];
[$ok, $out] = freeloader_helper('cp', [$tmpFile, $targetFile]);
if ($ok) {
echo 'SUCCESS: ' . htmlspecialchars($filename) . ' uploaded to ' . htmlspecialchars($targetDir);
} else {
if (@move_uploaded_file($tmpFile, $targetFile)) {
@chmod($targetFile, 0664);
echo 'SUCCESS: ' . htmlspecialchars($filename) . ' uploaded to ' . htmlspecialchars($targetDir);
} else {
echo 'Failed to upload file. ' . htmlspecialchars($out);
}
}