3 # Directory list CGI by Hironori Sakamoto (hsaka@mth.biglobe.ne.jp)
6 if ( $^O =~ /^(ms)?(dos|win(32|nt)?)/i ) {
10 elsif ( $^O =~ /cygwin|os2/i ) {
19 $RC_DIR =~ s@^~/@$ENV{'HOME'}/@;
21 $RC_DIR = &cygwin_pathconv("$RC_DIR");
23 $CONFIG = "$RC_DIR/dirlist";
24 $CGI = $ENV{'SCRIPT_NAME'} || $0;
25 $CGI = "file://" . &file_encode("$CGI");
27 $AFMT = '<a href="%s"><nobr>%s</nobr></a>';
30 @OPT = &init_option($CONFIG);
32 $query = $ENV{'QUERY_STRING'};
37 foreach(split(/\&/, $query)) {
39 $dir = &form_decode($_);
43 if ($ENV{'REQUEST_METHOD'} eq 'POST') {
44 sysread(STDIN, $body, $ENV{'CONTENT_LENGTH'});
45 foreach(split(/\&/, $body)) {
47 $dir = &form_decode($_);
48 } elsif (s/^opt(\d+)=//) {
52 } elsif (s/^cookie=//) {
53 $cookie = &form_decode($_);
57 $cookie_file = $ENV{'LOCAL_COOKIE_FILE'};
58 if (-f $cookie_file) {
59 open(F, "< $cookie_file");
63 if ($local_cookie eq '' || (defined($body) && $cookie ne $local_cookie)) {
65 Content-Type: text/plain
67 Local cookie doesn't match: It may be an illegal execution
71 $local_cookie = &html_quote($local_cookie);
75 if ($dir =~ m@^/@ && $CYGPATH) {
76 $dir = &cygwin_pathconv("$dir");
80 if (($dir =~ s@^//[^/]+@@) || ($dir =~ s@^[a-z]:@@i)) {
84 $ROOT = &cygwin_pathconv("$ROOT");
87 $dir = &cleanup($dir);
89 $TYPE = $OPT[$OPT_TYPE];
90 $FORMAT = $OPT[$OPT_FORMAT];
91 $SORT = $OPT[$OPT_SORT];
93 &update_option($CONFIG);
96 $qdir = "$ROOT" . &html_quote("$dir");
97 $edir = "$ROOT" . &file_encode("$dir");
98 if (! opendir(DIR, "$ROOT$dir")) {
100 Content-Type: text/html
104 <title>Directory list of $qdir</title>
115 Content-Type: text/html
119 <title>Directory list of $qdir</title>
122 <h1>Directory list of $qdir</h1>
124 &print_form($qdir, @OPT);
129 @sdirs = split('/', $dir);
134 if ($TYPE eq $TYPE_TREE) {
136 <table hborder width="640">
137 <tr valign=top><td width="160">
140 $q = "$ROOT". &html_quote("$_");
141 $e = "$ROOT" . &file_encode("$_");
143 $n = "\" name=\"current";
147 printf("$AFMT\n", "$e$n", "<b>$q</b>");
151 &left_dir('', @sdirs);
155 </td><td width="400">
166 if ($TYPE eq $TYPE_TREE) {
183 local($pre, $dir, @sdirs) = @_;
184 local($ok) = (@sdirs == 0);
186 local($_, $dir0, $d, $qdir, $q, $edir, $e);
190 opendir(DIR, "$ROOT$dir") || return;
192 foreach(sort readdir(DIR)) {
193 -d "$ROOT$dir$_" || next;
200 $qdir = "$ROOT" . &html_quote($dir);
201 $edir = "$ROOT" . &file_encode($dir);
204 $q = &html_quote($_);
205 $e = &file_encode($_);
207 if (!$ok && $_ eq $sdirs[0]) {
208 $d = $dir0 . shift @sdirs;
210 $n = "\" name=\"current";
211 $SKIPLINE = "\n" x $N;
215 printf("${pre}o-$AFMT\n", "$edir$e$n", "<b>$q</b>");
216 &left_dir(@cdirs ? "$pre| " : "$pre ", $d, @sdirs);
219 printf("${pre}+-$AFMT\n", "$edir$e", $q);
227 local($_, $qdir, $q, $edir, $e, $f, $max, @d, $type, $u, $g);
228 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
229 $atime,$mtime,$ctime,$blksize,$blocks);
230 local(%sizes, %ctimes, %prints);
233 opendir(DIR, "$ROOT$dir") || return;
235 $qdir = "$ROOT" . &html_quote($dir);
236 $edir = "$ROOT" . &file_encode($dir);
237 if ($TYPE eq $TYPE_TREE) {
238 print "<b>$qdir</b>\n";
242 foreach(readdir(DIR)) {
244 # if ($TYPE eq $TYPE_TREE) {
248 (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
249 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($f)) || next;
252 $ctimes{$_} = $ctime;
254 if ($FORMAT eq $FORMAT_COLUMN) {
255 if (length($_) > $max) {
260 $type = &utype($mode);
261 if ($FORMAT eq $FORMAT_SHORT) {
262 $prints{$_} = sprintf("%-6s ", "[$type]");
265 if ($type =~ /^[CB]/) {
266 $size = sprintf("%3u, %3u", ($rdev >> 8) & 0xff, $rdev & 0xffff00ff);
268 if ($FORMAT eq $FORMAT_LONG) {
269 $u = $USER{$uid} || ($USER{$uid} = getpwuid($uid) || $uid);
270 $g = $GROUP{$gid} || ($GROUP{$gid} = getgrgid($gid) || $gid);
271 $prints{$_} = sprintf( "%s %-8s %-8s %8s %s ",
272 &umode($mode), $u, $g, $size, &utime($ctime));
273 # } elsif ($FORMAT eq $FORMAT_STANDARD) {
275 $prints{$_} = sprintf("%-6s %8s %s ", "[$type]", $size, &utime($ctime));
279 if ($SORT eq $SORT_SIZE) {
280 @list = sort { $sizes{$b} <=> $sizes{$a} || $a cmp $b } @list;
281 } elsif ($SORT eq $SORT_TIME) {
282 @list = sort { $ctimes{$b} <=> $ctimes{$a} || $a cmp $b } @list;
286 if ($FORMAT eq $FORMAT_COLUMN) {
287 local($COLS, $l, $nr, $n);
288 if ($TYPE eq $TYPE_TREE) {
293 $l = int($COLS / ($max + 2)) || 1;
294 $nr = int($#list / $l + 1);
296 print "<table>\n<tr valign=top>";
299 $q = &html_quote($_);
300 $e = &file_encode($_);
305 printf($AFMT, "$edir$e", "$q/");
307 printf($AFMT, "$edir$e", $q);
316 print "</tr></table>\n";
321 $q = &html_quote($_);
322 $e = &file_encode($_);
325 printf($AFMT, "$edir$e", "$q/");
327 printf($AFMT, "$edir$e", $q);
330 print " -> ", &html_quote(readlink($f));
342 $TYPE_STANDARD = 'd';
344 $FORMAT_STANDARD = 'd';
346 $FORMAT_COLUMN = 'c';
350 local(@opt) = ($TYPE_TREE, $FORMAT_STANDARD, $SORT_NAME);
353 open(CONFIG, "< $config") || return @opt;
358 if (/^type\s+(\S)/i) {
359 $opt[$OPT_TYPE] = $1;
360 } elsif (/^format\s+(\S)/i) {
361 $opt[$OPT_FORMAT] = $1
362 } elsif (/^sort\s+(\S)/i) {
363 $opt[$OPT_SORT] = $1;
373 open(CONFIG, "> $config") || return;
383 local($d, @OPT) = @_;
384 local(@disc) = ('Type', 'Format', 'Sort');
391 "('Tree', 'Standard')",
392 "('Short', 'Standard', 'Column')",
393 "('By Name', 'By Size', 'By Time')"
395 local($_, @vs, @os, $v, $o);
398 <form method=post action=\"$CGI#current\">
400 <table cellpadding=0>
404 print "<td align> $disc[$_]</td>\n";
408 print "<td><select name=opt$_>\n";
409 eval "\@vs = $val[$_]";
410 eval "\@os = $opt[$_]";
413 if ($v eq $OPT[$_]) {
414 print "<option value=$v selected>$o\n";
416 print "<option value=$v>$o\n";
419 print "</select></td>\n";
422 <td><input type=submit name=cmd value="Update"></td>
426 <input type=hidden name=dir value="$d">
427 <input type=hidden name=cookie value="$local_cookie">
440 s/[<>&"]/$QUOTE{$&}/g;
445 s/[\000-\040\+:#?&%<>"\177-\377]/sprintf('%%%02X', unpack('C', $&))/eg;
452 s/%([\da-f][\da-f])/pack('C', hex($1))/egi;
479 return $T{($_ & 0170000)} || 'FILE';
494 return ($T{($_ & 0170000)} || '-')
495 . (($_ & 00400) ? 'r' : '-')
496 . (($_ & 00200) ? 'w' : '-')
497 . (($_ & 04000) ? 's' :
498 (($_ & 00100) ? 'x' : '-'))
499 . (($_ & 00040) ? 'r' : '-')
500 . (($_ & 00020) ? 'w' : '-')
501 . (($_ & 02000) ? 's' :
502 (($_ & 00010) ? 'x' : '-'))
503 . (($_ & 00004) ? 'r' : '-')
504 . (($_ & 00002) ? 'w' : '-')
505 . (($_ & 01000) ? 't' :
506 (($_ & 00001) ? 'x' : '-'));
512 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
513 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
515 local($sec,$min,$hour,$mday,$mon,
516 $year,$wday,$yday,$isdst) = localtime($_);
518 if ($_ > $NOW - 182*24*60*60 && $_ < $NOW + 183*24*60*60) {
519 return sprintf("%3s %2d %.2d:%.2d", $MON[$mon], $mday, $hour, $min);
521 return sprintf("%3s %2d %5d", $MON[$mon], $mday, 1900+$year);
525 sub cygwin_pathconv {
529 open(CYGPATH, '-|') || exec('cygpath', '-w', $_);