#! /usr/local/bin/perl require 'jcode.pl'; &main; #************************************************ # はじめにお読み下さい # #このプログラムは、メンバー登録用のCGIです。 # #■設置方法■ #1.CGI設置するディレクトリを作成し、パーミッションを777と設定する。 # さらにそのディレクトリ内にdataディレクトリを作成しパーミッションを777と設定する。 #2.member.cgi内のuser_setup関数、header関数、message関数、footer関数を # お好みに併せて編集する。 #3.member.cgi (744) # jcode.pl (744) # をFTPでサーバーにアップし、 # パーミッションを上記のように設定する。 #4.member.cgiにアクセスする。 # # #■メンテナンス方法■ #編集したい記事のpassフォームに、 #user_setup関数で設定した管理者パスワードを入力すると #編集画面に移ります。 # # #************************************************ #************************************************ # ユーザー設定 #************************************************ sub user_setup{ $op_pass = '0000'; #管理者用パスワード $main_title='常連一覧'; #メインタイトル $log_max = '30'; #一覧表示させる常連数の初期設定 @log_list =(10,30,50,100); #選択できる表示数のリスト $max_log_lines = '20'; #1ファイルに保存する人数 } #************************************************ # ヘッダー表示関数 # #ページのヘッダー部分に表示される部分です。 # #_HTML_と_HTML_との間に、 #普通にHTMLをお書き下さい。 #なお、user_setup関数で設定したように #$maintitle→メインタイトル #$cgi_file→このファイル名 #に変換されます。 #************************************************ sub header { if($_[0] ne ""){$main_title="$main_title $_[0]";} print "Content-type: text/html\n\n"; # HTMLの出力 ' 'の間に通常のHTML文を書けばよい print<<"_HTML_"; $main_title
[TOPへ] [常連一覧] [常連登録]
$main_title
_HTML_ } #************************************************ # トップページメッセージ # #常連一覧ページのトップに表示される部分です。 #ヘッダー部分に続いて表示されます。 # #************************************************ sub message { print<<"_HTML_";
私のページにようこそ。
ぜひこのページの常連になりたいという方は、お気軽に登録して下さい。


_HTML_ } #************************************************ # ログ表示関数 # #すべてのページのフッター部分に表示されます。 #このスクリプトの著作権表示は消さないで下さい。 # #************************************************ sub footer { # このスクリプトの著作権表示 print<<"_HTML_";
qqq members Ver1.00
_HTML_ } #************************************************ # メインプログラム #************************************************ sub main{ &setup; #初期設定 &user_setup; unless(-d "data"){mkdir("data",777);} # フォーム入力されたデータを$bufferに格納する # getかpostかによって取得方法が異なる if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } if ($buffer eq ""){ &header(); #ヘッダーhtml &message; &html; #ログ表示関数 }else { &buf_read; #バッファ読み込み関数 &time_set; #時間処理関数 if($FORM{'type'} eq 'new'){&header('-登録画面-');&input_form;} elsif($FORM{'art'} ne ""){&pass_check;&header('-編集画面-');&input_form;} elsif($FORM{'type'} eq 'write'){ &log_write; #ログ書き込み書き込み関数 &header();&message;&html; }else{ &header();&message;&html; } } &footer; } #************************************************ # 初期変数設定 #************************************************ sub setup{ $cgi_file ='member.cgi'; #このファイル名 $id = $ENV{'REMOTE_HOST'}; $log_head = 'mem'; #ログの頭文字 $log_foot = 'log'; #ログの拡張子 $log_dir = 'data'; $CH_S_NUM{$log_max}=' selected'; @ken_list=("未選択","北海道","青 森","岩 手","宮 城","秋 田","山 形","福 島","茨 城","栃 木","群 馬","埼 玉","千 葉","東 京","神奈川","新 潟","富 山","石 川","福 井","山 梨","長 野","岐 阜","静 岡","愛 知","三 重","滋 賀","京 都","大 阪","兵 庫","奈 良","和歌山","鳥 取","島 根","岡 山","広 島","山 口","香 川","徳 島","愛 媛","高 知","福 岡","佐 賀","長 崎","熊 本","大 分","宮 崎","鹿児島","沖 縄"); } #************************************************ # ログ表示関数 #************************************************ sub input_form { # HTMLの出力 ' 'の間に通常のHTML文を書けばよい local($ken_form,$i)=("'; if($FORM{'art'} ne ""){ $FORM{'art'} = "削除$user_pass"; $FORM{'date'}= ""; $FORM{'value'}=~ s/
/\r/g; } print<<"_HTML_";
常連情報を記入し送信ボタンを押してください。
公開したくない情報は記入しなくても結構\です。(名前とパスワードは必須です)

