#!/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
#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";
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
#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";
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 "\n";
}
print "\n";
print "\n";
return;
}
## 管理ページ用のフォームボタンを返す
## @param hash_ref フォームボタンのパラメータ
## @return string フォームボタンタグ
sub get_button_tag {
my( $name, $bt_params ) = @_;
my $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;