CLIP-MAILをロリポで使おうと思ったらいろいろあったので、メモがてら

アンケートフォームに画像を添付したいとのご要望をいただいて、今回はKENT-WEBさんのCLIP-MAILというフリーソフトを使用しました。
使用バージョンは4.01 UTF-Versionです。
今回ロリポップ!でいくらかトラブルがあって、ググってもわりと古いサポート情報しか見当たらないこともあったので、まとめておきます。

500エラーで表示されない

これはロリポに関して言えば、改行コードによるもののようでした。
.cgiのファイルの改行コードがCR+LFになっているのをすべてLFに変換したら表示されました。

添付ファイルが確認画面で表示されない

添付画像をアップロードすると確認画面でサムネイルが表示されるはずなのですが、画像が500エラーでロードされない現象がありました。そのまま送信するとメールにはきちんと画像が添付されています。
これはディレクトリのパーミッションが原因でした。
ロリポはsuEXECサーバーになりますので、基本CLIP-MAILの説明ページにある通りuplディレクトリには700を指定していたのですが、707にしないと確認画面でサムネイルが表示できませんでした。

入力エラー画面で項目の順番がバラバラになる

必須項目が入力されていない場合などに、それらが後ろにいく仕様になっているようです。

説明ページに下記のとおり書かれているのですが、これでは解決しませんでした。

・制御タグ-3
→ name値の並び順を指定する(半角スペースで複数指定)
→ 入力エラー画面及びメール本文の並びを指定します
(例)

<input type="hidden" name="sort" value="name email メッセージ" />

以下はコアプログラム(clipmail.cgi)をカスタマイズしますのでご注意ください。
サポートの情報だとわりと端折った中上級者向けの書き方をされていてわかりにくかったので、ちょっと長いですが、該当部分を引用します。
一箇所目は587行目くらいから。

#-----------------------------------------------------------
#  フォームデコード
#-----------------------------------------------------------
sub parse_form {
	my ($clip,@key,@need,%in);
	foreach my $key ( $cgi->param() ) {
		my $val;

		# 添付
		if ($key =~ /^clip-\d+$/) {
			$val = $cgi->param($key);
			if ($val) { $clip++; }

		# テキスト系
		} else {

			# 複数値の場合はスペースで区切る
			$val = join(" ", $cgi->param($key));

			# 無害化/改行変換
			$key =~ s/[<>&"'\r\n]//g;
			$val =~ s/&/&amp;/g;
			$val =~ s/</&lt;/g;
			$val =~ s/>/&gt;/g;
			$val =~ s/"/&quot;/g;
			$val =~ s/'/&#39;/g;
			$val =~ s/\r\n/\t/g;
			$val =~ s/\r/\t/g;
			$val =~ s/\n/\t/g;
			$val =~ s/-/-/g;
			$val =~ s/~/~/g;

			# 文字コード変換
			if ($cf{conv_code}) {
				$key = $j->set($key)->utf8;
				$val = $j->set($val)->utf8;
			}

			# 入力必須
# ここからコメントアウト
#			if ($key =~ /^_(.+)/) {
#				$key = $1;
#				push(@need,$key);
#			}
# ここまでコメントアウト

# ここから追記
# 必須入力項目
if ($key =~ /^_(.+)/) {
$key = $1;
push(@need,$key);
if ($val eq "") { $check++; push(@err,$key); }
}
$in{$key} .= "\0" if (defined($in{$key}));
$in{$key} .= $val;
next if($key eq 'sort'); ## ←追加
push(@key,$key);
# ここまで追記


		}

		# 受け取るキーの順番を覚えておく
		push(@key,$key);

		# %inハッシュに代入
		$in{$key} = $val;
	}

	# post送信チェック
	if ($cf{postonly} && $ENV{REQUEST_METHOD} ne 'POST') {
		&error("不正なアクセスです");
	}
	# 添付拒否の場合
	if (!$cf{attach} && $clip) {
		&error("不正なアクセスです");
	}

	# リファレンスで返す
	return (\@key,\@need,\%in);


}

もう一箇所はその続き部分

#-----------------------------------------------------------
#  入力エラー表示
#-----------------------------------------------------------
sub err_check {
	my $match2 = shift;

	# テンプレート読み込み
	my ($err,$flg,$cell,%fname,%err);
	open(IN,"$cf{tmpldir}/err2.html") or &error("open err: err2.html");
	my $tmpl = join('', <IN>);
	close(IN);

	# テンプレート分割
	my ($head,$loop,$foot) = $tmpl =~ /(.+)<!-- cell_begin -->(.+)<!-- cell_end -->(.+)/s
			? ($1,$2,$3) : &error("テンプレート不正");

	# 画面展開
	print "Content-type: text/html; charset=utf-8\n\n";
	print $head;
	my $bef;
# 一行コメントアウトして、その次の行を追加
# foreach my $key (@$key) {
foreach my $key (split(/ /,$$in{sort})) { ## ←追加
		next if ($key eq "need");
		next if ($key eq "match");
		next if ($$in{match} && $key eq $match2);
		next if ($_ eq "match");
		next if ($bef eq $key);
		next if ($key eq "x");
		next if ($key eq "y");

これで

<input type="hidden" name="sort" value="name email メッセージ" />

をhtmlのform要素に入れれば指定の順に並びます。

ログデータをCSVでダウンロードできたりもするので、とても使いやすいファイルアップロード機能付きフォームだと思います。