$FORM{'date'}$FORM{'art'}
お名前(必須)
メール
ホームページ
住所$ken_form
会社学校名、職種等
パスワード(必須)←お客様がご自分で、編集、削除するのに必要です。
コメント


■■■■■■ヘルプ■■■■■■
パスワードは、内容を更新するときに利用します。
忘れないようにしてください。
表\示される順番は、更新された順に表\示されます。
上位に表\示されたい方は、こまめに更新してください
_HTML_ } #************************************************ # パスワードチェック関数 #************************************************ sub pass_check { &get_log; local($flag)=0; foreach(@lines){ local($date,$update,$art,$name,$email,$url,$value,$pass,$work,$ken,$id) = split(/\t/,$_); if($art eq $FORM{'art'}){ if(($pass ne $FORM{'pass'})&&($FORM{'pass'} ne $op_pass)){ &header('パスワードエラー'); print '

おしらせ

不正なパスワードです。

'; &html;&footer;exit; } $FORM{'name'}=$name; $FORM{'date'}=$date; $FORM{'email'}=$email; $FORM{'url'}=$url; $FORM{'value'}=$value; $FORM{'work'}=$work; $ken_ch{$ken}=" selected"; if($FORM{'pass'} eq $op_pass){$FORM{'pass'}=$pass;$user_pass="pasword=$pass";} $flag=1;last; } }if($flag ne 1){ &header('エラー'); print '

おしらせ

記事が見つけられませんでした。

'; &html;&footer;exit; } } #************************************************ # 検索結果表示関数 #************************************************ sub sort_form { $FORM_CH{$log_max}=' selected'; print<<"_HTML_"; _HTML_ if ($view{'last_end'} ne ""){ print "\n"; } if ($view{'next_start'} ne ""){ print "\n"; } print'
番号順
\n"; print "\n"; print "\n"; print "\n"; print ""; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "

'; } #************************************************ # 検索結果表示関数 # @linesに全ログが入っている。ソート後@linehitに入れ直す。 #************************************************ sub sort_log { foreach(@lines){ local($date,$update,$art,$name,$email,$url,$value,$pass,$work,$ken,$id) = split(/\t/,$_); $id_test=4-length($art); $id_test='0' x $id_test; $dumy="$name\t$email\t$url\$value\$work\$ken_list[$ken]\t$id_test$art"; if($dumy =~ /$FORM{'s_val'}/){push(@linehit,$_);$SORT_LOG{$_}=$update;} } if($FORM{'s_type'} eq ""){ @linehit=(); foreach(sort{$SORT_LOG{$b}<=>$SORT_LOG{$a}}keys %SORT_LOG){ push(@linehit,$_); } } } #************************************************ # ログ表示関数 #************************************************ sub html { @test=&active_log; &get_log; $logall = @lines; &sort_log; #@linehitに全ログを入れる。 $loghit=@linehit; %view=&log_limit($logall,$loghit,$FORM{'article'},$log_max); &sort_form; if($FORM{'s_type'} eq ""){ print'【更新記事順】'; }else{print'【番号順】';} if($FORM{'s_num'} eq 'all'){$sort_num2='全件表\示';} else{$sort_num2="最大表\示件数$log_max件";} print "$sort_num2。
"; print "総常連数$view{'all'}人 検索結果$view{'hit'}人 $view{'start'}〜$view{'end'}件表\示
\n"; print"
\n"; print "登録内容の変更は、passに登録したパスワードを入力すれば、編集画面に移ります。
どうしてもパスワードが解らない方はメールください。
\n"; ###記事一覧処理### ###配列<@lines>から1件ずつデータを取り出して処理する### $i = 1; print"


"; foreach $line (@linehit) { if ($i>=$view{'start'}){ local($date,$update,$art,$name,$email,$url,$value,$pass,$work,$ken,$id) = split(/\t/,$line); local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($update+9*60*60); $year=$year+1900; if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } $mon++; $update="$year\/$mon\/$mday\[$hour\'$min"$sec\]"; $dumy=4-length($art); $dumy='0' x $dumy; $id_num="$dumy$art"; if ($email ne ""){ $email=" [E-MAIL]";} if ($url ne ""){$url=" [Home Page]";} print<<"_HTML_";
ID[$id_num]
名前(Home Page等)$name$email$url
登録日$date
住所$ken_list[$ken]
職種、会社学校名$work
コメント$value
最終更新$update
_HTML_ } $i++; if($i>$view{'end'}) { last; } } &sort_form; } #************************************************ # プレビュー表示関数 #************************************************ sub preview { # HTMLの出力 ' 'の間に通常のHTML文を書けばよい $FORM{'value'} =~ s/\r/
/g; print"
【プレビュー表\示】

