#!/usr/local/bin/perl # sendmail CGI # version 0.0 2001/12/01 # # program by Timeplant/Ituki Kirihara/NI # ITUKI over TCP : http://fc.to/ituki/ # Mail to: ituki@fc.to # # (c) Copyright 2001 Timeplant/Ituki Kirihara/NI All rights reserved. # ## ----------------------------- ## 環境に応じて変更して下さい ## ----------------------------- # 漢字ライブラリ(jcode.pl)のファイル名(必要に応じて変更して下さい) $jcode_pl = './jcode.pl'; #このファイルの漢字コード('euc' 'sjis' 'jis'のどれかが指定可能。) $cgicode = 'sjis'; # 出力文字コード $kanjicode = $cgicode; ## ------------------------------------------ ## 意味の分かっている人しか変更しないで下さい ## ------------------------------------------- &Init; &From_dec; #------------------------------------------------------------------------ # これ以下で使える変数の解説(内容のチェックはされていないので注意) # $ENV{'(名前)'} # 環境変数(例) # $ENV{'REMOTE_ADDR'} 相手のIPアドレス # $ENV{'REMOTE_HOST'} 相手のホスト名 # $ENV{'HTTP_REFERER'} (ほとんどの場合)投稿元アドレス # $ENV{'HTTP_USER_AGENT'} (ほとんどの場合)相手のブラウザの名前 # $form{'(名前)'} # フォームでname="(名前)"で指定したデータの値 # &env_data() # すべての環境変数を(名前)=(値)\nで繋いだ物 # &form_data() # すべてのフォームデータを(名前)=(値)\nで繋いだ物 # $year $mon $mday $hour $min $sec # それぞれ、CGIが起動された 年 月 日 時間 分 秒 # $wday $wdy $mody $times # それぞれ、CGIが起動された # 曜日(0=日曜,6=土曜) 曜日(英語表記) 月(英語表記) 時間(time戻り値) #------------------------------------------------------------------------ ## ----------------------- ## 必ず変更して下さい ## ----------------------- # メール送り先アドレス $send_address = 'ituki@fc.to'; # メール送り元アドレス $from_address = 'ituki@fc.to'; # メール送信後に出力するデータ $location_address =<<_EOF_LOCATION_ADDRESS; Location: http://fc.to/ituki/ _EOF_LOCATION_ADDRESS # 送信を許可するURLの正規表現 @reffer_address=('^http\:\/\/fc\.to\/ituki\/index\.html$'); ## ----------------------------- ## 環境・用途に応じて変更して下さい ## ----------------------------- # sendmailの場所 $sendmail = '/usr/sbin/sendmail'; # sendmailのオプション $sendmail_option = '-t'; # To:を自力で出力するか する:1(デフォルト) しない:0 $to_header_addr = 1; # HTTP_REFERERが空のとき許可するかしないか する:1 しない:0 $enable_blank_reffer = 1; # 送られてくるデータで必須のものの中で、一致しなければならない正規表現(空にしておくと、チェックされない) $indis_rexp{'sex'} = '^(w|m)$'; $indis_rexp{'name'} = '.+'; $indis_rexp{'mail'} = '^[A-Za-z0-9]([A-Za-z0-9\.\-\_]*)\@([A-Za-z0-9]([A-Za-z0-9\-\_]*)\.)+[A-Za-z0-9]([A-Za-z0-9\.\-\_]*)$'; $indis_rexp{'message'} = '.+'; # 参照名($indis_rexp_name) $indis_rexp_name{'sex'} = '性別'; $indis_rexp_name{'name'} = '名前'; $indis_rexp_name{'mail'} = 'メールアドレス(半角)'; $indis_rexp_name{'message'} = 'ご質問内容'; # 送られてくるデータで必須のものが一致しなかったときに表示するデータ # は、存在しなかった必須データのフォーム名を表す # は、存在しなかった$indis_rexp_name{必須データフォーム名}で変換されたデータを表す $indis_rexp_error_data =<<_EOF_INDIS_REXP_ERROR_DATA; Content-type: text/html $contenttype ) -->の内容が記述されていないか、不正な内容です。 _EOF_INDIS_REXP_ERROR_DATA # 送信されるメール if($form{'sex'} eq 'w'){ $form_dec{'sex'} = '女';}else{$form{'sex'} = '男';} $mail_body =<<_EOF_MAIL_BODY; MIME-Version: 1.0 Content-type: text/plain; charset=ISO-2022-JP From: $from_address Subject: [Webform] $year/$mon/$mday $hour:$min:$sec --------- 名前: $form{'name'} 性別: $form_dec{'sex'} メールアドレス: $form{'mail'} 内容 $form{'message'} --------- _EOF_MAIL_BODY # メールの送信に失敗したときに出力する内容 $sendmail_error =<<_EOF_SENDMAIL_ERROR; Content-type: text/html $contenttype メールの送信に失敗しました。 _EOF_SENDMAIL_ERROR # 規定外の場所からメールを送信しようとしたとき $reffer_error =<<_EOF_SENDMAIL_ERROR; Content-type: text/html $contenttype 規定外のフォームからの送信はできません。 _EOF_SENDMAIL_ERROR ## ----------------------------- ## (これ以下の値を変更することによって生じるリスクを覚悟の上で) ## 必要に応じて変更して下さい ## ----------------------------- # すべての環境変数を追加するかどうか(メインのアドレス) する:1(標準) しない:0 $add_env = 1; # フォームから入力されたアドレスにメールを送信するか しない:空 する:内容 $form_address_sendmail_data =<<_EOF_FORM_ADDRESS_SENDMAIL_DATA; _EOF_FORM_ADDRESS_SENDMAIL_DATA # そのフォームの名前 $form_address_sendmail_name = 'mail'; # そのときもすべての環境変数を追加するかどうか する:1 しない:0(標準) $form_address_sendmail_add_env = 0; # sendmailを呼び出す際、送り先(To:)をコマンドラインで渡すか 渡さない:0(標準) 渡す:1 $sendmail_call_to_address_Commandline = 0;#渡さなければ正常動作しないとき以外は渡さないで下さい &Main; ## -------------------------------------------------------- ## ここから先は、意味の分かっている人しか変更しないで下さい ## -------------------------------------------------------- sub check_all_error{ local($key,$tmp); ($key) = @_; $tmp = $indis_rexp_error_data; $tmp =~ s//$key/g; $tmp =~ s//$indis_rexp_name{$key}/g; &error_this($tmp); } sub check_all{ # check all local($f,$tmp); # reffer_check if($ENV{'HTTP_REFERER'} eq ''){ if($enable_blank_reffer == 0){&error_this();} }else{ $f = 0; foreach $ref(@reffer_address){ if($ENV{'HTTP_REFERER'} =~ /$ref/){$f = 1;} } if($f != 1){&error_this($reffer_error);} } # indis_rexp check foreach $key(%indis_rexp){ if($form{$key} !~ /$indis_rexp{$key}/){ &check_all_error($key); } } # チェック追加 # 上記チェックに追加 } sub Main{ # main local($env_data); &check_all; $env_data = ''; if($add_env != 0 or $form_address_sendmail_add_env != 0){ $env_data = &env_data(); }else{ $env_data = ''; } if($add_env == 0){ &Send_mail($send_address,$mail_body);} else { &Send_mail($send_address,$mail_body . "\n" . $env_data);} if($form_address_sendmail_data ne '' and $form{$form_address_sendmail_name} ne ''){ if($form_address_sendmail_add_env == 0){ &Send_mail($form{$form_address_sendmail_name},$form_address_sendmail_data);} else { &Send_mail($form{$form_address_sendmail_name},$form_address_sendmail_data . "\n" . $env_data);} } print $location_address; print "\n\n"; } sub Init{ # initialize local($tmp); require $jcode_pl; $times = time; ($sec,$min,$hour,$mday,$mon,$year,$wday,$wdy,$mody) = &time_to($times); $contenttype = ''; if($kanjicode eq 'euc'){ $contenttype = ''; } if($kanjicode eq 'sjis'){ $contenttype = ''; } if($kanjicode eq 'jis'){ $contenttype = ''; } # IPv4 if($ENV{'REMOTE_ADDR'} !~ /^([0-9]{1,3}\.){3}([0-9]{1,3})$/){&error_this(); } $tmp = gethostbyaddr(pack("C4", split(/\./, $ENV{'REMOTE_ADDR'})), 2); if($ENV{'REMOTE_HOST'} ne $tmp){ $ENV{'REMOTE_HOST'} = $tmp; } if($ENV{'REMOTE_HOST'} eq ''){ $ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'}; } } sub From_dec{ local($query,@assocarray,$assoc,$property,$value,$method); $method = $ENV{'REQUEST_METHOD'}; $method =~ tr/A-Z/a-z/; if($method eq 'post'){ read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } else { $query = $ENV{'QUERY_STRING'}; } @assocarray = split(/&/,$query); foreach $assoc (@assocarray){ ($property,$value) = split(/=/, $assoc); $value =~ tr/+/ /; $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; &jcode'convert(*value, $cgicode); if($form{$property} eq ''){ $form{$property} = $value; }elsif($value ne ''){ $form{$property} .= $value; } } } sub Send_mail{ local($to,$data,*MAIL); ($to,$data) = @_; if($to !~ /^[A-Za-z0-9]([A-Za-z0-9\.\-\_]*)\@([A-Za-z0-9]([A-Za-z0-9\-\_]*)\.)+[A-Za-z0-9]([A-Za-z0-9\.\-\_]*)$/){ &error_this();} if($sendmail !~ /^(\/[A-Za-z0-9]+)+$/){&error_this();} if($sendmail_option !~ /^[A-Za-z0-9\-]*$/){&error_this();} if($cgicode ne 'jis'){ &jcode'convert(*data, $cgicode,'jis'); } if($sendmail_call_to_address_Commandline == 1){ if(open(MAIL,"| $sendmail '$sendmail_option' '$to'")){ }else{ &error_this($sendmail_error); } }else{ if(open(MAIL,"| $sendmail '$sendmail_option'")){ }else{ &error_this($sendmail_error); } } if($to_header_addr != 0){ print MAIL "To: $to\n"; } print MAIL "X-Mailer: sendmail.cgi ver 0.0 program by Timeplant/Ituki Kirihara/NI(http://fc.to/ituki/)\n"; print MAIL "X-Sender-IP: $ENV{'REMOTE_ADDR'}\n"; print MAIL $data; print MAIL "\n\n"; close(MAIL); } sub error_this{ local($error_str) = @_; if($error_str eq ''){ # 内部でエラーが起きたときに出力する内容 $error_str =<<_EOF_LOCAL_ERROR; Content-type: text/html $contenttype 内部エラーです。 管理者に報告をお願いします。 _EOF_LOCAL_ERROR } if($cgicode ne $kanjicode){ &jcode'convert(*error_str, $cgicode,$kanjicode); } print $error_str; print "\n\n"; exit(0); } sub time_to{ local($time,$sec,$min,$hour,$mday,$mon,$year,$wday,$wdy,$mody); ($time) = @_; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($time); if($sec<10) {$sec = "0$sec"}; if($min<10) {$min = "0$min"}; if($hour<10) {$hour = "0$hour"}; if($mday<10) {$mday = "0$mday"}; $mon = $mon + 1; if($mon<10) {$mon = "0$mon"}; $year=1900+$year; $wdy = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$wday]; $mody = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mon-1]; return ($sec,$min,$hour,$mday,$mon,$year,$wday,$wdy,$mody); } sub env_data{ # &env_data('=',"\n"が標準) local($ret,$serf,$net); ($serf,$net) = @_; if($serf eq ''){$serf = ' = ';} if($net eq ''){$net = "\n";} $ret = ''; foreach $key(sort keys %ENV){ $ret .= $key . $serf . $ENV{$key} . $net; } return $ret; } sub form_data{ # &form_data('=',"\n"が標準) local($ret,$serf,$net); ($serf,$net) = @_; if($serf eq ''){$serf = ' = ';} if($net eq ''){$net = "\n";} $ret = ''; foreach $key(sort keys %form){ $ret .= $key . $serf . $form{$key} . $net; } return $ret; }