プロが教える店舗&オフィスのセキュリティ対策術

指定したディレクトリ内にあるファイルを一覧表示しリンクを自動で作ってくれるCGIを探しています
自分で探してみたところ、いくつか見つけられたのですがなかなか条件にあうCGIが無かったので・・・
↓こんなの探してます
・携帯でも見れるシンプルなもの
・ファイルの並び順(名前順や最新順)を設定できる
 ↑観覧者が自由にソートするのではなくサーバー側(?)で決めれる
・1ページに表示するファイルの数を設定できる
・指定ディレクトリ内にディレクトリがあった場合それもリンク
あとできれば画像ファイルを開いたときに「進む」で次のファイルに移動などの機能があればうれしいです

どうかよろしくおねがいします・・・

A 回答 (1件)

Perl CGIで作ってみました。


解釈を間違っていなければ以下の用件は満たしています。

1. 携帯でも見れるシンプルなもの (確認はしていませんが恐らく)
2. ファイルの並び順(名前順や最新順)を設定できる
 (自由にソートできるようにしてありますのでどうしてもいやなら
 自分で修正してみてください)
3. 1ページに表示するファイルの数を設定できる
4. 指定ディレクトリ内にディレクトリがあった場合それもリンク
 (ディレクトリ内のファイル一覧表示)

> あとできれば画像ファイルを開いたときに「進む」で次のファイルに移動などの機能があればうれしいです

これは意味が分からなかったので実装していません。
かなり要求しているものと全く異なる可能性もありますがせっかく
作ったので載せておきます。

#!/usr/bin/perl
use strict;
use CGI::Carp qw(fatalsToBrowser);
use File::Spec;
use File::Basename;

my $cgi = &getreq();
my $script = (fileparse(__FILE__))[0];
print "Content-type: text/html; charset=shift_jis\n\n";

# 表示するディレクトリ
my $dir = $cgi->{'dir'} || '.';
# Win のディレクトリ区切りをスラッシュに変換する
# (MacOS 非対応)
$dir =~ s/\\/\//g;
# ディレクトリリストの取得
my $dir_list = &dir_list($dir);
$dir .= '/' if($dir !~ /\/$/);
# 絶対パスに変換しておく
my $view_dir = File::Spec->rel2abs($dir);
# 表示するファイルの上限数 (0=無制限)
my $limit = 0;

print <<'HTML';
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=shift_jis">
<title>ディレクトリのファイル一覧</title>
</head>
<body>
<div><a href="#note">注意</a></div>
HTML
print "<table border=\"1\" bordercolor=\"black\" cellspacing=\"0\">\n";
print "<caption>表\示中のディレクトリ: $view_dir</caption>\n";
print &th($cgi, $view_dir);

my $type = 'NAME';
if($cgi->{'type'} eq 'fn') {
$type = 'NAME';
} elsif($cgi->{'type'} eq 'type') {
$type = 'TYPE';
} elsif($cgi->{'type'} eq 'ts') {
$type = 'TIME';
}

# カウントフラグ (表示上限数用)
my $i = 0;
# ループ
foreach(&sorting($dir_list->{'DIR'}, $type, $cgi->{'sort'}), &sorting($dir_list->{'FILE'}, $type, $cgi->{'sort'})) {
my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($_->{'TIME'}))[0 .. 5];
$year += 1900;
$mon++;
my $time = sprintf('%04d/%02d/%02d %02d:%02d:%02d', $year, $mon, $mday, $hour, $min, $sec);
my $fn = $_->{'NAME'};
my $vdir = File::Spec->abs2rel("$view_dir/$fn");
if($_->{'TYPE'} eq 'DIR') {
$vdir =~ s/\\/\//g;
$vdir =~ s/(\/)/'%' . unpack("H2", $1)/eg;
$fn = "<a href=\"$script?dir=$vdir&amp;type=$cgi->{'type'}&amp;sort=$cgi->{'sort'}\">$fn</a>";
} else {
$fn = "<a href=\"$vdir\">$fn</a>";
}
print "<tr>\n";
print "<td>$fn</td><td>$_->{'TYPE'}</td><td>$time</td>\n";
print "</tr>\n";
$i++;
last if($limit && $limit <= $i);
}
print "</table>\n";
print <<'HTML';
<div id="note">注意: </div>
<ul>
<li>DIR: ディレクトリ</li>
<li>BIN: バイナリファイル</li>
<li>PLAIN: プレーンテキストファイル</li>
<li>BIN/PLAIN は正確には判断できません</li>
<li>LINK: シンボリックリンクファイル</li>
</ul>
</body>
</html>
HTML
exit;

