config root man

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
Upload File :
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;
}

Man Man