]> git.lizzy.rs Git - dirlistozxa.git/blob - dirlistozxa.php
Fix handling spaces and other encoded characters in folder names
[dirlistozxa.git] / dirlistozxa.php
1 <?php
2 /* dirlistozxa - Basic directory lister script written in PHP
3  * Copyright (C) 2023 ROllerozxa
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published
7  * by the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  * This software is best enjoyed with soused herring!
19  */
20
21 // Configuration:
22
23 // List of filenames (and folder names) that should be ignored.
24 $ignore_file_list = [
25         '.htaccess', '.htpasswd',       // Apache junk files
26         'Thumbs.db', '.DS_Store',       // OS junk files
27         'index.php', 'index.html',      // Potential other index files
28         '.git', 'vendor',                       // Dev
29         'dirlistozxa.php', '.dirlistozxa', '.thumbs', 'gen-thumbs' // dirlistozxa
30 ];
31
32 // ================
33
34 // Lazy sanitisation done if the web server somehow sends idiotic input,
35 // nginx with default configuration (merge_slashes) doesn't actually need this.
36 $_SERVER['REQUEST_URI'] = str_replace('../', '', $_SERVER['REQUEST_URI']);
37
38 // Allow spaces and other heretical stuff in folder names.
39 $_SERVER['REQUEST_URI'] = urldecode($_SERVER['REQUEST_URI']);
40
41 $folder = str_replace('?'.$_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI']);
42 $path = $_SERVER['DOCUMENT_ROOT'].$folder;
43
44 if (!is_dir($path)) die('invalid folder?');
45
46 define('THUMB_FOLDER', 1);
47 define('THUMB_FILE', 2);
48 define('THUMB_IMAGE', 3);
49
50 function display_size($bytes, $precision = 2) {
51         $units = ['B', 'K', 'M', 'G', 'T'];
52         $bytes = max($bytes, 0);
53         $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
54         $pow = min($pow, count($units) - 1);
55         $bytes /= (1 << (10 * $pow));
56         return round($bytes, $precision) . $units[$pow];
57 }
58
59 function row($name, $date, $size, $thumb) {
60         $img = match ($thumb) {
61                 THUMB_FOLDER => '/.dirlistozxa/folder.png',
62                 THUMB_FILE => '/.dirlistozxa/file.png',
63                 THUMB_IMAGE => "/.thumbs/".$name,
64         };
65
66         return sprintf(
67                 '<tr>
68                         <td class="tum"><a href="%s"><img src="%s" loading="lazy"></td>
69                         <td><a href="%s">%s</a></td>
70                         <td>%s</td><td class="r">%s</td>
71                 </tr>',
72         $name, $img, $name, $name, $date, $size);
73 }
74
75 function build_blocks($items) {
76         global $ignore_file_list, $path, $folder;
77
78         $rtn = '';
79
80         $objects = [ 'directories' => [], 'files' => [] ];
81
82         foreach ($items as $item) {
83                 if ($item == '..' || $item == '.' || in_array($item, $ignore_file_list)) continue;
84
85                 if (is_dir($path.$item))
86                         $objects['directories'][$item] = $item;
87                 else
88                         $objects['files'][$item] = $item;
89         }
90
91         // SORT
92         natsort($objects['directories']);
93         natsort($objects['files']);
94
95         if ($folder != '/')
96                 $rtn .= row('../', '', '', THUMB_FOLDER);
97
98         foreach ($objects['directories'] as $dir) {
99                 $name = basename($dir).'/';
100                 $date = date('Y-m-d H:i', filemtime($path.$dir));
101
102                 $rtn .= row($name, $date, '-', THUMB_FOLDER);
103         }
104
105         foreach ($objects['files'] as $file) {
106                 $name = basename($file);
107                 $date = date('Y-m-d H:i', filemtime($path.$file));
108                 $size = display_size(filesize($path.$file));
109
110                 $doThumb = file_exists($_SERVER['DOCUMENT_ROOT']."/.thumbs/".$file) ? THUMB_IMAGE : THUMB_FILE;
111
112                 $rtn .= row($name, $date, $size, $doThumb);
113         }
114
115         return $rtn;
116 }
117 ?>
118 <!DOCTYPE html>
119 <html>
120 <head>
121         <title>Index of <?=$folder ?></title>
122         <meta charset="utf-8">
123         <style>
124 body {
125         background-color: #111;
126         color: #eee;
127         font-family: monospace;
128         font-size: 12pt;
129         max-width: 1440px;
130         margin: auto;
131         padding: 0 5px;
132 }
133 td { padding: 5px; }
134 th { padding: 0 5px; }
135 .r { text-align: right }
136
137 a {
138         color: lime;
139         text-decoration: none;
140 }
141
142 .tum {
143         height: 48px;
144         width: 48px;
145 }
146 .tum img {
147         max-width: 100%;
148         max-height: 100%;
149         margin: auto;
150         display: block;
151 }
152         </style>
153 </head>
154 <body>
155         <h1>Index of <?=$folder ?></h1>
156
157         <table>
158                 <tr><th></th><th>Name</th><th>Last modified</th><th>Size</th></tr>
159                 <tr><th colspan="4"><hr></th></tr>
160                 <?=build_blocks(scandir($path)) ?>
161                 <tr><th colspan="4"><hr></th></tr>
162         </table>
163
164         <address><?=$_SERVER['SERVER_SOFTWARE'] ?? 'Cool' ?> server at <?=$_SERVER['HTTP_HOST'] ?>, index powered by <a href="https://github.com/rollerozxa/dirlistozxa/">dirlistozxa</a></address>
165 </body>
166 </html>