Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 74 additions & 38 deletions app/Http/Livewire/Firmwares.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Livewire\Component;
use App\Models\Firmware;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
use GuzzleHttp\Exception\GuzzleException;

class Firmwares extends Component
{
Expand All @@ -18,54 +20,88 @@ public function render()

public function update()
{
session()->flash('message', 'Download started, please wait...');
Log::info("Firmware update started");
$path = Firmware::basedir();
if (!file_exists($path))
mkdir($path);
if (!file_exists($path)) {
mkdir($path, 0755, true);
Log::info("Created directory: " . $path);
}

$tmpfile = tempnam(sys_get_temp_dir(), "firmware-download");
try
{
try {
$client = new \GuzzleHttp\Client();
$r = $client->get('https://api.github.com/repos/raspberrypi/rpi-eeprom/zipball', ['sink' => $tmpfile]);
if ($r->getStatusCode() != 200)
throw new \Exception("Expected HTTP response code 200, but received ".$r->getStatusCode()." ".$r->getReasonPhrase() );
$tmpfile = tempnam(sys_get_temp_dir(), "firmware-download");
Log::info("Temporary file created: " . $tmpfile);

$response = $client->get('https://github.com/raspberrypi/rpi-eeprom/archive/refs/heads/master.zip', [
'sink' => $tmpfile,
'allow_redirects' => true
]);
Log::info("HTTP request sent, response status: " . $response->getStatusCode());

if ($response->getStatusCode() != 200) {
throw new \Exception("Expected HTTP response code 200, but received " . $response->getStatusCode());
}

clearstatcache(true, $tmpfile);
$downloadedFileSize = filesize($tmpfile);
Log::info("Downloaded file size: " . $downloadedFileSize);
if ($downloadedFileSize == 0) {
throw new \Exception("Downloaded file is empty");
}

$zip = new \ZipArchive;
if (!$zip->open($tmpfile))
throw new \Exception("Error opening .zip file");

// We only want rpi-eeprom-something/firmware/* of the .zip
$prefix = $zip->getNameIndex(0);
if (!$prefix)
throw new \Exception("Error listing .zip file");

$prefix .= "firmware/";

for ($i = 1; $i < $zip->numFiles; $i++)
{
$name = Str::of($zip->getNameIndex($i));
if (!$name->startsWith($prefix) || $name->contains("../"))
continue;

$nameWithoutPrefix = $name->substr(strlen($prefix));
if (substr($nameWithoutPrefix, -1) == "/")
{
@mkdir($path."/".$nameWithoutPrefix, 0755, true);
}
else
{
@file_put_contents($path."/".$nameWithoutPrefix, $zip->getFromIndex($i));
$openResult = $zip->open($tmpfile);
if ($openResult !== true) {
throw new \Exception("Error opening .zip file, ZipArchive open() returned: " . $openResult);
}

if ($zip->numFiles == 0) {
throw new \Exception("Zip file contains no files");
}
Log::info("file in .zip file " . $zip->numFiles);

$allowedSubfolders = ['latest', 'feature-specific'];
$found = false; // Track if any matching file is found

for ($i = 0; $i < $zip->numFiles; $i++) {
$name = $zip->getNameIndex($i);
if (preg_match('#rpi-eeprom-.+?/firmware-2711/(' . implode('|', $allowedSubfolders) . ')/(.*)#', $name, $matches)) {
$found = true; // Mark as found when a match is detected
$subfolder = $matches[1];
$subfolderPath = $matches[2];

$destPath = $path . "/" . $subfolder . "/" . $subfolderPath;

if (substr($name, -1) === "/") {
if (!is_dir($destPath)) {
mkdir($destPath, 0755, true);
Log::info("Created directory: " . $destPath);
}
} else {
$directoryPath = dirname($destPath);
if (!is_dir($directoryPath)) {
mkdir($directoryPath, 0755, true);
}
if (!is_dir($destPath)) {
file_put_contents($destPath, $zip->getFromIndex($i));
Log::info("File extracted: " . $destPath);
}
}
}
}

$zip->close();
if (!$found) {
throw new \Exception("Downloaded file has not the expected content.");
}

$zip->close();
session()->flash('message', 'Firmware updated');
} catch (\Exception | GuzzleException $e) {
Log::error("Error: " . $e->getMessage());
session()->flash('message', 'Error: ' . $e->getMessage());
} finally {
@unlink($tmpfile);
}
catch (\Exception $e)
{
session()->flash('message', 'Error: '.$e->getMessage() );
}
@unlink($tmpfile);
}
}
2 changes: 1 addition & 1 deletion app/Models/Firmware.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static function allOfChannel($channel)
public static function all()
{
$entries = [];
$channels = ["stable", "beta"];
$channels = ["latest", "feature-specific"];

foreach ($channels as $channel)
{
Expand Down