# CGI リクエスト取得
sub getreq {
# 環境変数取得
my $cgi = {};
my $query = '';
read(STDIN, $query, $ENV{'CONTENT_LENGTH'}) if($ENV{'CONTENT_LENGTH'});
$query = join('&', $query, $ENV{'QUERY_STRING'});

# デコード
my @args = split(/&/, $query);
foreach my $i (@args) {
my ($name, $val) = split(/=/, $i);
$val =~ tr/+/ /;
$val =~ s/%(\w{2})/pack('C', hex($1))/eg;
$val =~ s/(\x0d\x0a|\x0a|\x0d)+$//;
$name =~ tr/+/ /;
$name =~ s/%(\w{2})/pack('C', hex($1))/eg;
$name =~ s/(\x0d\x0a|\x0a|\x0d)+$//;
if(exists($cgi->{$name})) {
$cgi->{$name} = [(ref($cgi->{$name}) eq 'ARRAY' ? @{$cgi->{$name}} : $cgi->{$name}), $val];
} else {
$cgi->{$name} = $val;
}
}
delete($cgi->{''});

return $cgi;
}

# ディレクトリリストの取得
sub dir_list {
my $dir = shift || '.';
my $sort = shift;
my @dir = ();
my @file = ();
opendir(DIR, $dir) || return;
$dir .= '/' if($dir !~ /\/$/);
foreach(readdir(DIR)) {
my $time = (stat("$dir$_"))[9];
if(-d("$dir$_")) {
# カレントディレクトリ ('.') は表示しない
next if($_ eq '.');
push(@dir, { 'NAME' => $_, 'TYPE' => 'DIR', 'TIME' => $time});
} elsif(-f("$dir$_")) {
my $type = '';
if(-T("$dir$_")) {
$type = 'PLAIN';
} elsif(-B("$dir$_")) {
$type = 'BIN';
}
push(@file, { 'NAME' => $_, 'TYPE' => $type, 'TIME' => $time});
} elsif(-l("$dir$_")) {
push(@file, { 'NAME' => $_, 'TYPE' => 'LINK', 'TIME' => $time});
}
next;
}
closedir DIR;
return { 'DIR' => \@dir, 'FILE' => \@file };
}

# ソート
sub sorting {
my $sort = shift;
my $key = shift;
my $flg = shift || 'up';
return sort {
$flg eq 'dn' ? $a->{$key} cmp $b->{$key} : $b->{$key} cmp $a->{$key}
} @$sort;
}

# テーブルヘッダ
sub th {
my $cgi = shift;
my $dir = File::Spec->abs2rel(shift);
$cgi->{'type'} ||= 'fn';
$cgi->{'sort'} ||= 'dn';
my %header = (
'fn' => 'ファイル名',
'type' => '種類',
'ts' => 'タイムスタンプ',
);
my $sort = '<sup>' . ($cgi->{'sort'} eq 'up' ? '↑' : '↓') . '</sup>';
while(my ($key, $value) = each(%header)) {
my $st = ($key ne $cgi->{'type'} || $cgi->{'sort'} eq 'dn' ? 'up' : 'dn');
$header{$key} = "<a href=\"$script?dir=$dir&amp;type=$key&amp;sort=$st\">$value</a>" .
($key eq $cgi->{'type'} ? "$sort" : '');
}
return "<tr>\n<th>$header{'fn'}</th><th>$header{'type'}</th><th>$header{'ts'}</th>\n</tr>\n";
}

1;

結構いい加減ですのでもう少し修正できればよかったのですが...。
動作確認したのもWinのみですので他のOSでの動作は保証しません。
(特にMacOSのパス区切りに対応できていません)
    • good
    • 0
この回答へのお礼

ありがとうございます!
こういうの探してました!
しかし設置してみたところDIRのリンクはできているのですがクリックしても中のファイルが一覧表示されません
cgiの書き換える場所が分からずそのままサーバーに設置してしまったのがいけなかったのでしょうか・・・

お礼日時:2008/07/14 17:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!