#!/usr/local/bin/perl #↑1行目にサーバへ設置されているPerlのパスを設定してください。 #不明な場合にはサーバ管理者へ問い合わせてください。 #(このスクリプトはPerl5で書かれています。) ## ## このファイルについて ## 「管理ページ実行ファイル」 ## #---------------------------------------------------------------------------# #初期設定ファイルini.cgiを要求 require( "./ini.cgi" ); #日本語変換ライブラリjcode.plを要求 require( "./lib/jcode.pl" ); #クッキー処理ライブラリap_cookie.plを要求 require( "./lib/ap_cookie.pl" ); #カレンダー処理ライブラリap_calender.plを要求 require( $LIB_DIR."/ap_calender.pl" ); #フォームデータ%in値のをshift_jisへ変換する &ch_jcode(); #表示レコード my @g_rows = (); #処理開始 &start(); ## 処理開始 ## @return void sub start { #モードで処理を振り分ける if( $in{'mode'} eq 'write1' ) { #記事追加1モード &check_admin_passw(); &do_write1(); } elsif( $in{'mode'} eq 'write2' ) { #記事追加2モード &check_admin_passw(); &do_write2(); } elsif( $in{'mode'} eq 'edit1' ) { #修正1モード &check_admin_passw(); &do_edit1(); } elsif( $in{'mode'} eq 'edit2' ) { #修正2モード &check_admin_passw(); &do_edit2(); } elsif( $in{'mode'} eq 'edit3' ) { #修正3モード &check_admin_passw(); &do_edit3(); } elsif( $in{'mode'} eq 'del1' ) { #削除1モード &check_admin_passw(); &do_del1(); } elsif( $in{'mode'} eq 'del2' ) { #削除2モード &check_admin_passw(); &do_del2(); } elsif( $in{'mode'} eq 'back' ) { #バックアップ/復旧モード &check_admin_passw(); require( "./lib/admin_back.pl" ); require( "./lib/ap_back.pl" ); &do_back(); } else { #認証モード &do_sertif(); } exit(0); } #---------------------------------------------------------------------------# ## レコード追加1 sub do_write1 { #日付けを取得 my ( $n_y, $n_m, $n_d ) = &get_date(); #クッキー発行 &set_admin_passw_cookie(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); print << "END_OF_DOC";
レコード追加
見出し
内容


