質問と回答

『Perlで作るCGI入門』基礎編

結城浩

目次

はじめに

このページでは読者からの質問と回答を紹介します。

最近の話題

2001-05-09 : アクセスカウンタに引数が渡せない

質問

本を読んでアクセスカウンタを動かそうとしていますが、
私の契約しているプロバイダでは、
SSIのコマンドに引数を渡せません。
つまり、
  <!--#exec cmd="./counter.pl countername"-->
という呼び出しができず、
  <!--#exec cmd="./counter.pl"-->
と書かなければなりません。
counter.plをどのように変更したらよいですか。

回答

41行目近辺を以下のように変更してください。

# カウンタ名からファイル名を作る。
$datafile = "$dir/$countername.$extention";

  ↓

# カウンタ名からファイル名を作る。
$datafile = "$dir/counter.cnt";

ここで、counter.cntの部分がカウンタファイルの
名前になります。

また、32行目近辺の引数チェックをはずしてください。

# 引数の数の確認
if ($#ARGV < 0) {
    print "Usage: counter.pl countername\n";
    exit(0);
}

  ↓

 (削除)

2001-03-08 : Perlを初歩から勉強するのにお勧めの本は?

質問

CGIをいじっているうちにPerlをもっと勉強したくなりました。
初歩から勉強するのにお勧めの本はありますか。

回答

あります。
私が書いた『Perl言語プログラミングレッスン』入門編がお勧めです。
詳しくは以下のページをご覧ください。

2001-03-08 : サブルーチンを自分のスクリプトで利用してもいいですか

質問

サブルーチンinit_formはとても使いやすいです。
このサブルーチンを、私の作ったCGIで利用したいです。
サブルーチン自体の改造、変更や抜き出した使用については
許可されているのでしょうか。

回答

サブルーチンを抜き出して使用する場合、
出典を明記していただければ問題ありません。
例えば、あなたのスクリプト中に以下のように書いてください。

    # &init_formは、
    # 結城浩さんのCGIスクリプトのものを利用(改造)させていただきました。
    # http://www.hyuki.com/

2000-05-08 : 掲示板に書き込むと文字化けする

質問

掲示板に書き込むと文字化けするのですが。

回答

ブラウザの文字コードの設定は変えてみましたか。

また、bbs.cgiのはじめにある
$kanjicode = 'euc';$kanjicode = 'sjis';
にして試してみてください。

2000-05-08 : アクセスしたユーザのメールアドレスを知りたい

質問

ホームページにアクセスしたユーザのメールアドレスを知りたいのですが、
良い方法はありませんか?

回答

もっとも確かな方法は、
ユーザに自分のメールアドレスを入力させることです。
自動的にユーザのメールアドレスを知る方法はないと思いますし、
それはWebサイトのセキュリティポリシーとしては適切ではないと思います。
ユーザに明示的に自分のメールアドレスを入力させる方がいいです。

2000-02-28 : 最近のRIMNETでのパーミッション変更方法

質問

最近のRIMNET(stドメイン)では、パーミッションの変更方法が変わったのですか?

回答

1999年末、RIMNET(stドメイン他)ではCGIのサーバとtelnetでログインできるサーバを分けたようです。
このため、これまでのように「telnetでログインしてchmodしてパーミッションを変更」という
やり方ができなくなりました(そもそもtelnetでログインするためには別途申し込みが必要)。
その代わりにFTPを使ってファイルを転送(PUT)後、以下のようにします。

ftp> literal site chmod 766 easy.cgi

(FTPソフトによっては自動的に設定を行ってくれるものもあります)

1999-05-15 : .htaccessのファイル名変更方法

質問

WindowsのExplorerで「.htaccess」というファイルの
名前を変更しようとしましたが、どうしてもできません。
どうしたらよいかご指導いただけますでしょうか。

回答

確かに、Explorerの上からは変更できませんね。
DOSウインドウの中で、renameあるいはrenというコマンドを使い、

rename 元のファイル名  新しいファイル名

のようにすれば変更できるはずです。

1999-04-26 : ロック : ミリセカンド待つ方法

質問

ロック解除待ちのカウンターについて質問です。
sleep (2)ですと2秒ですね。
これを10回くり返すと最大20秒になり、
待ちすぎにならないでしょうか。
リトライの一回分をミリ・セカンドにする必要はないでしょうか。

回答

現実的には、10回待つことはほとんどなく、
通常の掲示板やチャットでは衝突が起こっても
1回程度ですので、問題はありません。
ミリセカンドにする方法は、トリッキーな方法しかなく、
selectという関数を使って以下のようにします。

select(undef, undef, undef, 0.1);

これで0.1秒待ちます。

1998-09-17 eval(...) の意味を教えて下さい

質問

書籍を購入して勉強しています。

