「CGI&SSIを使うとホームページ作成にこんなに差が出る」
を図書館でみつけよみました。そこでFLY関係のCGIを動かして
みたのですが自分の環境では全く動作しませんでした。コード
修正してうまくいったのでご報告したいとおもいます。
環境:widows2000pro + activeperl v.5.6.1 + AN HTTPD 1.42h
そしてFLY.exe はcgi-bin 直下におき、FLY関係のCGIはcgi-bin 直下
にフォルダをつくりそのなかにいれました。
修正してうごいたもの:
*ここのHPの s18.lzh "アナログ時計 / アナログ時計" →clock.cgi
http://p4room.mda.or.jp/book/cgi2/download/dload.cgi?s18.lzh
*ここのHPの s14.lzh "似顔絵付きBBS" →face.cgi
http://p4room.mda.or.jp/book/cgi2/download/dload.cgi?s14.lzh
参考になったサイト:
*http://p4room.mda.or.jp/
*An HTTP 掲示板 1999/02/07 20:33の記述
原因:
DOS/Windowsではファイル入出力にバイナリ/テキストモードがあり、
デフォルトはテキストモード。
Windows上ではパイプ出力をバイナリモードにすることができない。、
そこでファイルの入出力関係をいじりました。
ソースは以下のとおり。
【clock.cgi】
#!/usr/local/bin/perl
#アナログ時計▲(c)p4room(http://p4room.mda.or.jp/)
$fly = "../fly";#flyコマンドのパス
$tmpdir = "/tmp";#一時的にファイルを作るディレクトリ
### 時計の画像の作成
unless (-x $fly) {#flyコマンドが実行できなければ
print "Location: bad.gif\n\n";#失敗画像を表示して中断
exit;
}
#$infile = "$tmpdir/#in$$.gif";#出力画像ファイル 削除 2003/6/10 birdmask
$infile = "/tmp_fly.$$"; # 追加 2003/6/10 birdmask
$outfile = "/tmp_out.$$"; # 追加 2003/6/10 birdmask
($sec,$min,$hour) = localtime(time);#時分秒を得る
$hour -= 12 if ($hour >= 12);#午後なら時間から12を引く
$size = 80;#時計のサイズ(円の直径)
$font = "small";#文字のサイズ
$deg1 = 3.14159265 / 180;#1度をラジアン単位に直した値
$cx = int($size / 2);#($cx,$cy)=中心座標
$cy = int($size / 2);
$blue = "0,0,255";#青色(RGB=0,0,255)
#open(FLY, "|$fly -q -o $infile");#flyコマンドを起動 削除 2003/6/10 birdmask
open(FLY, ">$infile"); # 追加 2003/6/10 birdmask
print FLY "new\n";#初期化
print FLY "size $size,$size\n";#画像サイズを設定
print FLY "transparent $blue\n";#青を透明色にする
print FLY "fsquare 0,0,$size,$blue\n";#全体を青で塗りつぶす
$d = $size;#画像と同サイズで
print FLY "fcircle $cx,$cy,$d,0,0,0\n";#黒い円を描く
$d -= 4;#直径を4減らして
print FLY "fcircle $cx,$cy,$d,204,204,204\n";#灰色の円を描く
print FLY "fcircle $cx,$cy,6,0,0,0\n";#中心に小さな黒丸を描く
for ($i = 1; $i <= 12 ; $i++) {#文字盤を描くループ
$len = $size / 2 - 8;#中心から文字までの距離
$rad = 30 * $i * $deg1;#角度をラジアン単位で算出
$x = $cx + sin($rad) * $len;#x座標を計算
$y = $cy - cos($rad) * $len;#y座標を計算
$x = int($x - 2);#文字幅の約半分だけ左にずらす
$y = int($y - 6);#文字高の約半分だけ上にずらす
print FLY "string 0,0,0,$x,$y,$font,$i\n";#文字を表示
}
$len = $size * 0.4;#長針(分針)の長さ
$rad = $min * 6 * $deg1;#長針の角度
$x = int($cx + sin($rad) * $len);#x座標を計算
$y = int($cy - cos($rad) * $len);#y座標を計算
print FLY "line $cx,$cy,$x,$y,0,0,0\n";#長針を描く
$len = $size * 0.27;#短針(時針)の長さ
$rad = ($hour*30 + $min*0.5) * $deg1;#短針の角度
$x = int($cx + sin($rad) * $len);#x座標を計算
$y = int($cy - cos($rad) * $len);#y座標を計算
print FLY "line $cx,$cy,$x,$y,0,0,0\n";#短針を描く
close(FLY);#flyコマンド終了
### 画像を出力して終了
$date = &gmt_date(time);#現在の時刻
print "Last-Modified: $date\n";#更新時刻の出力
print "Expires: 0\n";#有効期限の出力
print "Content-Type: image/gif\n\n";#GIF画像のMIMEタイプを出力
#open(FILE, $infile);#画像をオープン 削除 2003/6/10 birdmask
#print <FILE>;# 削除 2003/6/10 birdmask
#close(FILE);#クローズ 削除 2003/6/10 birdmask
###############入れ替え↓######################
`$fly -q -i $infile -o $outfile`; #追加 2003/6/10 birdmask
open(FILE, "$outfile"); #追加 2003/6/10 birdmask
binmode(FILE); #追加 2003/6/10 birdmask
binmode(STDOUT); #追加 2003/6/10 birdmask
read(FILE, $output, 2048); #追加 2003/6/10 birdmask
print "$output"; #追加 2003/6/10 birdmask
close(FILE); #追加 2003/6/10 birdmask
###############入れ替え↑######################
unlink($infile); #画像ファイルを削除
unlink($outfile); #unlinkの一行追加 #追加 2003/6/10 birdmask
exit; #おしまい
### 以下サブルーチン
sub gmt_date {
($sec, $min, $hour, $day, $mon, $year, $wday) = gmtime($_[0]);
sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
(Sun, Mon, Tue, Wed, Thu, Fri, Sat)[$wday], $day,
(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)[$mon],
$year+1900, $hour, $min, $sec);
【face.cgi】
#!/usr/local/bin/perl
$fly = "../fly";#FLYコマンドのパス
$img_dir = "img";#パーツ画像のあるディレクトリ
$cache_dir = "cache";#作成画像を保存するディレクトリ
$maxcache = 100;#画像の保存数の上限
### パラメータの取得
$id = $ENV{'QUERY_STRING'};
for ($i = 0; $i < 9; $i++) {
$n = substr($id, $i*4, 2);
$x = hex(substr($id, $i*4+2, 1)) - 7;
$y = hex(substr($id, $i*4+3, 1)) - 7;
$parts[$i] = ($n < 0 || $n > 16) ? 0 : $n;
$xmove[$i] = ($n == 0 || $x < -7 || $x > 7) ? 0 : $x;
$ymove[$i] = ($n == 0 || $y < -7 || $y > 7) ? 0 : $y;
}
$id = "";
for ($i = 0; $i < 9; $i++) {
$id .= sprintf("%02d%x%x", $parts[$i], $xmove[$i] + 7, $ymove[$i] + 7);
}
### 画像作成(キャッシュに存在しない場合のみ)
#$infile = "$cache_dir/$id.gif";#削除 2003/6/10 birdmask
#$outfile = "$cache_dir/$id.gif";#削除 2003/6/10 birdmask
$infile = "/tmp_fly.$$"; #追加 2003/6/10 birdmask
$outfile = "/tmp_out.$$"; #追加 2003/6/10 birdmask
if (-f $infile) {#画像がキャッシュにある場合は再利用
utime(time, time, $infile);#アクセス時刻を更新する
}
else {#画像がキャッシュにない場合は画像作成
&check_cache();#キャッシュの上限チェック
# open(FLY, "| $fly -q -o $infile");#削除 2003/6/10 birdmask
open(FLY, "">$infile"); #追加 2003/6/10 birdmask
print FLY "new\n";#初期化
print FLY "size 64,80\n";#64x80の画像を作る
print FLY "frect 0,0,63,79,0,0,0\n";#黒で塗りつぶす
for ($i = 0; $i < 9; $i++) {#各パーツについてチェック
$n = $parts[$i];#パーツ番号(0..16)
next if ($n == 0);#パーツ番号が0なら表示なし
$x = $xmove[$i];#横の移動量(-7..7)
$y = $ymove[$i];#縦の移動量(-7..7)
$f = sprintf("$img_dir/p%d%02d.gif",$i,$n);#パーツの画像ファイル名
print FLY "copy $x,$y,-1,-1,-1,-1,$f\n";#パーツを追加する
}
close(FLY);#FLYコマンド終了
chmod(0666, $infile);#パーミッションを666に変更
}
### 画像を出力して終了
$date = &gmt_date(time);#現在の時刻を
print "Last-Modified: $date\n";#更新時刻として出力
print "Content-Type: image/gif\n\n";#GIF画像のHTTPヘッダを出力
#open(FILE, $infile);#画像ファイルをオープン
#print <FILE>;#全データを出力
#close(FILE);#ファイルをクローズ
###############入れ替え↓######################
`$fly -q -i $infile -o $outfile`; #追加 2003/6/10 birdmask
open(FILE, "$outfile"); #追加 2003/6/10 birdmask
binmode(FILE); #追加 2003/6/10 birdmask
binmode(STDOUT); #追加 2003/6/10 birdmask
read(FILE, $output, 2048); #追加 2003/6/10 birdmask
print "$output"; #追加 2003/6/10 birdmask
close(FILE); #追加 2003/6/10 birdmask
unlink($infile); #追加 2003/6/10 birdmask
unlink($outfile); #追加 2003/6/10 birdmask
###############入れ替え↑######################
exit;#スクリプト終了
### サブルーチン
sub check_cache {
local(@list, @files, $file, $t, $data);
opendir(DIR, $cache_dir);#キャッシュディレクトリをオープン
@files = readdir(DIR);#ファイル名を読み込む
closedir(DIR);#ディレクトリをクローズ
@files = grep(/[0-9a-f]+\.gif/, @files);#画像ファイルのみ取り出す
return if ($#files < $maxcache);#まだファイル数が少なければ何もしない
foreach $file (@files) {#更新時刻とファイル名のリストを作る
$t = (stat("$cache_dir/$file"))[9];#ファイルの更新時刻を得る
push(@list, sprintf("%11d %s", $t, $file));#"更新時刻 ファイル名"を記録
}
@list = sort(@list);#リストを更新時刻でソートする
splice(@list, $#list - $maxcache/2);#リスト後部(新しいもの)を切り捨てる
foreach $data (@list) {#リストに残った古いデータを見ていく
$file = substr($data, 12);#$dataの12文字目以降がファイル名
unlink("$cache_dir/$file");#そのファイルを削除する
}
}
sub gmt_date {
local($t) = @_;
($sec, $min, $hour, $day, $mon, $year, $wday) = gmtime($t);
return sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
(Sun, Mon, Tue, Wed, Thu, Fri, Sat)[$wday], $day,
(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)[$mon],
$year + 1900, $hour, $min, $sec);
}