内容の表\示オプション
年月日(半角数字)
年 - 月 -
END_OF_DOC #HTMLフッタ &print_footer(); return; } ## レコード追加2 sub do_write2 { #入力検査 if( $in{'headline'} eq "" ) { &error( '見出しを記入してください。' ); } if( $in{'content'} eq "" ) { &error( '内容を記入してください。' ); } if( $in{'y'} eq "" ) { &error( '年を記入してください。' ); } if( $in{'m'} eq "" ) { &error( '月を記入してください。' ); } if( $in{'d'} eq "" ) { &error( '日を記入してください。' ); } #日付けを検査 if( (($in{'y'} !~ /\d/) || ($in{'y'} =~ /\D/) ) || (($in{'m'} !~ /\d/) || ($in{'m'} =~ /\D/) ) || (($in{'d'} !~ /\d/) || ($in{'d'} =~ /\D/) ) || !( int $in{'y'} >= 1971 ) || !( int $in{'m'} >= 1 ) || !( int $in{'m'} <= 12 ) || !( int $in{'d'} >= 1 ) || !( int $in{'d'} <= 31 ) ) { &error( '年月日の書式が間違っています。確認してください。' ); } my $m_days = &ap_calender::getDays( $in{'y'}, $in{'m'} ); if( $in{'d'} > $m_days ) { &error( $in{'y'}.'年'.$in{'m'}.'月は、'.$m_days.'日までです。' ); } #記事を追加するファイル名を設定 my $dat_name = 'd_'.$in{'y'}.'_'.sprintf("%02d",$in{'m'}).'.cgi'; #ロック &lock(); my @rows = (); my $w_flag = undef; my $new_num = 1; #記事ファイルを開く if( !open( RECS, "<".$DATA_DIR.$dat_name ) ) { if( !-e($DATA_DIR.$dat_name) ) { #新規ファイル作成し追加 if( !open( RECS, ">".$DATA_DIR.$dat_name ) ) { &error( '記事ファイルアクセスエラー。' ); } &__write_newrec( $new_num ); close( RECS ); chmod( 0666, $DATA_DIR.$dat_name ); } else { &error( '記事ファイルアクセスエラー。' ); } #古いファイルを削除 } else { #上書きし記事追加 #全行を読む @rows = ; #同日の記事があるか検査し、 #記事番号を設定 for ( my $i = 0; $i < @rows; $i++ ) { if( $rows[$i] =~ /^$in{'d'}<>(.+)<>.+/ ) { if( int $1 >= $new_num ) { $new_num = int $1 + 1; } #2重投稿防止 &parse_rec( $rows[$i] ); if( ($in{'headline'} eq $rec{'headline'}) && ($in{'content'} eq $rec{'content'}) ) { &error( 'このレコードは書込み完了しています。', '確認してください。' ); } } } #記事ファイルを上書き if( !open( RECS, ">".$DATA_DIR.$dat_name ) ) { &error( '記事ファイルアクセスエラー。' ); } #print "Content-Type: text/plain\n\n ブレイクポイント\n"; #書き換え if( !$W_RULE ) { #上に追加 for ( my $i = 0; $i < @rows; $i++ ) { if( !$w_flag ) { &parse_rec( $rows[$i] ); if( $in{'d'} >= $rec{'d'} ) { &__write_newrec( $new_num ); $w_flag = 1; } } print RECS $rows[$i]; } } else { #下に追加 for ( my $i = 0; $i < @rows; $i++ ) { if( !$w_flag ) { &parse_rec( $rows[$i] ); if( $in{'d'} > $rec{'d'} ) { &__write_newrec( $new_num ); $w_flag = 1; } } print RECS $rows[$i]; } } if( !$w_flag ) { &__write_newrec( $new_num ); } #ファイルを閉じる close( RECS ); chmod( 0666, $DATA_DIR.$dat_name ); } wait(); #古いファイルを削除 #ファイル数を調べる my @data_files = &__read_datafilenames(); &__rm_olddatafiles( @data_files ); #ロック解除 &unlock(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); my $button = &get_button_tag( '続けて追加する', { "mode" => 'write1', "admin_passw" => $in{'admin_passw'} } ); print << "END_OF_DOC"; レコード追加完了しました。

$button

END_OF_DOC #HTMLフッタ &print_footer(); return; } sub __write_newrec { my( $new_num ) = @_; print RECS "$in{'d'}<>"; print RECS "$new_num<>"; print RECS "$in{'headline'}<>"; print RECS "$in{'content'}<>"; print RECS "$in{'auto_ret'}<>"; print RECS "$in{'tag'}<>"; print RECS "$in{'y'}/". sprintf("%02d",$in{'m'})."/". sprintf("%02d",$in{'d'})."<>" ; print RECS "\n"; return; } sub __read_datafilenames { my @files = (); if( !opendir( DIR, $DATA_DIR ) ) { &error( 'データディレクトリアクセスエラー。', $DATA_DIR.'のパーミッションを確認してください。' ); } my $file = ""; while( $file = readdir( DIR ) ) { if( ($file =~ /^\./ ) || #.隠しファイルなどを無視 ($file =~ /^Icon/) || #MacOSXアイコン対策 ($file !~ /^d_.+/) ) { next; } push @files, $file; } close( DIR ); #新しい順 @files = sort { $b cmp $a } @files; return @files; } ## 古いデータファイルを削除 sub __rm_olddatafiles { my( @files ) = @_; wait(); my $cnt = 0; for( my $i = 0; $i < @files; $i++ ) { $cnt++; if( $MAX_MONTH >= $cnt ) { next; } unlink( $DATA_DIR.$files[$i] ); } wait(); return; } ## レコード修正1 sub do_edit1 { #ロック &lock(); #ファイル数を調べる my @data_files = &__read_datafilenames(); #ファイルの日付けを設定 my @data_info = (); for( my $i = 0; $i < @data_files; $i++ ) { $data_info[$i] = substr( $data_files[$i], 2, 4 ).'年'. substr( $data_files[$i], 7, 2 ).'月' ; } #データファイルの情報 my $n_file_info = ''; if( @data_info == 0 ) { $n_file_info = '(現在、レコードは記録されていません。)'; $in{'datafile'} = ""; } else { if( !exists($in{'datafile'}) || ($in{'datafile'} eq "") ) { $in{'datafile'} = $data_files[0]; $n_file_info = '('.$data_info[0].')'; } else { for( my $i = 0; $i < @data_files; $i++ ) { if( $in{'datafile'} eq $data_files[$i] ) { $n_file_info = '('.$data_info[$i].')'; } } if( $n_file_info eq "" ) { &error( '現在、その月のレコードは存在しません。' ); } } } #データを読む if( $in{'datafile'} ne "" ) { if( open( REC, "<".$DATA_DIR.$in{'datafile'} ) ) { @g_rows = ; close(REC); } else { &error( '記事ファイルアクセスエラー。' ); } } #ロック解除 &unlock(); #クッキー発行 &set_admin_passw_cookie(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); print << "END_OF_DOC";
END_OF_DOC # for( my $i = 0; $i < @g_rows; $i++ ) { &parse_rec( $g_rows[$i] ); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } print << "END_OF_DOC";
レコード修正$n_file_info
選択 見出し 日付け
$rec{'headline'}$rec{'date'}

