| 
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>
 |