aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dirlist.cgi.in
diff options
context:
space:
mode:
authorTatsuya Kinoshita <tats@vega.ocn.ne.jp>2011-05-04 07:05:14 +0000
committerTatsuya Kinoshita <tats@vega.ocn.ne.jp>2011-05-04 07:05:14 +0000
commit72f72d64a422d6628c4796f5c0bf2e508f134214 (patch)
tree0c9ea90cc53310832c977265521fb44db24a515e /scripts/dirlist.cgi.in
parentAdding upstream version 0.3 (diff)
downloadw3m-1ef51c20e0ea7b35c8c9cad6f9d9bc1e16664cc5.tar.gz
w3m-1ef51c20e0ea7b35c8c9cad6f9d9bc1e16664cc5.zip
Adding upstream version 0.5.1upstream/0.5.1
Diffstat (limited to 'scripts/dirlist.cgi.in')
-rwxr-xr-xscripts/dirlist.cgi.in536
1 files changed, 536 insertions, 0 deletions
diff --git a/scripts/dirlist.cgi.in b/scripts/dirlist.cgi.in
new file mode 100755
index 0000000..5cba1a8
--- /dev/null
+++ b/scripts/dirlist.cgi.in
@@ -0,0 +1,536 @@
+#!@PERL@
+#
+# Directory list CGI by Hironori Sakamoto (hsaka@mth.biglobe.ne.jp)
+#
+
+if ( $^O =~ /^(ms)?(dos|win(32|nt)?)/i ) {
+ $WIN32 = 1;
+ $CYGPATH = 1;
+}
+elsif ( $^O =~ /cygwin|os2/i ) {
+ $WIN32 = 1;
+ $CYGPATH = 0;
+}
+else {
+ $WIN32 = 0;
+ $CYGPATH = 0;
+}
+$RC_DIR = '@RC_DIR@';
+$RC_DIR =~ s@^~/@$ENV{'HOME'}/@;
+if ($CYGPATH) {
+ $RC_DIR = &cygwin_pathconv("$RC_DIR");
+}
+$CONFIG = "$RC_DIR/dirlist";
+$CGI = $ENV{'SCRIPT_NAME'} || $0;
+$CGI = "file://" . &file_encode("$CGI");
+
+$AFMT = '<a href="%s"><nobr>%s</nobr></a>';
+$NOW = time();
+
+@OPT = &init_option($CONFIG);
+
+$query = $ENV{'QUERY_STRING'};
+$dir = '';
+$cmd = '';
+$cookie = '';
+$local_cookie = '';
+foreach(split(/\&/, $query)) {
+ if (s/^dir=//) {
+ $dir = &form_decode($_);
+ }
+}
+$body = undef;
+if ($ENV{'REQUEST_METHOD'} eq 'POST') {
+ sysread(STDIN, $body, $ENV{'CONTENT_LENGTH'});
+ foreach(split(/\&/, $body)) {
+ if (s/^dir=//) {
+ $dir = &form_decode($_);
+ } elsif (s/^opt(\d+)=//) {
+ $OPT[$1] = $_;
+ } elsif (s/^cmd=//) {
+ $cmd = $_;
+ } elsif (s/^cookie=//) {
+ $cookie = &form_decode($_);
+ }
+ }
+}
+$cookie_file = $ENV{'LOCAL_COOKIE_FILE'};
+if (-f $cookie_file) {
+ open(F, "< $cookie_file");
+ $local_cookie = <F>;
+ close(F);
+}
+if ($local_cookie eq '' || (defined($body) && $cookie ne $local_cookie)) {
+ print <<EOF;
+Content-Type: text/plain
+
+Local cookie doesn't match: It may be an illegal execution
+EOF
+ exit(1);
+}
+$local_cookie = &html_quote($local_cookie);
+if ($dir !~ m@/$@) {
+ $dir .= '/';
+}
+if ($dir =~ m@^/@ && $CYGPATH) {
+ $dir = &cygwin_pathconv("$dir");
+}
+$ROOT = '';
+if ($WIN32) {
+ if (($dir =~ s@^//[^/]+@@) || ($dir =~ s@^[a-z]:@@i)) {
+ $ROOT = $&;
+ }
+ if ($CYGPATH) {
+ $ROOT = &cygwin_pathconv("$ROOT");
+ }
+}
+$dir = &cleanup($dir);
+
+$TYPE = $OPT[$OPT_TYPE];
+$FORMAT = $OPT[$OPT_FORMAT];
+$SORT = $OPT[$OPT_SORT];
+if ($cmd) {
+ &update_option($CONFIG);
+}
+
+$qdir = "$ROOT" . &html_quote("$dir");
+$edir = "$ROOT" . &file_encode("$dir");
+if (! opendir(DIR, "$ROOT$dir")) {
+ print <<EOF;
+Content-Type: text/html
+
+<html>
+<head>
+<title>Directory list of $qdir</title>
+</head>
+<body>
+<b>$qdir</b>: $! !
+</body>
+</html>
+EOF
+ exit 1;
+}
+
+print <<EOF;
+Content-Type: text/html
+
+<html>
+<head>
+<title>Directory list of $qdir</title>
+</head>
+<body>
+<h1>Directory list of $qdir</h1>
+EOF
+&print_form($qdir, @OPT);
+print <<EOF;
+<hr>
+EOF
+$dir =~ s@/$@@;
+@sdirs = split('/', $dir);
+$_ = $sdirs[0];
+if ($_ eq '') {
+ $_ = '/';
+}
+if ($TYPE eq $TYPE_TREE) {
+ print <<EOF;
+<table hborder width="640">
+<tr valign=top><td width="160">
+<pre>
+EOF
+ $q = "$ROOT". &html_quote("$_");
+ $e = "$ROOT" . &file_encode("$_");
+ if ($dir =~ m@^$@) {
+ $n = "\" name=\"current";
+ } else {
+ $n = '';
+ }
+ printf("$AFMT\n", "$e$n", "<b>$q</b>");
+ $N = 0;
+ $SKIPLINE = "";
+
+ &left_dir('', @sdirs);
+
+ print <<EOF;
+</pre>
+</td><td width="400">
+<pre>$SKIPLINE
+EOF
+} else {
+ print <<EOF;
+<pre>
+EOF
+}
+
+&right_dir($dir);
+
+if ($TYPE eq $TYPE_TREE) {
+ print <<EOF;
+</pre>
+</td></tr>
+</table>
+</body>
+</html>
+EOF
+} else {
+ print <<EOF;
+</pre>
+</body>
+</html>
+EOF
+}
+
+sub left_dir {
+ local($pre, $dir, @sdirs) = @_;
+ local($ok) = (@sdirs == 0);
+ local(@cdirs) = ();
+ local($_, $dir0, $d, $qdir, $q, $edir, $e);
+
+ $dir0 = "$dir/";
+ $dir = "$dir0";
+ opendir(DIR, "$ROOT$dir") || return;
+
+ foreach(sort readdir(DIR)) {
+ -d "$ROOT$dir$_" || next;
+ /^\.$/ && next;
+ /^\.\.$/ && next;
+ push(@cdirs, $_);
+ }
+ closedir(DIR);
+
+ $qdir = "$ROOT" . &html_quote($dir);
+ $edir = "$ROOT" . &file_encode($dir);
+ while(@cdirs) {
+ $_ = shift @cdirs;
+ $q = &html_quote($_);
+ $e = &file_encode($_);
+ $N++;
+ if (!$ok && $_ eq $sdirs[0]) {
+ $d = $dir0 . shift @sdirs;
+ if (!@sdirs) {
+ $n = "\" name=\"current";
+ $SKIPLINE = "\n" x $N;
+ } else {
+ $n = '';
+ }
+ printf("${pre}o-$AFMT\n", "$edir$e$n", "<b>$q</b>");
+ &left_dir(@cdirs ? "$pre| " : "$pre ", $d, @sdirs);
+ $ok = 1;
+ } else {
+ printf("${pre}+-$AFMT\n", "$edir$e", $q);
+ }
+ }
+}
+
+sub right_dir {
+ local($dir) = @_;
+ local(@list);
+ local($_, $qdir, $q, $edir, $e, $f, $max, @d, $type, $u, $g);
+ local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks);
+ local(%sizes, %ctimes, %prints);
+
+ $dir = "$dir/";
+ opendir(DIR, "$ROOT$dir") || return;
+
+ $qdir = "$ROOT" . &html_quote($dir);
+ $edir = "$ROOT" . &file_encode($dir);
+ if ($TYPE eq $TYPE_TREE) {
+ print "<b>$qdir</b>\n";
+ }
+ @list = ();
+ $max = 0;
+ foreach(readdir(DIR)) {
+ /^\.$/ && next;
+# if ($TYPE eq $TYPE_TREE) {
+# /^\.\.$/ && next;
+# }
+ $f = "$ROOT$dir$_";
+ (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = lstat($f)) || next;
+ push(@list, $_);
+ $sizes{$_} = $size;
+ $ctimes{$_} = $ctime;
+
+ if ($FORMAT eq $FORMAT_COLUMN) {
+ if (length($_) > $max) {
+ $max = length($_);
+ }
+ next;
+ }
+ $type = &utype($mode);
+ if ($FORMAT eq $FORMAT_SHORT) {
+ $prints{$_} = sprintf("%-6s ", "[$type]");
+ next;
+ }
+ if ($type =~ /^[CB]/) {
+ $size = sprintf("%3u, %3u", ($rdev >> 8) & 0xff, $rdev & 0xffff00ff);
+ }
+ if ($FORMAT eq $FORMAT_LONG) {
+ $u = $USER{$uid} || ($USER{$uid} = getpwuid($uid) || $uid);
+ $g = $GROUP{$gid} || ($GROUP{$gid} = getgrgid($gid) || $gid);
+ $prints{$_} = sprintf( "%s %-8s %-8s %8s %s ",
+ &umode($mode), $u, $g, $size, &utime($ctime));
+# } elsif ($FORMAT eq $FORMAT_STANDARD) {
+ } else {
+ $prints{$_} = sprintf("%-6s %8s %s ", "[$type]", $size, &utime($ctime));
+ }
+ }
+ closedir(DIR);
+ if ($SORT eq $SORT_SIZE) {
+ @list = sort { $sizes{$b} <=> $sizes{$a} || $a cmp $b } @list;
+ } elsif ($SORT eq $SORT_TIME) {
+ @list = sort { $ctimes{$b} <=> $ctimes{$a} || $a cmp $b } @list;
+ } else {
+ @list = sort @list;
+ }
+ if ($FORMAT eq $FORMAT_COLUMN) {
+ local($COLS, $l, $nr, $n);
+ if ($TYPE eq $TYPE_TREE) {
+ $COLS = 60;
+ } else {
+ $COLS = 80;
+ }
+ $l = int($COLS / ($max + 2)) || 1;
+ $nr = int($#list / $l + 1);
+ $n = 0;
+ print "<table>\n<tr valign=top>";
+ foreach(@list) {
+ $f = "$ROOT$dir$_";
+ $q = &html_quote($_);
+ $e = &file_encode($_);
+ if ($n % $nr == 0) {
+ print "<td>";
+ }
+ if (-d $f) {
+ printf($AFMT, "$edir$e", "$q/");
+ } else {
+ printf($AFMT, "$edir$e", $q);
+ }
+ $n++;
+ if ($n % $nr == 0) {
+ print "</td>\n";
+ } else {
+ print "<br>\n";
+ }
+ }
+ print "</tr></table>\n";
+ return;
+ }
+ foreach(@list) {
+ $f = "$ROOT$dir$_";
+ $q = &html_quote($_);
+ $e = &file_encode($_);
+ print $prints{$_};
+ if (-d $f) {
+ printf($AFMT, "$edir$e", "$q/");
+ } else {
+ printf($AFMT, "$edir$e", $q);
+ }
+ if (-l $f) {
+ print " -> ", &html_quote(readlink($f));
+ }
+ print "\n";
+ }
+}
+
+sub init_option {
+ local($config) = @_;
+ $OPT_TYPE = 0;
+ $OPT_FORMAT = 1;
+ $OPT_SORT = 2;
+ $TYPE_TREE = 't';
+ $TYPE_STANDARD = 'd';
+ $FORMAT_SHORT = 's';
+ $FORMAT_STANDARD = 'd';
+ $FORMAT_LONG = 'l';
+ $FORMAT_COLUMN = 'c';
+ $SORT_NAME = 'n';
+ $SORT_SIZE = 's';
+ $SORT_TIME = 't';
+ local(@opt) = ($TYPE_TREE, $FORMAT_STANDARD, $SORT_NAME);
+ local($_);
+
+ open(CONFIG, "< $config") || return @opt;
+ while(<CONFIG>) {
+ chop;
+ s/^\s+//;
+ tr/A-Z/a-z/;
+ if (/^type\s+(\S)/i) {
+ $opt[$OPT_TYPE] = $1;
+ } elsif (/^format\s+(\S)/i) {
+ $opt[$OPT_FORMAT] = $1
+ } elsif (/^sort\s+(\S)/i) {
+ $opt[$OPT_SORT] = $1;
+ }
+ }
+ close(CONFIG);
+ return @opt;
+}
+
+sub update_option {
+ local($config) = @_;
+
+ open(CONFIG, "> $config") || return;
+ print CONFIG <<EOF;
+type $TYPE
+format $FORMAT
+sort $SORT
+EOF
+ close(CONFIG);
+}
+
+sub print_form {
+ local($d, @OPT) = @_;
+ local(@disc) = ('Type', 'Format', 'Sort');
+ local(@val) = (
+ "('t', 'd')",
+ "('s', 'd', 'c')",
+ "('n', 's', 't')",
+ );
+ local(@opt) = (
+ "('Tree', 'Standard')",
+ "('Short', 'Standard', 'Column')",
+ "('By Name', 'By Size', 'By Time')"
+ );
+ local($_, @vs, @os, $v, $o);
+
+ print <<EOF;
+<form method=post action=\"$CGI#current\">
+<center>
+<table cellpadding=0>
+<tr valign=top>
+EOF
+ foreach(0 .. 2) {
+ print "<td align>&nbsp;$disc[$_]</td>\n";
+ }
+ print "</tr><tr>\n";
+ foreach(0 .. 2) {
+ print "<td><select name=opt$_>\n";
+ eval "\@vs = $val[$_]";
+ eval "\@os = $opt[$_]";
+ foreach $v (@vs) {
+ $o = shift(@os);
+ if ($v eq $OPT[$_]) {
+ print "<option value=$v selected>$o\n";
+ } else {
+ print "<option value=$v>$o\n";
+ }
+ }
+ print "</select></td>\n";
+ }
+ print <<EOF;
+<td><input type=submit name=cmd value="Update"></td>
+</tr>
+</table>
+</center>
+<input type=hidden name=dir value="$d">
+<input type=hidden name=cookie value="$local_cookie">
+</form>
+EOF
+}
+
+sub html_quote {
+ local($_) = @_;
+ local(%QUOTE) = (
+ '<', '&lt;',
+ '>', '&gt;',
+ '&', '&amp;',
+ '"', '&quot;',
+ );
+ s/[<>&"]/$QUOTE{$&}/g;
+ return $_;
+}
+sub file_encode {
+ local($_) = @_;
+ s/[\000-\040\+:#?&%<>"\177-\377]/sprintf('%%%02X', unpack('C', $&))/eg;
+ return $_;
+}
+
+sub form_decode {
+ local($_) = @_;
+ s/\+/ /g;
+ s/%([\da-f][\da-f])/pack('C', hex($1))/egi;
+ return $_;
+}
+
+sub cleanup {
+ local($_) = @_;
+
+ s@//+@/@g;
+ s@/\./@/@g;
+ while(m@/\.\./@) {
+ s@^/(\.\./)+@/@;
+ s@/[^/]+/\.\./@/@;
+ }
+ return $_;
+}
+
+sub utype {
+ local($_) = @_;
+ local(%T) = (
+ 0010000, 'PIPE',
+ 0020000, 'CHR',
+ 0040000, 'DIR',
+ 0060000, 'BLK',
+ 0100000, 'FILE',
+ 0120000, 'LINK',
+ 0140000, 'SOCK',
+ );
+ return $T{($_ & 0170000)} || 'FILE';
+}
+
+sub umode {
+ local($_) = @_;
+ local(%T) = (
+ 0010000, 'p',
+ 0020000, 'c',
+ 0040000, 'd',
+ 0060000, 'b',
+ 0100000, '-',
+ 0120000, 'l',
+ 0140000, 's',
+ );
+
+ return ($T{($_ & 0170000)} || '-')
+ . (($_ & 00400) ? 'r' : '-')
+ . (($_ & 00200) ? 'w' : '-')
+ . (($_ & 04000) ? 's' :
+ (($_ & 00100) ? 'x' : '-'))
+ . (($_ & 00040) ? 'r' : '-')
+ . (($_ & 00020) ? 'w' : '-')
+ . (($_ & 02000) ? 's' :
+ (($_ & 00010) ? 'x' : '-'))
+ . (($_ & 00004) ? 'r' : '-')
+ . (($_ & 00002) ? 'w' : '-')
+ . (($_ & 01000) ? 't' :
+ (($_ & 00001) ? 'x' : '-'));
+}
+
+sub utime {
+ local($_) = @_;
+ local(@MON) = (
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
+ );
+ local($sec,$min,$hour,$mday,$mon,
+ $year,$wday,$yday,$isdst) = localtime($_);
+
+ if ($_ > $NOW - 182*24*60*60 && $_ < $NOW + 183*24*60*60) {
+ return sprintf("%3s %2d %.2d:%.2d", $MON[$mon], $mday, $hour, $min);
+ } else {
+ return sprintf("%3s %2d %5d", $MON[$mon], $mday, 1900+$year);
+ }
+}
+
+sub cygwin_pathconv {
+ local($_) = @_;
+ local(*CYGPATH);
+
+ open(CYGPATH, '-|') || exec('cygpath', '-w', $_);
+ $_ = <CYGPATH>;
+ close(CYGPATH);
+ s/\r?\n$//;
+ s!\\!/!g;
+ s!/$!!;
+ return $_;
+}