他の月のレコードを選択する場合はこちらから
END_OF_DOC #HTMLフッタ &print_footer(); return; } ## レコード修正2 sub do_edit2 { #入力検査 if( !exists( $in{'d_num'} ) || $in{'d_num'} eq "" ) { &error( 'レコードを選択してください。' ); } if( !exists( $in{'datafile'} ) || $in{'datafile'} eq "" ) { &error( 'そのリクエストは認識できません。' ); } #年月日、番号を解析 my $tg_y = substr( $in{'datafile'}, 2, 4 ); my $tg_m = substr( $in{'datafile'}, 7, 2 ); my( $tg_d, $tg_num ) = split( /_/, $in{'d_num'} ); #ロック &lock(); #記事ファイルを開く if( !open( RECS, "<".$DATA_DIR.$in{'datafile'} ) ) { &error( '記事ファイルアクセスエラー。' ); } #修正対象の記事を取る。 my $row = ""; my $check = undef; while( $row = readline( *RECS ) ) { if( $row =~ /^$tg_d<>$tg_num<>.*/ ) { $check = 1; last; } } if( !$check ) { &error( '指定のレコードが見つかりませんでした。' ); } #ファイルを閉じる close( RECS ); #ロック解除 &unlock(); #レコード解析 &parse_rec( $row ); $rec{'content'} =~ s/\t/\n/g; #タグ my @tag = ( "", "" ); $tag[$rec{'tag'}] = " selected"; #自動改行 my @auto_ret = ( "", "" ); $auto_ret[$rec{'auto_ret'}] = " selected"; #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); print << "END_OF_DOC";
レコード修正
見出し
内容


内容の表\示オプション
年月日:$tg_y\年 - $tg_m\月 - $tg_d\日
END_OF_DOC #HTMLフッタ &print_footer(); return; } ## レコード修正3 sub do_edit3 { #入力検査 if( !exists( $in{'datafile'} ) || $in{'datafile'} eq "" ) { &error( 'そのリクエストは認識できません。' ); } if( $in{'headline'} eq "" ) { &error( '見出しを記入してください。' ); } if( $in{'content'} eq "" ) { &error( '内容を記入してください。' ); } #ロック &lock(); #記事ファイルを開く if( !open( RECS, "<".$DATA_DIR.$in{'datafile'} ) ) { &error( '記事ファイルアクセスエラー。' ); } #全行を読む my @rows = ; #記事ファイルを上書き if( !open( RECS, ">".$DATA_DIR.$in{'datafile'} ) ) { &error( '記事ファイルアクセスエラー。' ); } #書き込む for( my $i = 0; $i < @rows; $i++ ) { if( $rows[$i] =~ /^$in{'d'}<>$in{'num'}<>/ ) { #修正レコード print RECS "$in{'d'}<>"; print RECS "$in{'num'}<>"; print RECS "$in{'headline'}<>"; print RECS "$in{'content'}<>"; print RECS "$in{'auto_ret'}<>"; print RECS "$in{'tag'}<>"; print RECS "$in{'date'}<>"; print RECS "\n"; next; } print RECS $rows[$i]; } #ファイルを閉じる close( RECS ); #ロック解除 &unlock(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); my $button = &get_button_tag( '続けて修正する', { "mode" => 'edit1', "datafile" => $in{'datafile'}, "no_cookie" => 1, "admin_passw" => $in{'admin_passw'} } ); print << "END_OF_DOC"; レコード修正しました。