"; local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time+9*60*60); $year=$year+1900; if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } $update="$year\/$mon\/$day\[$hour\'$min"sec\]"; if ($FORM{'email'} ne ""){ $FORM{'email'}=" E-MAIL";} if ($FORM{'url'} ne ""){$FORM{'url'}=" Home Page";} print<<"_HTML_"; $FORM{'work'}
名前(Home Page等):$FORM{'name'}$FORM{'email'}$FORM{'url'}登録日:$date_now
住所:$ken_list{$FORM{'ken'}}職種、会社学校名
コメント:
$FORM{'value'}
$update
_HTML_ } #************************************************ # バッファを変数に読み込む #************************************************ sub buf_read { @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; #$value =~ s/%0D%0A/
/g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/\n//g; $value =~ s/^//g; # 掲示板に書き込まれたくないタグが含まれる行を消去する # ここでは、200){&error(3);} if($FORM{'pass'} eq ''){&error(4);} } if($FORM{'s_type'} ne ''){$FORM{'ch_s_type'}=' checked';} if($FORM{'s_num'} ne ''){$log_max=$FORM{'s_num'};undef %CH_S_NUM;$CH_S_NUM{$FORM{s_num}}=' selected';} } #************************************************ # ログ書き込み #************************************************ sub log_write{ $FORM{'value'} =~ s/\r/
/g; if($FORM{'re_art'} ne ""){ local(@files)=&dir_list($log_head,$log_foot,$log_dir); foreach $file(@files){ open(DB,"$log_dir/$log_head$file\.$log_foot"); local(@lines) = ;close(DB); @write_log=(); foreach(@lines){ $_=~ s/\n//g; if($_ eq ''){last;} local($date,$update,$art,$name,$email,$url,$value,$pass,$work,$ken,$id) = split(/\t/,$_); if($FORM{'re_art'} eq $art){ if($FORM{'del'} eq ""){ $value =join("\t",$FORM{date},$ttime,$FORM{'re_art'},$FORM{'name'},$FORM{'email'},$FORM{'url'},$FORM{'value'},$FORM{'pass'},$FORM{'work'},$FORM{'ken'},$id,"\n"); push(@write_log,$value); } $flag=1; }else{push(@write_log,"$_\n");} } if($flag eq 1){ open(DB,">$log_dir/$log_head$file.$log_foot");print DB @write_log;close(DB); last; } } if($flag ne 1){ &header('エラー'); print '

おしらせ

記事が見つけられませんでした。

'; &html;&footer;exit; } }else{ # 記録ファイルを読み出しオープンして、配列<@lines>に格納する local($file,$num)=&active_log; open(DB,"$log_dir/$log_head$file\.$log_foot"); local(@lines) = ;close(DB); $value =join("\t",$date_now,$ttime,$num,$FORM{'name'},$FORM{'email'},$FORM{'url'},$FORM{'value'},$FORM{'pass'},$FORM{'work'},$FORM{'ken'},$id,"\n"); push(@lines,$value); # 記録ファイルを上書きオープンして、配列<@new>を書き出す open(DB,">$log_dir/$log_head$file.$log_foot"); print DB @lines;close(DB); chmod 0666,"$log_dir/$log_head$file.$log_foot"; } } #************************************************ # ディレクトリ内ファイルリスト # &dir_list($kakuchou) # @listの各要素を文字列$sepaleteで分割し # $pal番目のキーで@listをソートする。 # $return :逆順ソート # $str :1=辞書的にソート,他=数的にソート #************************************************ sub dir_list{ local($list,@files,$file,@newfiles); local($head,$kakuchou,$dir)=@_; if (!opendir(DIR,$dir)) { &error(0); } @list = readdir(DIR); foreach $file(@list) { next if -d $file; if ($file=~ /$head(\d+)\.$kakuchou/) { push(@files,"$1"); } } close(DIR); @files=sort{$a <=> $b}@files; return @files; } #************************************************ # 全ログの読み込み #************************************************ sub get_log{ @lines=(); local(@file_list,@log_list,$line); @file_list=&dir_list($log_head,$log_foot,$log_dir); foreach(@file_list){ open(DB,"$log_dir/$log_head$_\.$log_foot"); @log_list = ; close(DB); unshift(@lines,reverse(@log_list)); } } #************************************************ # アクティブログファイル #************************************************ sub active_log{ local(@file_list,@log_list,$max,$maxfile,$num,@lines,@return); @file_list=&dir_list($log_head,$log_foot,$log_dir); $max=0;$maxfile=0; foreach $file(@file_list){ open(DB,"$log_dir/$log_head$file\.$log_foot"); @lines=;close(DB); $num=@lines; foreach(@lines){ local($date,$update,$art,$name,$email,$url,$value,$pass,$work,$ken,$id) = split(/\t/,$_); if($max < $art){$max=$art;} if($maxfile < $file){$maxfile=$file;} } } if($num >= $max_log_lines){return ($maxfile+1,$max+1);} else{return ($maxfile,$max+1);} } #************************************************ # 記事表示数処理 # log_limit($all,$hit,$start,$num) #************************************************ sub log_limit{ local($all,$hit,$start,$num,$list); @list=(); local($all,$hit,$start,$num)=@_; $list{'all'}=$all; if($hit>=1){ $list{'hit'}=$hit; if($num eq "all"){$num=$hit;$list{'num'}="all";} elsif($num<1){$num=1;$list{'num'}=$num;} else{$list{'num'}=$num;} if(($hit<$start)||($start<1)){$start=1;} $list{'start'}=$start; if($hit<$start+$num-1){$list{'end'}=$hit+0;} else{$list{'end'}=$start+$num-1;} if($list{'start'}>1){ $list{'last_end'}=$list{'start'}-1; if($list{'start'}-$num>0){$list{'last_start'}=$list{'start'}-$num;} else{$list{'last_start'}=1;} } if($hit>$list{'end'}){ $list{'next_start'}=$list{'end'}+1; if($hit>=$list{'next_start'}+$num-1){$list{'next_end'}=$list{'next_start'}+$num-1;} else{$list{'next_end'}=$hit;} } }else{$list{'hit'}=0;$list{'end'}=0;$list{'start'}=0;} return %list; } #************************************************ # 時間表示処理 #************************************************ sub time_set{ # 海外サーバ等で時差が生じる場合は修正します # 海外時間に+9時間する場合 = localtime(time + 9*60*60); # 海外時間に−9時間する場合 = localtime(time - 9*60*60); # (参考)timeには1970年からの秒数が入っています ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time+9*60*60); # 時分秒を2桁に統一する処理 if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } # 上記の$monには0から11までの数字が入るので修正処理 $month = ($mon + 1); # 曜日変換処理 # $wdayには0から6までの数字が入り曜日に対応している $y0="日"; $y1="月"; $y2="火"; $y3="水"; $y4="木"; $y5="金"; $y6="土"; $youbi = ($y0,$y1,$y2,$y3,$y4,$y5,$y6) [$wday]; $year=$year+1900; # 時刻フォーマット $date_now = "$year\/$month\/$mday\[$hour\'$min"$sec\]"; $ttime=time; } #************************************************ # エラー表示 #************************************************ sub error { $error = $_[0]; if ($error eq "0") { &header('エラー'); print '

おしらせ

記録ファイルの入出力にエラーが発生しました。

'; }elsif ($error eq "1") { &header('書き込みエラー'); print '

おしらせ

名前が記入されていません。

'; &input_form; }elsif ($error eq "2") { &header('書き込みエラー'); print '

おしらせ

コメントが書かれていません。または記録禁止のタグが書かれています。

'; &input_form; }elsif ($error eq "3") { &header('書き込みエラー'); print '

おしらせ

コメントが長すぎます。全角文字で100文字以内です。

'; &input_form; }elsif ($error eq "4") { &header('書き込みエラー'); print '

おしらせ

パスワードが記入されていません。

'; &input_form; }elsif ($error eq "5") { &header('書き込みエラー'); print '

おしらせ

不正なメールアドレスです。

'; &input_form; }elsif ($error eq "6") { &header('書き込みエラー'); print '

おしらせ

不正なURLです。

'; &input_form; }else { &header('エラー'); print '

おしらせ

処理に何らかのエラーが発生し作業は中止されました。

'; } &footer; exit; }