| 0 | 1 <?php | 
| 2 | 2   //real men use UTC for internets | 
|  | 3   date_default_timezone_set('UTC'); | 
|  | 4   $wwwroot = $_ENV["DOCUMENT_ROOT"]; | 
|  | 5   $link_prefix = "/"; | 
|  | 6   $link_base = rtrim(preg_replace("#/+#", "/", urldecode($_ENV["REQUEST_URI"])),'/'); | 
|  | 7   $link_path = substr($link_base,strlen(utf8_decode($link_prefix))); | 
|  | 8   $path = realpath("$wwwroot/".$link_path); | 
|  | 9   if (!$path) { die("fail"); } | 
|  | 10   $dir_handle = @opendir($path); | 
|  | 11   $to_dir = explode('/', trim($link_path,'/')); | 
|  | 12   array_unshift($to_dir, trim($link_prefix,'/')); | 
|  | 13   $files = array(); | 
|  | 14   $dirs = array(); | 
|  | 15   while ($file = readdir($dir_handle)) { | 
|  | 16     if ($file == '.' or $file == '..') { continue; } | 
|  | 17     elseif (is_dir("$path/$file")) { $dirs[] = $file; } | 
|  | 18     else { $files[] = $file; } | 
|  | 19   } | 
|  | 20   sort($files); | 
|  | 21   sort($dirs); | 
|  | 22   function h($string) { return htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); } | 
|  | 23   function a($string) { return preg_replace("#(%2F)+#", "/", rawurlencode($string)); } | 
|  | 24   function link_to($target, $title) { | 
|  | 25     return("<a href=\"".a($target)."\">".h($title)."</a>"); | 
|  | 26   } | 
| 3 | 27   function path_tree_header() { | 
| 2 | 28     global $link_prefix, $link_base, $to_dir; | 
|  | 29     $path_tree = link_to('/', '[root]') . "/"; | 
|  | 30     foreach ($to_dir as $level => $dir) { | 
|  | 31       if($dir) { | 
|  | 32         $link = "/"; | 
|  | 33         for ($i = 0; $i <= $level; $i++) { $link .= "$to_dir[$i]/"; } | 
|  | 34         $path_tree .= link_to($link, $dir)."/"; | 
|  | 35       } | 
|  | 36     } | 
| 3 | 37     return "Index of $path_tree"; | 
|  | 38   } | 
|  | 39   function title() { | 
|  | 40     global $link_base; | 
|  | 41     return "Index of ".h(rtrim($link_base,"/")."/"); | 
| 2 | 42   } | 
| 3 | 43 | 
| 2 | 44   function nice_size($size) { | 
| 3 | 45     $thousand_units = array('ko', 'Mo', 'Go', 'To', 'Po'); | 
|  | 46 | 
|  | 47     $return_format = "%d %s"; | 
|  | 48 | 
|  | 49     if ($size <= 1) { | 
|  | 50       $return_unit = "octet"; | 
|  | 51     } elseif ($size < 10000) { | 
|  | 52       $return_unit = "octets"; | 
|  | 53     } else { | 
|  | 54       $size /= 1000; | 
|  | 55       for ($i = 0; $size >= 1000 && $i < count($thousand_units); $i++) { $size /= 1000; } | 
|  | 56       $return_format = "%.2f %s"; | 
|  | 57       $return_unit = $thousand_units[$i]; | 
|  | 58     } | 
|  | 59     return sprintf($return_format, $size, $return_unit); | 
| 2 | 60   } | 
| 3 | 61 | 
| 2 | 62   function file_rows($files, $is_dir) { | 
|  | 63     global $path, $link_base, $link_prefix; | 
| 3 | 64 | 
| 2 | 65     $file_rows = ""; | 
|  | 66     if ($is_dir) { | 
|  | 67       $file_suffix = "/"; | 
|  | 68       if($link_base != $link_prefix) { | 
| 3 | 69         $file_rows .= "<tr><td colspan=3>".link_to(dirname($link_base)."/","..")."</td></tr>"; | 
| 2 | 70       } | 
|  | 71     } else { $file_suffix = ""; } | 
| 3 | 72 | 
| 2 | 73     foreach($files as $file) { | 
|  | 74       $file_stat = stat("$path/".$file); | 
| 3 | 75 | 
|  | 76       $file_rows .= "<tr>"; | 
|  | 77       $file_rows .= "<td>".link_to("$link_base/".$file.$file_suffix, $file.$file_suffix)."</td>"; | 
|  | 78 | 
|  | 79       $file_rows .= "<td>"; | 
| 2 | 80       if ($is_dir) { $file_rows .= "[dir]"; } | 
|  | 81       else { $file_rows .= nice_size($file_stat['size']); } | 
| 3 | 82       $file_rows .= "</td>"; | 
|  | 83 | 
|  | 84       $file_rows .= "<td>".h(strftime("%Y-%m-%d %H:%M %Z", $file_stat['mtime']))."</td>"; | 
|  | 85 | 
| 2 | 86       $file_rows .= "</tr>"; | 
|  | 87     } | 
|  | 88     return $file_rows; | 
|  | 89   } | 
| 0 | 90 ?> | 
| 3 | 91 <?php header('Content-Type: text/html; charset=utf-8'); ?> | 
|  | 92 <!doctype html> | 
|  | 93 <head> | 
|  | 94   <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | 
|  | 95   <title><?php echo title(); ?></title> | 
|  | 96   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> | 
|  | 97   <style type="text/css"> | 
|  | 98     * { box-sizing: border-box; } | 
|  | 99     body { | 
|  | 100       font-family: Segoe UI, sans-serif; | 
|  | 101       font-size: 14px; | 
|  | 102     } | 
|  | 103     h1 { margin: 5px; } | 
|  | 104     table { | 
|  | 105       width: 100%; | 
|  | 106     } | 
|  | 107     th:first-child, td:first-child { | 
|  | 108       width: 100%; | 
|  | 109       white-space: pre-wrap; | 
|  | 110       word-wrap: break-word; | 
|  | 111       word-break: break-all; | 
|  | 112     } | 
|  | 113     tr { | 
|  | 114       position: relative; | 
|  | 115     } | 
|  | 116     th, td { | 
|  | 117       white-space: nowrap; | 
|  | 118       padding: 2px 5px; | 
|  | 119     } | 
|  | 120 | 
|  | 121     @media (min-width: 768px) { | 
|  | 122       th { background: #ccc; } | 
|  | 123       tr:nth-child(even) { background: #eee; } | 
|  | 124       tr:hover { background: #ddd; } | 
|  | 125     } | 
|  | 126 | 
|  | 127     @media (max-width: 767px) { | 
|  | 128       table { | 
|  | 129         border-spacing: 0 10px; | 
|  | 130       } | 
|  | 131       th { display: none; } | 
|  | 132       tr { | 
|  | 133         background: #eee; | 
|  | 134       } | 
|  | 135       td { | 
|  | 136         display: inline-block; | 
|  | 137       } | 
|  | 138       td:first-child { | 
|  | 139         background: #ddd; | 
|  | 140         padding: 5px; | 
|  | 141       } | 
|  | 142       table a { | 
|  | 143         font-size: 18px; | 
|  | 144         display: block; | 
|  | 145       } | 
|  | 146     } | 
|  | 147   </style> | 
|  | 148 </head> | 
|  | 149 <body> | 
|  | 150   <h1><?php echo path_tree_header(); ?></h1> | 
|  | 151 | 
|  | 152   <table> | 
|  | 153     <thead><tr> | 
|  | 154       <th>File</th> | 
|  | 155       <th>Size</th> | 
|  | 156       <th>Date</th> | 
|  | 157     </tr></thead> | 
|  | 158     <tbody> | 
|  | 159       <?php echo file_rows($dirs, true); ?> | 
|  | 160       <?php echo file_rows($files, false); ?> | 
|  | 161     </tbody> | 
|  | 162   </table> | 
|  | 163 </body> |