$button

END_OF_DOC #HTMLフッタ &print_footer(); return; } ## レコード削除1 sub do_del1 { #ロック &lock(); #ファイル数を調べる my @data_files = &__read_datafilenames(); #ファイルの日付けを設定 my @data_info = (); for( my $i = 0; $i < @data_files; $i++ ) { $data_info[$i] = substr( $data_files[$i], 2, 4 ).'年'. substr( $data_files[$i], 7, 2 ).'月' ; } #データファイルの情報 my $n_file_info = ''; if( @data_info == 0 ) { $n_file_info = '(現在、レコードは記録されていません。)'; $in{'datafile'} = ""; } else { if( !exists($in{'datafile'}) || ($in{'datafile'} eq "") ) { $in{'datafile'} = $data_files[0]; $n_file_info = '('.$data_info[0].')'; } else { for( my $i = 0; $i < @data_files; $i++ ) { if( $in{'datafile'} eq $data_files[$i] ) { $n_file_info = '('.$data_info[$i].')'; } } if( $n_file_info eq "" ) { &error( '現在、その月のレコードは存在しません。' ); } } } #データを読む if( $in{'datafile'} ne "" ) { if( open( REC, "<".$DATA_DIR.$in{'datafile'} ) ) { @g_rows = ; close(REC); } else { &error( '記事ファイルアクセスエラー。' ); } } #ロック解除 &unlock(); #クッキー発行 &set_admin_passw_cookie(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); print << "END_OF_DOC";
END_OF_DOC # for( my $i = 0; $i < @g_rows; $i++ ) { &parse_rec( $g_rows[$i] ); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } print << "END_OF_DOC";
レコード削除$n_file_info
選択 見出し 日付け
$rec{'headline'}$rec{'date'}

他の月のレコードを選択する場合はこちらから
END_OF_DOC #HTMLフッタ &print_footer(); return; } ## レコード削除2 sub do_del2 { #入力検査 if( !exists( $in{'d_num'} ) || $in{'d_num'} eq "" ) { &error( 'レコードを選択してください。' ); } if( !exists( $in{'datafile'} ) || $in{'datafile'} eq "" ) { &error( 'そのリクエストは認識できません。' ); } #年月日、番号を解析 my $tg_y = substr( $in{'datafile'}, 2, 4 ); my $tg_m = substr( $in{'datafile'}, 7, 2 ); my( $tg_d, $tg_num ) = split( /_/, $in{'d_num'} ); #ロック &lock(); #記事ファイルを開く if( !open( RECS, "<".$DATA_DIR.$in{'datafile'} ) ) { &error( '記事ファイルアクセスエラー。' ); } #全行を読む my @rows = ; #記事ファイルを上書き if( !open( RECS, ">".$DATA_DIR.$in{'datafile'} ) ) { &error( '記事ファイルアクセスエラー。' ); } #削除レコード以外を書き込む my $rec_cnt = 0; for( my $i = 0; $i < @rows; $i++ ) { if( $rows[$i] =~ /^$tg_d<>$tg_num<>/ ) { next; } print RECS $rows[$i]; $rec_cnt++; } #ファイルを閉じる close( RECS ); wait(); #空になったら、ファイルを削除 if( $rec_cnt == 0 ) { unlink( $DATA_DIR.$in{'datafile'} ); wait(); } #ロック解除 &unlock(); #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); my $button = ""; if( $rec_cnt >= 1 ) { $button = &get_button_tag( '続けて削除する', { "mode" => 'del1', "data_file" => $in{'datafaile'}, "no_cookie" => '1', "admin_passw" => $in{'admin_passw'} } ); } print << "END_OF_DOC"; レコード削除しました。

$button

