From 2ddeaf1bfad016567c438dfb712ee7955ad64af1 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 15 Apr 2024 15:22:48 +0200 Subject: [PATCH] clients: Implement directory listing for sync --- www/clients.php | 89 ++++++++++++++++++++++++++++++++++++++++++++- www/files/index.php | 2 +- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/www/clients.php b/www/clients.php index 138ea3d..6cbe99b 100644 --- a/www/clients.php +++ b/www/clients.php @@ -7,6 +7,63 @@ $clients = array_keys($CREDENTIALS); $format = get_fmt(); +function get_zip_meta($path): array { + $meta = 'null'; + $fp = fopen($path, "rb"); + + $zipHdr1 = fread($fp, 30); + if (strlen($zipHdr1) !== 30 || !str_starts_with($zipHdr1, "PK\x03\x04") || + $zipHdr1[8] !== "\x00" || $zipHdr1[9] !== "\x00" || $zipHdr1[26] !== "\x07" || $zipHdr1[27] !== "\x00") + { + fclose($fp); + return array($meta, null, null); + } + + $name1 = fread($fp, 7); + $data1 = fread($fp, unpack("V", substr($zipHdr1, 18, 4))[1]); + if ($name1 !== "version" || !str_starts_with($data1, "elwig:")) { + fclose($fp); + return array($meta, null, null); + } + $version = (int)substr($data1, 6); + + $zipHdr2 = fread($fp, 30); + if (strlen($zipHdr2) !== 30 || !str_starts_with($zipHdr2, "PK\x03\x04") || + $zipHdr2[8] !== "\x00" || $zipHdr2[9] !== "\x00" || $zipHdr2[26] !== "\x09" || $zipHdr2[27] !== "\x00") + { + fclose($fp); + return array($meta, $version, null); + } + + $name2 = fread($fp, 9); + if ($name2 !== "meta.json") { + fclose($fp); + return array($meta, $version, null); + } + + $meta = fread($fp, unpack("V", substr($zipHdr2, 18, 4))[1]); + $files = "{"; + $first = true; + while (!feof($fp)) { + $zipHdr3 = fread($fp, 30); + if (strlen($zipHdr3) !== 30 || !str_starts_with($zipHdr3, "PK\x03\x04")) + continue; + $compSize = unpack("V", substr($zipHdr3, 18, 4))[1]; + $uncompSize = unpack("V", substr($zipHdr3, 22, 4))[1]; + $name = fread($fp, unpack("v", substr($zipHdr3, 26, 2))[1]); + $crc = unpack("V", substr($zipHdr3, 14, 4))[1]; + fseek($fp, $compSize, SEEK_CUR); + $hex = substr("00000000" . dechex($crc), -8); + if (!$first) $files .= ", "; + $files .= "\"$name\": {\"compressed_size\": $compSize, \"uncompressed_size\": $uncompSize, \"crc32\": \"$hex\"}"; + $first = false; + } + $files .= "}"; + + fclose($fp); + return array($meta, $version, $files); +} + $path = $_SERVER['PATH_INFO']; if ($path == '') { if ($_SERVER['REQUEST_METHOD'] !== 'GET') { @@ -79,11 +136,39 @@ foreach ($clients as $c) { header("Allow: GET"); exit("405 Method Not Allowed :(\n"); } - system("ls -Al .data/clients/$c/"); + + header('Content-Type: application/json; charset=UTF-8'); + echo "{\"status\": \"success\", \"data\": [\n"; + $first = true; + foreach (scandir(".data/clients/$c/") as $file) { + if (str_starts_with($file, ".") || str_ends_with($file, ".php")) continue; + if (!$first) echo ",\n"; + $path = ".data/clients/$c/$file"; + $size = filesize($path); + $url = "https://www.necronda.net/elwig/clients/$c/$file"; + $mod = date(DATE_ATOM, filemtime($path)); + $cre = date(DATE_ATOM, filectime($path)); + $datetime = "null"; + $zwstid = "null"; + if (str_ends_with($file, ".zip") && substr_count($file, "_") === 2) { + $parts = explode("_", substr($file, 0, -4)); + $time = str_replace("-", ":", $parts[1]); + $dt = DateTime::createFromFormat("Y-m-d H:i:s", "$parts[0] $time"); + $datetime = '"' . $dt->format(DateTimeInterface::RFC3339) . '"'; + $zwstid = "\"$parts[2]\""; + } + list($meta, $version, $files) = get_zip_meta($path); + $files ??= "null"; + $version ??= "null"; + echo " {\"name\": \"$file\", \"timestamp\": $datetime, \"zwstid\": $zwstid, \"meta\": $meta, \"files\": $files, " . + "\"version\": $version, \"url\": \"$url\", \"size\": $size, \"created\": \"$cre\", \"modified\": \"$mod\"}"; + $first = false; + } + echo "\n]}\n"; exit(); } $file = substr($path, strlen("/$c/")); - $path = ".clients/$c/$file"; + $path = ".data/clients/$c/$file"; if (str_contains($file, '/')) { header("Status: 400"); exit("400 Bad Request :(\n"); diff --git a/www/files/index.php b/www/files/index.php index 6b69a40..18d154d 100644 --- a/www/files/index.php +++ b/www/files/index.php @@ -32,7 +32,7 @@ global $getVers; $getProd = null; $getVers = null; $info = explode('/', $_SERVER['PATH_INFO']); -if (sizeof($info) > 0 && ($info[1] === 'elwig' || $info[1] === 'winziprint')) { +if (sizeof($info) > 1 && ($info[1] === 'elwig' || $info[1] === 'winziprint')) { $getProd = $info[1]; $getVers = $info[2]; if (sizeof($info) > 3) {