eval("flock(FILE, 8)");

という文の意味がどうしてもわからないので
教えて下さい。

回答

簡単に説明します。
flock(FILE, 8) を実行するのだが、
もしもflockという命令が存在しない場合も、
エラーで中断することなく戻ってくる
という処理を行います。

詳しくは、Perlのマニュアル本などをご参照下さい。

1998-09-02 &init_formが使えない?

質問

基礎編を読んでスクリプトを自作しています。
ちゃんと、

    require "jcode.pl";
    &init_form('euc');

のようにしているのですが、エラーになります。
なぜですか?

回答

&init_form は jcode.pl のサブルーチンではありません。
bbs.cgiやchat.cgiなどのスクリプトの中で定義されているサブルーチンです。
スクリプトを自作をなさっているということですので、
きっと &init_form の定義が抜けているものと思われます。
基礎編のスクリプトをダウンロードなさってそれを参照なさるとよいでしょう。

なお、
『Perlで作るCGI入門』応用編の書籍(付録)では、&init_form の内容を詳細に解説していますので、
できればそちらもご参照ください。

1998-08-06 HTML→CSVの変換について

質問

基礎編のp.152に書いてある、
ゲストブックのHTMLファイルをCSV形式に変換する方法を教えてください。

回答

HTMLファイルをCSV形式に変換するのではなく、
最初からCSV形式で保存し、表示するときにHTMLに変換するほうがよいと思います。
「Perlで作るCGI入門」の応用編の方で詳しく紹介しています。
具体的には「アンケート」の章です。
サンプルプログラムは、
「Perlで作るCGI入門」応用編の方から入手できます。

1998-05-25 easy.cgiが動きません

質問

easy.cgiが動きません。
以下に手順を示します。

・easy.cgi は以下です。

    #!/usr/local/bin/perl/

    print "Content-type: text/html\n";
    print "\n";
    print "<HTML>\n";
    print "<H1>Hello!</H1>\n";
    print "</HTML>"\n;

・easy.cgi を FTP で TEXTモードで転送しています。

・easy.cgi のパーミッションは 755 にしています。

・.htaccess は以下のようにして、パーミッションは 644 にしています。

    AddType application/x-httpd-cgi .cgi
    AddType application/x-httpd-cgi .cgi/

・ブラウザで見ると、プロバイダが用意したエラーページになってしまいます。

どうぞよろしくお願いいたします。

回答

手順自体は正しいようです。
けれど、以下の二点がおかしいようです。

(1) easy.cgi の最後の行が変です。

    print "</HTML>\n";

    ではありませんか?

(2) Perlのパスが変です。

    #!/usr/local/bin/perl

    ではありませんか? 最後のスラッシュは不要ではないでしょうか?
    また、/usr/local/bin/perl でいいですか?
    これはプロバイダごとに違います。

できれば、サーバに送る前に文法チェックだけでもなさった方がよいと思います。
それから、もしかして、easy.cgiを手で入力なさいましたか?
本書のスクリプトはネットワークからダウンロードできますので、ぜひそちらをご利用ください。

1998-05-21 UnicodeについてのPerlのツール

質問

Unicode(ユニコード)に関するPerlのツールはご存知ありませんか?

Adobe Acrobat3.0Jを使ってPDFファイルで掲示板ページを作っているのですが、
Acrobat FormなるHTMLのフォームみたいなものから出力される日本語文字が、
ユニコードをURLエンコードした文字列のようなのです。
jcode.plを試しましたが文字化けして全く扱えないものでした。

回答

CPAN (Comprehensive Perl Archive) にあるかもしれません。
Yahoo! でCPANを検索してみてください。

↓結果

検索してみました。

ftp://ftp.lab.kdd.co.jp/lang/perl/CPAN/CPAN.html
の
13_Internationalization_and_Locale
に
uniocde
ftp://ftp.lab.kdd.co.jp/lang/perl/CPAN/modules/by-module/Unicode/
という文字を発見することが出来ました。

1998-04-29 他のユーザからCGIをのぞかれないか?

質問

CGIスクリプトは一般にパーミッションが 755 や 555 になります。
そのサーバにログインできる他のユーザからCGIのスクリプトの内容を
のぞき見される心配はないのでしょうか?

回答

ご指摘のことは起り得ます。
CGIスクリプトはそのサーバにログインできる他のユーザから参照される危険はあります。
また書き込んだデータ(掲示板のファイルなど)は書き換えられてしまう可能性もあります。

1998-04-29 アクセスした人のアドレスってわかるの?

質問

ページにアクセスしたとき、相手(ページ作成者)に
アクセスした人のアドレスはわかってしまうのでしょうか?

回答

メールアドレスはわかりません。
IPアドレスはわかります。

