<?php require ".php/format.inc"; require ".php/auth.inc"; require ".php/credentials.inc"; global $CLIENT_CREDENTIALS; $clients = array_keys($CLIENT_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') { header('Status: 405'); header('Allow: GET'); if ($format === 'text') { header('Content-Type: text/plain; charset=UTF-8'); echo "405 Method Not Allowed :(\n"; } else if ($format === 'json') { header('Content-Type: application/json; charset=UTF-8'); echo "{\"status\": \"error\", \"errors\": [{\"message\": \"Method not allowed\"}]}\n"; } else { header('Content-Type: text/html; charset=UTF-8'); header('Content-Length: 0'); } exit(); } if ($format === 'text') { header('Content-Type: text/plain; charset=UTF-8'); foreach ($clients as $c) echo "$c\n"; } else if ($format === 'json') { header('Content-Type: application/json; charset=UTF-8'); echo "{\"status\": \"success\", \"data\": ["; $first = true; foreach ($clients as $c) { if (!$first) echo ","; echo "\n {\"name\": \"$c\"}"; $first = false; } echo "\n]}\n"; } else if ($format === 'html') { header('Content-Type: application/xhtml+xml; charset=UTF-8'); echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; ?> <html xmlns="http://www.w3.org/1999/xhtml" lang="de-AT"> <head> <meta charset="UTF-8"/> <title>Mandanten - Elwig - Elektronische Winzergenossenschaftsverwaltung</title> <link rel="icon" href="/favicon.ico" sizes="16x16 20x20 24x24 30x30 32x32 36x36 40x40 48x48 60x60 64x64 72x72 80x80 96x96 128x128 256x256"/> <link rel="stylesheet" href="/res/style.css"/> </head> <body> <h1>Mandanten</h1> <table> <thead><tr><th>Name</th></tr></thead> <tbody> <?php foreach ($clients as $c) { echo " <tr><td><a href='clients/$c'>$c</a></td></tr>\n"; } ?> </tbody> </table> <p><a href="clients?format=json">JSON-Format</a></p> </body> </html> <?php } exit(); } foreach ($clients as $c) { if ($path !== "/$c" && !str_starts_with($path, "/$c/")) continue; header('Content-Type: text/plain; charset=UTF-8'); authenticate_client($c); if ($path === "/$c") { header("Location: $c/"); header('Status: 303'); exit("303 See Other :)\n"); } elseif ($path === "/$c/") { if ($_SERVER['REQUEST_METHOD'] !== 'GET') { header("Status: 405"); header("Allow: GET"); exit("405 Method Not Allowed :(\n"); } 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 = ".data/clients/$c/$file"; if (str_contains($file, '/')) { header("Status: 400"); exit("400 Bad Request :(\n"); } elseif ($_SERVER['REQUEST_METHOD'] === 'GET') { $size = filesize($path); if ($size === false) { header("Status: 404"); exit("404 Not Found :(\n"); } $type = mime_content_type($path); header("Content-Type: $type"); header("Content-Disposition: attachment; filename=\"$file\""); header("Content-Length: $size"); readfile($path); } elseif ($_SERVER['REQUEST_METHOD'] === 'PUT') { $putdata = fopen('php://input', 'r'); $fp = fopen($path, 'wb'); if ($fp === false) { header("Status: 500"); exit("500 Internal Server Error :(\n"); } while ($data = fread($putdata, 4096)) fwrite($fp, $data); fclose($fp); fclose($putdata); header("Status: 201"); exit("201 Created :)\n"); } elseif ($_SERVER['REQUEST_METHOD'] === 'DELETE') { if (unlink($path) === false) { header("Status: 500"); exit("500 Internal Server Error :(\n"); } exit("200 OK :)\n"); } else { header("Status: 405"); header("Allow: GET, PUT, DELETE"); exit("405 Method Not Allowed :(\n"); } exit(); } header("Status: 404"); if ($format === 'text') { header('Content-Type: text/plain; charset=UTF-8'); echo "404 Not Found :(\n"; } else if ($format === 'json') { header('Content-Type: application/json; charset=UTF-8'); echo "{\"status\": \"error\", \"errors\": [{\"message\": \"Not found\"}]}\n"; } else { header('Content-Type: text/html; charset=UTF-8'); header('Content-Length: 0'); } exit();