Current Path : /home/tools/fm/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //home/tools/fm/formmail.cgi |
#!/usr/bin/perl -w # # formmail.cgi # #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// use Module #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= use strict; use Jcode; use CGI::FastTemplate; use ADN::HTML; use ADN::Utility; #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Controller #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// ---------------------------------------------------------- #// 変数設定 #// ---------------------------------------------------------- my $query = ADN::Utility::query(); my $mode = 0; my $action = 0; my $page = 1; if ($query->{form}->{mode}) { $mode = $query->{form}->{mode}; } if ($query->{form}->{action}) { $action = $query->{form}->{action}; } if ($query->{form}->{page}) { $page = $query->{form}->{page}; } #// ---------------------------------------------------------- #// 設定ファイルからハッシュリファレンス生成 #// ---------------------------------------------------------- #// テスト環境か実環境か判定 my $file_conf0 = './fmadmin.conf'; my $conf0 = ADN::Utility::read_conf($file_conf0); my $path_tml = $conf0->{CUST_PATH_TML}; if ($mode == 1) { $path_tml = $conf0->{CUST_PATH_TML0}; } #// 対象設定ファイルから読み込み my $file_conf = $path_tml . $conf0->{CONF_FORM}; my $conf1 = ADN::Utility::read_conf($file_conf); #// 各ハッシュリファレンスを合成 my $conf = ADN::Utility::merge_conf($conf0, $conf1); $conf->{MODE} = $mode; if ($mode == 0) { $conf->{TITLE_CHECK} = ''; } if ($conf->{MAINT} == 1 && $mode == 0) { $action = 3; } $conf->{ACTION} = $action; $conf->{PAGE} = $page; #// ---------------------------------------------------------- #// スイッチ #// ---------------------------------------------------------- my $tml = new CGI::FastTemplate($path_tml); $conf->{MAKE_PATH_TML} = $path_tml; if ($action == 0) { input($tml, $conf, $query, $page); } if ($action == 1) { confirm($tml, $conf, $query); } if ($action == 2) { thanks($tml, $conf, $query); } if ($action == 3) { maint($tml, $conf); } #// HTML 出力 ADN::HTML::write_adn($tml, $conf); #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Model (Logic) #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= sub input { my ($tml, $conf, $query, $page) = @_; my @error = check($conf, $query); if (@error) { show_error($tml, $conf, \@error); } else { my $input = "input_p" . $page . ".html"; my $row = "input_row.html"; $tml->define(main => $input, row => $row); $tml->assign($conf); #// input hidden 処理 value_hidden($query, $tml, '.row'); } my $title = 'TITLE_INPUT' . $page; $tml->assign( MAKE_MODE => $conf->{MODE}, MAKE_TITLE => $conf->{$title}, ); } sub confirm { my ($tml, $conf, $query) = @_; my @error = check($conf, $query); if (@error) { show_error($tml, $conf, \@error); } else { my $confirm = "confirm.html"; my $row0 = "input_row.html"; my $row1 = "confirm_row.html"; $tml->define(main => $confirm, row0 => $row0, row1 => $row1); $tml->assign($conf); #// input hidden 処理 value_hidden($query, $tml, '.row0'); #// HTML 表示処理 my @sort = split(/ /, get_sort($conf)); foreach (@sort) { my $key = "name" . $_; my $value0 = $query->{form}->{$key}; if ($value0) { $value0 =~ s/[\t\r]//g; } else { $value0 = ''; } my ($name, $value) = value_sort($_, $conf, $value0, $query, ','); $value = ADN::Utility::untag($value); $value = ADN::Utility::htmlchars(ADN::Utility::z2asc($value)); $value = ADN::Utility::lf2br($value); $tml->assign( MAKE_NAME => $name, MAKE_VALUE => $value ); $tml->parse(CONFIRM_ROW => ".row1"); } } $tml->assign( MAKE_MODE => $conf->{MODE}, MAKE_TITLE => $conf->{TITLE_CONFIRM}, MAKE_SCRIPT => $conf->{SCRIPT_FORM}, ); } sub thanks { my ($tml, $conf, $query) = @_; #// メールヘッダ my $base_addr = $conf->{MAIL_FROM}; unless ($conf->{MAIL_FROM}) { $conf->{MAIL_FROM} = 'formmail@drive.ne.jp'; } unless ($conf->{MAIL_RCPT0}) { $conf->{MAIL_RCPT0} = $base_addr; } my $header = {}; $header->{Subject} = $conf->{MAIL_SUBJ}; $header->{From} = $base_addr; $header->{To} = ($conf->{MODE} == 0) ? $conf->{MAIL_RCPT} : $conf->{MAIL_RCPT0}; $header->{Cc} = $conf->{MAIL_COPY}; $header->{Bcc} = ''; #// メール本文, CSV my $show_blank = ' ' x 2; my $text_blank = 4; my $mail_line = $conf->{MAIL_LINE}; my $body = $conf->{MAIL_ADD0}; $body =~ s/\x5c\x6e/\n/g; $body .= "\n\n"; my $csv = ''; my @sort = split(/ /, get_sort($conf)); foreach (@sort) { my $key = "name" . $_; my $value0 = $query->{form}->{$key}; if ($value0) { $value0 = ADN::Utility::z2asc($value0); $value0 =~ s/[\t\r]//g; $value0 =~ s/<br>/\n/ig; } else { $value0 = ''; } #// CSV $csv .= "$value0\t"; #// メール my ($name, $value) = value_sort($_, $conf, $value0, $query, ','); $name = ADN::Utility::untag($name); $value = ADN::Utility::untag($value); $value = ADN::Utility::rev_htmlchars($value); $value = ADN::Utility::txt_make($text_blank, $mail_line, Jcode->new(\$value)->euc); $body .= $show_blank . $name . "\n" . "$value\n\n"; } $body .= $show_blank . '----------' . "\n"; my $count = 0; foreach (split/ /, $conf->{CSV_ITEM}) { my $name = "CSV" . $count . "_SHOW"; $name = $conf->{$name}; my $item = "CSV" . $count . "_ITEM"; $item = $conf->{$item}; my $value = $ENV{$item}; $value = ADN::Utility::txt_make($text_blank, $mail_line, Jcode->new(\$value)->euc); $body .= $show_blank . $name . "\n" . "$value\n\n"; $count += 1; } $body =~ s/\n\n$/\n/; $body .= $show_blank . '----------' . "\n"; #// メール送信 my $mta = $conf->{SYSTEM_SENDMAIL} . " -t"; ADN::Utility::mail_send($mta, $header, \$body); #// CSV データ蓄積 $csv .= csv_add($conf); my $char = $conf->{CSV_CHAR}; $csv = Jcode->new(\$csv)->$char; if ($conf->{CSV_TYPE} == 1) { #// カンマ区切り $csv = ADN::Utility::csv_make($csv); } else { #// タブ区切り $conf->{CSV_PATH} =~ s/\.([a-zA-Z]+)$/\.txt/; } open CSV, ">>$conf->{CSV_PATH}"; print CSV "$csv\n"; close CSV; `$conf->{SYSTEM_CHMOD} 666 $conf->{CSV_PATH}`; #// 完了画面 $tml->define(main => "thanks.html"); $tml->assign($conf); $tml->assign( MAKE_MODE => $conf->{MODE}, MAKE_TITLE => $conf->{TITLE_THANKS}, MAKE_SCRIPT => $conf->{SCRIPT_FORM}, ); } sub maint { my ($tml, $conf) = @_; $tml->define(main => "maint.html"); $tml->assign($conf); $tml->assign( MAKE_MODE => $conf->{MODE}, MAKE_TITLE => $conf->{TITLE_MAINT}, MAKE_SCRIPT => $conf->{SCRIPT_FORM}, ); } #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Model (Parts) #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= sub check { my ($conf, $query) = @_; my @error = (); my $must_v = ''; #// 必須入力項目 取得 my $page = $conf->{PAGE_INPUT}; foreach my $p (1 .. $page) { my $must_n = "MUST_INPUT" . $p; if ($conf->{$must_n}) { $must_v .= ',' . $conf->{$must_n}; } } $must_v =~ s/^,//; #// ユーザ入力から、チェックタイプを通すか判別。 foreach (%{$query->{form}}) { next if (!defined $query->{form}->{$_}); next if ($_ !~ /^name(\d+)/); my $must = 0; foreach my $name (split(/,/, $must_v)) { if ($_ eq $name) { $must = 1; last; } } my $value = ADN::Utility::z2asc($query->{form}->{$_}); $_ =~ s/^name//; my $ecc = "NAME" . $_ . "_ECC0"; my $title = "NAME" . $_ . "_SHOW"; #// チェックタイプを通す if ($conf->{$ecc}) { my $check = value_check($ecc, $title, $value, $conf, $must); if ($check) { push(@error, $check); } } } return @error; } sub show_error { my ($tml, $conf, $ref) = @_; my @error = @$ref; my $error = 'error.html'; my $row = 'error_row.html'; $tml->define(main => $error, row => $row); $tml->assign($conf); foreach (@error) { my $title = pop(@$_); my $msg = ADN::Utility::dump_array($_, "<br>\n"); $tml->assign( MAKE_ERROR_TITLE => ADN::Utility::htmlchars($title), MAKE_ERROR_MSG => $msg ); $tml->parse(ERROR_ROW => ".row"); } $tml->assign(MAKE_TITLE => $conf->{TITLE_ERROR}); ADN::HTML::write_adn($tml, $conf); exit; } #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Model (Parts) #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= sub get_sort { my $conf = shift; my $sort = ''; foreach (%$conf) { if ($_ =~ /^SORT_INPUT/) { $sort .= $conf->{$_} . " "; } } $sort =~ s/ $//; return $sort; } sub value_hidden { my ($query, $tml, $row) = @_; foreach my $key (%{$query->{form}}) { if ($key =~ /name\d/) { my $value = $query->{form}->{$key}; if (ref($value) eq 'ARRAY') { $value = ADN::Utility::dump_array($value); } $value = ADN::Utility::htmlchars(ADN::Utility::z2asc($value)); $value =~ s/[\t\r]//g; $tml->assign( MAKE_NAME => $key, MAKE_VALUE => $value ); $tml->parse(INPUT_ROW => $row); } } } sub value_sort { #// Utility::dump_array に渡す $char と同期をとる必要あり my ($num, $conf, $value, $query, $char) = @_; my $name = "NAME" . $num . "_SHOW"; $name = $conf->{$name}; my $type = "NAME" . $num . "_TYPE"; my $child = "NAME" . $num . "_CHILD"; my $add = ''; if ($value eq '') { return ($name, $value); } if ($conf->{$child}) { foreach my $key0 (split(/ /, $conf->{$child})) { my $value0 = $query->{form}->{$key0}; if (!defined $value0) { $value0 = ''; } $key0 =~ s/name//; my $join = "NAME" . $key0 . "_JOIN"; $add .= $conf->{$join} . $value0; } } if ($conf->{$type} eq "radio" || $conf->{$type} eq "checkbox" || $conf->{$type} eq "select") { $value = value_multi($num, $conf, $value, $char); } $value .= $add; return ($name, $value); } sub value_multi { my ($num, $conf, $value, $char) = @_; if ($value eq '') { return $value; } my $join = ', '; #// 複数選択時の表示上の結合文字列 my $value0 = ''; my @value = (); if (ref($value) eq 'ARRAY') { @value = @$value; } elsif (defined $char) { foreach (split(/$char/, $value)) { push(@value, $_); } } else { push(@value, $value); } foreach my $i (@value) { my $text = "NAME" . $num . "_TEXT" . $i; $value0 .= $join . $conf->{$text}; } $value = $value0; $value =~ s/^$join//; return $value; } sub value_check { my ($ecc, $title, $value, $conf, $must) = @_; my @conv = (); if ($must == 1) { unless ($value) { #// JavaScript off 対策 my $msg = $conf->{ALERT_VALUE_BLANK}; push(@conv, $msg); push(@conv, $conf->{$title}); return \@conv; } } #// 必須入力項目以外は、空であれば素通り #// 値のある時のみチェック if ($value && $conf->{$ecc} eq 'Mail') { my ($ref, $target) = ADN::Utility::mail_check($value); if (@$ref) { my @conv = (); foreach (@$ref) { my ($addr, $check) = split(/\t/); my $msg = ''; if ($check == 1) { $msg = $conf->{ALERT_MAIL_ADDRESS}; } if ($check == 2) { $msg = $conf->{ALERT_MAIL_MXCHECK}; } $msg = ADN::HTML::mkhtml_br('', $msg) . "($addr)"; push(@conv, $msg); } push(@conv, $conf->{$title}); return \@conv; } } if ($value && $conf->{$ecc} eq 'Tel') { unless ($value =~ /\-/) { my $msg = $conf->{ALERT_TEL_CHAR}; push(@conv, $msg); push(@conv, $conf->{$title}); return \@conv; } } if ($value && $conf->{$ecc} eq 'Zip') { unless ($value =~ /\d{3}\-\d{4}/) { my $msg = $conf->{ALERT_ZIP_CHAR}; push(@conv, $msg); push(@conv, $conf->{$title}); return \@conv; } } #// エラー検知なし return undef; } sub csv_add { my $conf = shift; my $item = ''; my $data = ADN::Utility::utime2date(time()); foreach (split/ /, $conf->{CSV_ITEM}) { my $item = "CSV" . $_ . "_ITEM"; $item = $conf->{$item}; $data .= "\t" . $ENV{$item}; } return $data; }