1998-04-05 検索ロボットの制御について教えてください

質問

『Perlで作るCGI入門』基礎編のp.262に「検索ロボット」について
触れられていますが、もう少し具体的に教えてください。

回答

『Perlで作るCGI入門』基礎編の第1刷では、
robots.txt というファイルを置いておけばよいと書いてありましたが、
あれは不正確な表現でした。

(1) サイトの管理者なら、
仮想パスのルートに robots.txt というファイルを置けばロボットを制御できます。

(2) プロバイダと契約している通常のユーザなら、
個々のページに <META>タグを入れることでロボットを制御できます。
<META>タグは<HEAD>〜</HEAD>の中に書きます。

<META NAME="ROBOTS" CONTENT="NOINDEX">
こう書くと、そのページは検索ロボットに登録されません。
(リンクはたどられます)

<META NAME="ROBOTS" CONTENT="NOFOLLOW">
こう書くと、そのページに含まれたリンクを検索ロボットはたどりません。
(そのページ自体は登録されます)

<META NAME="ROBOTS" CONTENT="NONE">
こう書くと、そのページは検索ロボットに登録されず、リンクもたどられません。

<META NAME="keyword" CONTENT="PGP security privacy">
こう書くと、PGP, security, privacy をキーワードとして検索ロボットに登録されます。

1998-03-18 自分でカスタマイズしたらエラーになってしまった

質問

『Perlで作るCGI入門』基礎編を購入したきっかけは、
私にもカスタマイズができるように解説が詳しかったからです。
がんばって「ゲストブック」をカスタマイズして動かしたのですが、
いつかしら、どうやっても Internal Server Error が出てしまうように
なりました。行き詰まっています。
項目はたくさん増やしたのですが、
Content-type: の行のあたりはまったくいじっていません。
どうしたらいいでしょうか?

回答

動作テストする前には必ず文法チェックをしてください。

送っていただいたスクリプトをPerl処理系で文法チェックしたところ、
あなたのホームページのURLの設定に誤りがありました。
よく読むと '...' の対応が変です。

$homepage   = 'http://www.abc.ac.jp/~hanako/'index.html#middle';
↓
$homepage   = 'http://www.abc.ac.jp/~hanako/index.html#middle';

パソコンで動くPerl処理系もネットワークから入手できますので、
探してみてはどうでしょうか。
上のエラーはパソコン(Windows)上のPerl処理系で、
perl -cw guestadd.cgi
としてすぐに見つかりましたよ。
以下のようになります。

c:\tmp> perl -cw guestadd.cgi
syntax error at guestadd.cgi line 25, near "'http://www.abc.ac.jp/~hanako/'index"
guestadd.cgi had compilation errors.

ダウンロード

1998-01-27 ダウンロードで文字化けしてしまいます

質問

Windowsを使っています。
ホームページからPerlスクリプトを「ダウンロード」すると文字化けしてしまいました。
Perlスクリプトをブラウザで表示してコピー&ペーストしたら大丈夫でした。
これでよいのでしょうか?

回答

はい、それで結構です。
ただし、
http://www.hyuki.com/cgibook/#download
に置いてあるアーカイブファイルでまとめてダウンロードした方が便利だと 思います。 アーカイブファイルの中身はシフトJISコードになっていますので、 Windowsでも文字化けしません。 ただし UNIX に持っていくときにEUCに変換する(あるいは持っていった後EUCに変換する) 必要が生じるかもしれません。 結城のページに置いてあるPerlスクリプトは文字コードが日本語EUCになっています。 ですから、直接ダウンロードすると、文字コードがEUCコードになってしまいます。 Windowsだと文字化けして見えますけれど、 UNIX だとあれが文字化けしていない方になるんです。

よくあるエラー

Not foundというエラーになる

質問

掲示板に書き込んだ後、書き込むボタンを押すと Not found になります。
何が原因ですか。

回答

URLが誤っていると思われます。

スクリプト中のURLを記述している部分(bbs.cgiの場合には、変数$bbsurlの値)が、
正しくなっているかご確認ください。

ちなみに、Not found (ノット・ファウンド)というのは「見つからない」という意味です。
書き込みボタンを押したときに呼び出そうとしているURLが、サーバから「見つからない」
と言われているのです。

Command not foundというエラーになる

質問

ダウンロードコーナーから「まとめてダウンロード」したCGIスクリプトが動きません。
Command not found になりました。
改行コードがMS-DOS形式になっているためのようです。
先頭の #! 行に余計なコードがあると問題が起こるようです。

回答

ご指摘ありがとうございます。
CGIスクリプトをサーバに設置(ftpなどでコピー)するときBINARYモードで送ってしまうと、
MS-DOS形式の改行コード(CR LF)がそのまま残ってしまいます。
一行目の、
    #!/usr/local/bin/perl