END_OF_DOC #HTMLフッタ &print_footer(); return; } ## 認証 sub do_sertif { #管理パスワードクッキー取得 my $admin_passw = &ap_cookie::get_cookie( $COOKIE_NAME.'admin_passw' ); my $cookie_check = ""; if( $admin_passw ne "" ) { $cookie_check = " checked"; } #バックアップ機能 my $back = ""; if( $BACK_MODULE ) { $back = ''; } #HTTPレスポンスヘッダとHTMLヘッダ &print_http_header(); &print_header(); print << "END_OF_DOC";
管理メニュー
実行モード
管理パスワード
管理パスワードをCookie保存
END_OF_DOC #HTMLフッタ &print_footer(); return; } #---------------------------------------------------------------------------# ## 管理パスワードを検査 ## @return void sub check_admin_passw { if( $in{'admin_passw'} ne $ADMIN_PASSW ) { &error( '管理パスワードが間違っています。' ); } return; } ## 管理パスワードクッキーを発行 ## @return void sub set_admin_passw_cookie { my $cookie_data = ""; #クッキー処理なし if( exists $in{'no_cookie'} ) { return; } #発行用クッキー文字列を作る if( $in{'cookie'} ) { #クッキーを作る $cookie_data = &ap_cookie::mk_cookie( $COOKIE_NAME.'admin_passw', $in{'admin_passw'}, $COOKIE_PATH, $COOKIE_EXP ); } else { #保存しない場合はクッキーを消すための文字列を作る $cookie_data = &ap_cookie::mk_cookie( $COOKIE_NAME.'admin_passw', "", $COOKIE_PATH, 0 ); } #発行 print "$cookie_data\n"; return; } ## この実行ファイルのHTTPレスポンスヘッダを出力 ## @return void sub print_http_header { #キャッシュ制御 print "Pragma: no-cache\n"; print "Cache-Control: no-cache\n"; print "Expires: -1\n"; #ロボット用 print "Robots: index,follow\n"; #コンテンツ形 print "Content-Type: text/html;charset=Shift_JIS\n\n"; return; } ## HTMLヘッダを出力 ## @return void sub print_header { my $style = $LIB_DOCS_ADDR.'style_admin.css'; print << "END_OF_DOC"; $TITLE - 管理用
$TITLE - 管理用
END_OF_DOC return; } ## HTMLフッタを出力 ## @return void sub print_footer { print "
\n"; print "\n"; print "

\n"; print ""; print "

\n"; if( $LISENCE ne 'REGISTERED' ) { print "
"; print ""; print "$THIS_NAME $VERSION"; print "
\n"; } print "\n"; print "\n"; return; } ## 管理ページ用のフォームボタンを返す ## @param hash_ref フォームボタンのパラメータ ## @return string フォームボタンタグ sub get_button_tag { my( $name, $bt_params ) = @_; my $ret = "
\n"; my $k = ""; my $v = ""; $ret .= "\n"; while( ($k, $v) = each %{$bt_params} ) { $ret .= "\n"; } $ret .= "\n"; $ret .= "
"; return $ret; } ## $ENV{'TZ'}に基づく日付を返す ## @param int タイムスタンプ ## @param string フォーマット ## @param [array_ref 曜日の配列](メモ:このファイルはsjis用) ## @return string フォーマットされた日付 ## フォーマットについて"%Y/%M/%D(%W) %G:%I:%S" ## %Y: 西暦 ## %M: 月 ## %D: 日 ## %W: 曜日 ## %G: 時間 ## %I: 分 ## %S: 秒 sub get_localdate { my( $time, $format, $week_array ) = @_; if( !defined( $time ) || $time eq "" ) { $time = time(); } my @week = ( "日", "月", "火", "水", "木", "金", "土" ); if( ref( $week_array ) eq 'ARRAY ') { @week = @{$week_array}; } my @tinfo = localtime( $time ); my $fstr = ""; my @farray = (); $format =~ s/%Y/sprintf("%04d",$tinfo[5] + 1900)/eg; $format =~ s/%M/sprintf("%02d",$tinfo[4] + 1)/eg; $format =~ s/%D/sprintf("%02d",$tinfo[3])/eg; $format =~ s/%W/$week[$tinfo[6]]/eg; $format =~ s/%G/sprintf("%02d",$tinfo[2])/eg; $format =~ s/%I/sprintf("%02d",$tinfo[1])/eg; $format =~ s/%S/sprintf("%02d",$tinfo[0])/eg; return $format; } ## 年と月を返す ## @param int タイムスタンプ ## @return int 4ケタの年 ## @return int 月 ## @return int 日 sub get_date { my( $time ) = @_; if( !defined( $time ) || $time eq "" ) { $time = time(); } my @tinfo = localtime( $time ); my $yaer = $tinfo[5] + 1900; my $month = $tinfo[4] + 1; my $day = $tinfo[3]; return $yaer, $month, $day; } 0;