の部分が、いわば
    #!/usr/local/bin/perl[CR]
となってしまい、Perl処理系が見つからない(Command not found)になるようです。
ftpでTEXT(ASCII)モードで転送してみてください。

Internal Server Errorというエラーになる

質問

CGIを動かそうとすると、
画面に「internal server error」の表示が出るだけで困っています。
何の誤りなのか、サーバーのなにかが問題なのか不明です。

回答

Internal Server Error あるいは Server Error は、よく起きるエラーです。
通常はサーバに原因があるわけではなく、
実行しようとしたCGIの文法ミスが原因です。
つまりCGIのスクリプトがPerlの文法違反を起こしているため、
そもそも実行できないでいるのです。

よくあるのが、二重引用符の中で二重引用符を使っている誤りです。
例えば
$title = "私の"会議室""; # 誤り
は、次のように書かなければなりません。
$title = "私の\"会議室\""; # 正しい
以下のように書くこともできます。
$title = '私の"会議室"'; # 正しい

Can't locate ./jcode.pl というエラーになる

質問

単独テストをしたところ、次のようなメッセージが出ました。
何がいけないのでしょうか。

Can't locate ./jcode.pl in @INC ...

回答

漢字コードライブラリのjcode.plが見つからないと言われています。
CGIファイル(例えばbbs.cgi)と同じ場所にjcode.plを置いてください。

「作業中のため…」というエラーになる

質問

bbs.cgi を使おうと思いましたが、
「作業中のためファイルが読めませんでした。」
と必ずエラーになってしまいます。
どうしたらいいですか?

回答

bbs.cgiの最後の方にある二つのサブルーチン
lock_file と unlock_file が古い(1998-03-22以前)可能性があります。
以下のサブルーチンで置き換えて試してみてください。

# ロック
sub lock_file {
    local(*FILE) = @_;
    if ($uselock) {
        eval("flock(FILE, 2)"); # 2=LOCK_EX
        if ($@) {
            # flock が使えない場合、ここに来る。
            return 0;
        }
    }
    return 1;
}

# アンロック
sub unlock_file {
    local(*FILE) = @_;
    if ($uselock) {
        eval("flock(FILE, 8)"); # 8=LOCK_UN
    }
}

置き換えても症状に変化がない場合、
flock という Perl の組み込み関数が使えないサーバである可能性があります
(例えば Windows 95では使えません)。スクリプトの初めの方にある、

$uselock = 1;

の部分を

$uselock = 0;

に変えてください。

This server is not configured to handle post というエラー

質問

掲示板のCGIを動作させると、
This server is not configured to handle post
と表示されてしまいます。
どうしたらいいでしょうか。

回答

このエラーメッセージの意味は
「このサーバは post メソッドを扱うようには設定されていません」
です。この場合には、スクリプト中で、

<form action=... method=post>

と書いてあるところを

<form action=... method=get>

で試すのが定石です。
やってみてください。

ただし、この場合、長い文章の送信に失敗することがあります。

拙著『Perlで作るCGI入門 基礎編』の p.136 をごらんください。

unmatched () in regexp at jcode.pl...というエラーになる

質問

unmatched () in regexp at jcode.pl line 504.

という表示が出て動きません。
jcode.plには手を加えていないのに、なぜでしょうか?

回答

JPerlを使っていませんか?
JPerl では jcode.pl は使えません。
日本語対応されていない Perl をお使い下さい。

tr : both end of - should be kanji at jcode.pl...というエラーになる

質問

jcode.plで
tr : both end of  - should be kanji at jcode.pl line 250.
というエラーになります。
jcode.plを使わないスクリプトは動きます。
なぜでしょうか?

回答

もしかして JPerlを使っていませんか?
jcode.plを使う場合、
Perl処理系は日本語対応していない perl を使ってください。

Illegal character \015 というエラーになる

質問

掲示板を使おうとしたら、以下のようなエラーになりました。
どのような対処をすればよいでしょうか。
Illegal character \015 (carriage return) at ...
(Maybe you didn't strip carriage returns after a network transfer?)

回答

これはファイルに CR コードが入っているためでしょう。
たとえばWindowsからUNIXにFTPするときに、バイナリモードで転送すると
こうなります。テキストモードなら大丈夫です。

エディタなどで CR を削除する方法もあります。
また、UNIX で

% tr -d '\015' < yourfile.cgi > tmpfile
% mv tmpfile yourfile.cgi

のようにして改行を削除する方法もあります。

アクセスカウンタ

1998-03-16 私のプロバイダではSSIが使えません [CHANGED!]

質問

私のプロバイダではSSIが使えません。
どのようにして counter.pl や countgif.pl を改良したら
アクセスカウンタが使えますか?

回答

CGIしか使えないプロバイダでは、
counter.pl や countgif.pl を改良して動くようにするのは大変です。

現在、『Perlで作るCGI入門』応用編向けに、
CGIだけで動作するアクセスカウンタも作っております。
サンプルプログラムは、
「Perlで作るCGI入門」応用編の方から入手できます。

また、私の作成したものではありませんが、
CERNの場合には fakessi.pl という
SSIをエミュレートするスクリプトも存在する、と聞いております。
情報まで。

1998-01-30 リロードしてもアクセスカウンタが更新されません

質問

SSIを使ったアクセスカウンタを設置しました。
けれどリロード(再読込み)してもアクセスカウンタが増えないことがあります。
Netscape Navigatorだとカウントアップするのですが、
Microsoft Internet Explorerでは変化しないことがあるようです。
どうしてでしょうか?
どうしたらいいですか?

回答

キャッシュサーバの影響が考えられます。
キャッシュサーバというのはWebサーバとブラウザの間に入って、
表示されたページを一時保存しているサーバのことです。
キャッシュサーバがいると、ページが高速に表示できるようになります。
しかしその反面Webサーバへアクセスしなくなるので、
SSIのプログラムが動作せず、カウントアップもしないことになります。

Microsoft Internet Explorerとキャッシュサーバの組み合わせで、
リロードしてもWebサーバへアクセスしないことがあるようです。

リムネットの場合、HTMLファイルの拡張子を
 .htm や .html ではなくて、 .shtml のように変更すると
キャッシュサーバを介さなくなり、カウントアップされるようになります。
この際に、拡張子 .shtml が SSI である旨を
.htaccess に書いておくのがよいでしょう。
他のプロバイダではどういう対処ができるかよくわかりません。

1998-02-03 SSIで cgi= を使う場合

質問

本を読んでアクセスカウンタを動かそうとしています。
SSIのコマンドを
  <!--#exec cmd="./counter.pl countername"-->
から、
  <!--#exec cgi=xxx.cgi"-->
に変えたい場合、counter.plをどのように変更すればいいでしょうか。

回答

本書のp.336とp.346を参照してください。
なお、p.346 に誤りがあります。以下のリンクをご確認ください。

掲示板 (bbs.cgi)

1998-03-10 掲示板の書き込みを折り返しさせたい

質問

掲示板の書き込み内容を、自動的にブラウザの右端で折り返し
させたいのですが、どうしたらよいですか?

回答

bbs.cgi の中のメッセージを構成する部分で、
<PRE> と </PRE> という文字列を削除すればよいでしょう。

1998-03-04 削除モードを持った掲示板について [CHANGED!]

質問

「管理者モード」や「削除モード」を持った掲示板について
参考文献や参考になるホームページなどはご存知ありませんでしょうか。

回答

結城の次回の著作「Perlで作るCGI入門 応用編」でも、
管理者モードや削除モードを持った掲示板の仕組みを詳しく
ご紹介しています。

サンプルプログラムは、
「Perlで作るCGI入門」応用編の方から入手できます。

1998-02-20 一回の書き込み量を制限したい

質問

掲示板(bbs.cgi)で、一回ものすごい量の書き込みをする人がいます。
一回の書き込み量の制限をしたいのですが、できますか?
どのようにすればいいですか?

回答

bbs.cgi を修正すれば容易にできます。


# 書き込みメッセージ構成
$message = "$myname $mymail $myhttp<BR>$datestr<BR><PRE>$mycomment</PRE><HR>";

の後のところに、

if (length($mycomment) > 1000) {
    &print_error("書き込みが長すぎますので短くしてください");
}

というプログラムを追加すればよいと思います。
1000 は例です。
これはバイト数ですので、日本語の文字数では半分(500文字)になります。
あなたの質問「掲示板(bbs.cgi)で……いいですか?」は約150バイトです。

チャット (chat.cgi)

1998-03-18 チャットから出るときに名前が文字化けします

質問

誰でも、というわけではないのですが、
チャットから出るときに名前が文字化けすることがあります。

回答

詳しく調べてみました。
原因はよくわかりませんが、名前の最後の一バイトが欠けることがあるようですね。
もしも気になるようならば、chat.cgi の「ログアウト」の部分を次のように
変更してください。

<A HREF="$chaturl?myaction=exit&myname=$myname">ログアウト</A>

↓

<FORM ACTION=$chaturl METHOD=post>
<INPUT TYPE=hidden NAME=myaction VALUE=exit>
<INPUT TYPE=hidden NAME=myname VALUE="$myname">
<INPUT TYPE=submit VALUE=ログアウト>
</FORM>

1998-05-18 チャットがときどき文字化けする (初出 1998-03-10)

質問

チャット(chat.cgi)がときどき文字化けするようですが、
どうしたらいいですか。
漢字コードはすべて EUC に統一しています。

回答

chat.cgi の下のフレームを出力する部分のプログラムに、
以下の一行を入れてみてください。

    # HTMLのはじめの部分を表示
    print "<HTML><HEAD>\n";
    print "<META HTTP-EQUIV=Refresh CONTENT=$interval>\n";
    print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=x-euc-jp\">\n";
    print "</HEAD>\n";
    print "$bodytag<HR>\n";

なお、挿入する文字列は漢字コードにより異なります。
上は EUC の場合です。その他は以下を参照してください。

SJIS
print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=Shift_JIS\">\n";
(古いブラウザの場合には、Shift_JISではなく、x-sjis を使わないとかえって文字化けする場合があります)

EUC
print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=EUC-JP\">\n";
(古いブラウザの場合には、EUC-JPではなく、x-euc-jp を使わないとかえって文字化けする場合があります)

JIS
print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=iso-2022-jp\">\n";

1998-02-15 チャットでフォーカスを制御したい

質問

chat.cgi を使ってチャットを作ろうとしています。
発言したあと、テキスト入力部分に自動的にフォーカスを当てるにはどうしたらいいですか。
現在は発言ボタンを押した後、テキスト入力部分にマウスをもっていって
一度クリックしてやる必要があります。

回答

chat.cgi のサブルーチン &show_say を 以下の赤文字の部分に注意して修正してください。
これは JavaScript (ジャバスクリプト)という言語の機能を使っています。
『Perlで作るCGI入門』応用編ではこの方法を使って自動的にフォーカスがあたるチャットを紹介しています。

# 発言ページの表示
sub show_say {
print <<"end_of_show_say";
<HTML>
  <HEAD>
    <TITLE>$titlechat:発言</TITLE>
  </HEAD>
  <BODY BGCOLOR="white" onLoad="document.sayform.mycomment.focus();">
  # $bodytag は削除
    <H3>$titlechat:気軽におしゃべりしましょう</H3>
      [
      <A HREF="$chaturl?myaction=update" TARGET="msg">表示の更新</A>
      |
      <A HREF="$chaturl?myaction=exit&myname=$myname">ログアウト</A>
      ]
      <FORM ACTION="$chaturl" METHOD="post" NAME=sayform>
        $myname:<INPUT TYPE="text" NAME="mycomment" SIZE=60>
        <INPUT TYPE="hidden" NAME="myaction" VALUE="say">
        <INPUT TYPE="hidden" NAME="myname" VALUE="$myname">
        <INPUT TYPE="submit" VALUE=" 発言 ">
      </FORM>
  </BODY>
</HTML>
end_of_show_say
}

ゲストブック (guestadd.cgi)

1998-03-16 ゲストブックで古いものは自動削除したい

質問

ゲストブックのデータを最新の何個かだけ残して、
それよりも古いものは自動的に削除するようにしたいのですが、
どうすればよいのでしょうか。

回答

guestadd.cgi の、

    print TXT @txt;

の行を削除して、
以下のコードに置き換えればよいはずです。
(50は保存件数 + 1)

    $nth = 0;
    for ($i = 0; $i < @txt; $i++) {
        if ($txt[$i] eq "<HR>\n") {
            $nth++;
            if ($nth >= 50) {
                last;
            }
        }
        print TXT $txt[$i];
    }
    print TXT "<HR>\n";

なお、必ず、
これまでのゲストブックのデータをバックアップしてから上を試してください。

1998-03-16 ゲストブックでユーザの改行を生かしたい

質問

ユーザがゲストブックに記入したとき、
長い文章の中に改行をいくら入れたとしても、
ゲストブックの閲覧する時には、すべて無視されて一行になってしまいます。
改行を生かしたいのですが、どうしたらいいですか。

回答

改行を改行として扱う簡単な方法は、
<PRE>を使う方法です。
guestadd.cgi を以下のように修正してください。

# コメント
if ($mycomment ne '') {
    print TXT "<DT>コメント<DD>$mycomment\n";
}

↓

# コメント
if ($mycomment ne '') {
    print TXT "<DT>コメント<DD><PRE>$mycomment</PRE>\n";
}

漢字コード

1998-02-22 どうやって EUC コードに変換したらいいかわからない

質問

ゲストブックを作っていますが、
一応動くのですが、文字化けしてしまいます。
漢字コードの統一の方法がどうしても分かりません。

「PerlプログラムをUNIXで転送後、EUCに変換する必要があります」

と書いてありますが、具体的な方法を教えてください。

回答

ファイルの漢字コードの変換を行うにはツールが必要です。
(p.305でも簡単に触れています)。

■nkf を使う場合

nkf というツールがインストールされている場合の例を説明します。
ファイル guestadd.cgi を EUC に変換する手順です。

(1) nkf を使って EUC コードになったファイルを作る

    % nkf -e guestadd.cgi > guestadd.euc

(2) そのファイル(guestadd.euc)をあらたな guestadd.cgi にする

    % mv guestadd.euc guestadd.cgi

ここで guestadd.euc は一時的に使うファイルですから、
もっと短い名前でも全然構いません。例えば、以下のようにしてもいいです。

    % nkf -e guestadd.cgi > a
    % mv a guestadd.cgi

でも次のようにしてはいけません。

    % nkf -e guestadd.cgi > guestadd.cgi

このようにすると、guestadd.cgi の内容は消えてしまいます
(p.305 の例では大文字小文字が違うことに注意してください)。

■sjtoeuc を使う場合

RIMNETでは sjtoeuc というツールが使えます。
以下はファイル guestadd.cgi を EUC に変換する手順です。

(1) sjtoeuc を使って EUC コードになったファイルを作る

    % sjtoeuc guestadd.cgi > guestadd.euc

(2) そのファイル(guestadd.euc)をあらたな guestadd.cgi にする

    % mv guestadd.euc guestadd.cgi


もしもあなたがパソコン上の漢字コード変換ツールを持っているのなら、
パソコン上で EUC に変換してから UNIX に転送してもけっこうです。

1998-02-05 日本語EUCコードのファイルをWindowsで編集したい

質問

日本語EUCコードのファイルをWindowsで編集したいのですが、
どうしたらいいですか。

回答

秀丸エディタで編集できます。
秀丸を起動するときのオプションで /fe をつけると
日本語EUCのファイルが編集できるようです(Version 2.13で確認)。
詳細は秀丸エディタのヘルプ「秀丸起動時のオプション」を参考にしてください。
また、以下に秀丸エディタのホームページへのリンクを示します。

パーミッションの変更

1999-07-09 : chmodでパーミッションが変更できない

質問

FTPを使ってUNIXサーバー上にファイルを転送しましたが、
easy.cgiをどうしても実行可能なファイルにできません。
    chmod 755 easy.cgi
という命令を実行してみたのですが、何度やっても”Invalid Command”と表示されてしまうのです。
ちなみにリムネットです。

回答

chmodというコマンドはFTPのコマンドではありません。
リムネットだとするとtelnetでUNIXにログインできると思います。
telnetでログインしてeasy.cgiがあるディレクトリ(public_htmlでしょうか)
に行き、そこで chmod します。
以下のようになります。

(1) telnet でログイン
(2) cd public_html      (easy.cgi が public_html ディレクトリにあるなら)
(3) chmod 755 easy.cgi

です。

1998-01-27 telnetが使えないプロバイダでファイルのパーミッションを変更したい

質問

CGIは使えるけれど、UNIXのシェルが使えないプロバイダを利用しています。
どうやってファイルのパーミッションを変更したらいいのでしょうか。

回答

UNIXのシェルが使える場合には、
chmod というコマンドでファイルのパミッションが変更できます。
例:
    % chmod 755 hello.cgi

FTPしか使えない場合には、
quote というコマンドでファイルのパミッションが変更できる場合があると聞いています。
例:
    ftp> quote site chmod 755 easy.cgi

詳しくは、プロバイダから提供されているマニュアルをごらんください。

ディレクトリのパーミッションを 777 にしてはいけないのか

質問

『Perlで作るCGI入門』の中でディレクトリの属性を 777 にしてはならないと書かれていますが、
ある別のサイトから入手した掲示板CGIスクリプトでは
「ログ消滅防止策として、ファイルロック機構を使う場合、
 cgi-binディレクトリのパーミッションを777 にする必要があります」
と説明されていますがこの場合も777にしてはいけないのですか?
symlinkやopenでロックを実現しているようです。

回答

とてもよい質問です。
ディレクトリのパーミッションを777にするとどうなるかを説明します。
777にすると、そのディレクトリに誰でも
ファイルを作る・ファイルを消すという操作ができることになります。

symlinkを使ってロックを実現する、
あるいはロックファイルを新たに作成してロックを実現するためには、
Webサーバが
あらたにファイルを作ったり消したりする操作ができなければいけないので、
777にする必要があるわけです。

しかしもし、悪意のあるユーザが、
そのディレクトリのファイルを消そうとしたら消せてしまうことになります。
悪いことには新たにファイルを作ることすらできるわけです。
要するに、あなたが設置したスクリプトファイルをごっそり削除したり、
ごっそり別のスクリプトにすげかえたりすることもできてしまいます。

悪意のあるユーザがいなくても、
不注意なユーザが、上のディレクトリで rm -rf / などとやった場合
(つまり以下のディレクトリ中のファイルすべて削除というコマンド)
あなたの cgi-bin の中にあるファイルがすべて失われます。

以上の危険性(777にしたディレクトリ中のファイルが失われる、あるいは
すげかえられる可能性)を理解しており、それをよしとするならば、
777にしても構いません。
(例えばそのマシンにログインできるユーザが自分しかいないような場合です)

もう一つよい方法は、
777にするディレクトリをcgi-bin にするのではなく、
全く別のディレクトリにすることです。
例えば lockdir などというディレクトリを作り、そこだけを777にする。
そうすれば、万一削除されたとしても、スクリプトは無事になります。

補足:以上の「悪意のあるユーザ」や「不注意なユーザ」というのは、
そのディレクトリに直接アクセスできるユーザという意味です。

以上のような情報は混乱を招きがちなため、
入門書としての『Perlで作るCGI入門』では、777にしてはならない、
と解説してあります。

その他

1998-03-06 自分のパソコン上でCGIの動作テストをしたい

質問

いちいちプロバイダにつながずに、
自分のパソコン上でCGIの動作テストをしたいのですが、
どうしたらいいですか?

回答

いい手があります。
中田さんという方が AN HTTPD という httpd (Webサーバ)を作成しています。
これは簡単に使え、しかもフリーで入手できます。
これを使えば、
自分のパソコン上にインストールしてCGIやSSIの動作がチェックできます。
結城のスクリプトを動かす上での注意点は以下の通り。

・漢字コードを全部シフトJISにしておく
・Win95では flock が使えないのでロックはオフにしておく
・.htaccess は不要
・Perlは別途必要

以下にリンクを示します。

1998-03-04 「基礎編」の次の本も出るのでしょうか?

質問

「Perlで作るCGI入門 基礎編」を読んで勉強しています。
ところで、「基礎編」ということは次の本も出るのでしょうか?
いつ、どんな内容になるのでしょうか。

回答

次の本「応用編」は現在発売中です。
詳細は、
「Perlで作るCGI入門」応用編をご覧ください。

1998-02-22 どうやってログインすればいいかわからない

質問

書籍を購入して勉強しています。
本の中にサーバのUNIXについてたくさん記述がありますが、よくわかりません。
例えば p.31 に「UNIX にログインして ls というコマンドで確認」とありますが、
どうやればいいのでしょうか?

ファイルを転送するとき、
DOSプロンプトでFTPを起動してユーザ名とパスワードを入力しますが、
これが「UNIX にログイン」ということなのでしょうか?

回答

おおよそ正しいですが、厳密に言えば違います。
「telnetでのログイン」と「ftpでのログイン」の違いです。

p.31 の本文は RIMNET のように UNIX のシェルを使用させてくれる
プロバイダの場合の記述になります。
「シェルを使用させてくれる」というのは「telnet でログインできる」という意味です。

ここで書いているのはUNIXに(telnetで)ログインするという意味です。
あなたが書かれているのはUNIXに(ftpで)ログインする操作になります。

ftpでログインした場合にはftpのコマンドしか使えないですが、
telnetでログインした場合には(本の付録Dにあるような)
UNIXのコマンドがすべて使える状況になります。

でも、まあ、以上は知識としてのお話です。

実際上はファイルの存在・名前・属性が確認できればいいですので、
図2-3 (p.31) にあるように ftp のコマンドで用は足りているわけです。

1998-02-02 文字列の一部の色を変えようとしたがエラーになります

質問

スクリプトの中で、
  $message = "$myname $mymail ...";
というところで、名前に色をつけようと思い、
  $message = "<FONT COLOR="red">$myname</FONT> $mymail ...";
と変更したらエラーになりました。
どうしてでしょうか。

回答

二重引用符でくくられた文字列の中で二重引用符を使っているからです。
  $message = "<FONT COLOR=\"red\">$myname</FONT> $mymail ...";
または
  $message = "<FONT COLOR=red>$myname</FONT> $mymail ...";
のようにしてください。
[Perl]

1998-01-30 スクリプトを改造した際の著作権表示はどのようにすればいいですか

質問

本のはじめの方に、
「改造した場合には、改造した人の著作権表示をファイル中に含めてください。」
と書かれていましたが、具体的にどのようにすればいいのですか。

回答

ゲストブック、掲示板、チャットなど
まとまった機能を持つスクリプトの中には、
$modifier という名前の変数があります。
その変数の値を、

  $modifier = 'XXXXX';

のように書き換えると、自動的に結城の著作権表示の下に、

  Copyright (C) 1997, 1998 by Hiroshi Yuki.
  Modified by XXXXX

のように表示されるようになっています。
改造した方は、自分のCGIスクリプトの XXXXX の部分に
自分の名前を入れてください。

豊かな人生のための四つの法則