#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################
#!/usr/local/bin/perl
#【 名 称 】空室状況カレンダー ver.1.6
#【 説 明 】空室状況をカレンダー形式で表示する。
#【 file 名 】yoyaku.lzh
#【 作 者 】hige hige@deneb.freemail.ne.jp
#【 作者HP 】CGIのかんづめ http://www.dab.hi-ho.ne.jp/appletea/cgikan/
#【 動作環境 】Perl5
#【 library 】jcode.plが必要
#【 作成月日 】2001/02/07
#【 種 別 】フリーソフトウェア
#【 著 作 権 】著作権はhigeが保有します。
#【 転載条件 】禁止
################################################################################
#
# 外部ライブラリ:パスは場合によって変更
#
################################################################################
require './jcode.pl';
################################################################################
#
# 必ず変更する設定
#
################################################################################
#HOME(空室状況から戻るときの頁)
$home = "http://koredesune.com";
#管理パスワード
$pwd = 'tokubei';
################################################################################
#
# 場合によって変更する設定:デザイン
#
################################################################################
####################################################################
# 標準カレンダー用の設定 (disptype=0/disptype指定なしの場合のみ必要)
#カレンダーの幅(%指定する場合は type 1 を参考に設定してください
#$calwidth = "100%" #type 1
#$calwidth = 400; #type 2
$calwidth = 475;
####################################################################
# 横長カレンダー用の設定 (disptype=1/2の場合のみ必要)
#1日の列幅
$colwidth_day = 20;
#列名表示の列幅
$colwidth_rowtitle = 90;
####################################################################
# 共通設定
#1日の状態の数(例えば午前と午後を別々に管理するとき->2)
#$periods = 1;
$periods = 1;
#1日の状態の数が複数のときにそれを識別するための文字列が必要か?
#$showpname = 0;
$showpname = 0;
#1日の状態の数が複数のときにそれを識別するための文字列
#($showpname = 0 の時は設定不要)
#$periodname[0] = '午前';
#$periodname[0] = '午後';
#背景色
$bgcolor = "#FFFFFF";
#カレンダーの月部分
$caltitle_color = "#FFCC33";
#平日の色
$col[1] = "#FFFFFF";
$col[2] = "#FFFFFF";
$col[3] = "#FFFFFF";
$col[4] = "#FFFFFF";
$col[5] = "#FFFFFF";
#土曜日の色
$col[6] = "#CCCCFF";
#日曜日の色
$col[0] = "#FFCCCC";
#祝日の色
$col[7] = "#FFCCCC";
#更新日時のデフォルト書式
#書式の中の特定の文字が年、月、日、時、分、秒と置き換わります
#指定可能な書式は下記の通りです。意味は推測してください。(^^;
# 年:YYYY,YY | 月:MM,M | 日:DD,D | 時:hh,h | 分:mm,m | 秒:ss,s
$updtime_format = "YYYY.MM.DD"; # ex. 2001.07.07
#$updtime_format = "YY/M/D"; # ex. 01/7/7
#$updtime_format = "YY/M/D hh:mm"; # ex. 01/7/7 01:15
#今日以降の空室状況のデフォルト値
$default_stat = 1;
################################################################################
#
# 場合によって変更する設定:その他
#
################################################################################
# OSの文字コード (euc / sjis)
$os_code = 'euc';
# 出力コード (euc / sjis)
$output_code = 'sjis';
#データファイル
$datafile = "./yoyaku/yoyaku.txt";
#文字列ファイル
$strfile = "./yoyaku/yoyakustr.txt";
#祝日ファイル
$holidayfile = "./yoyaku/holiday.txt";
#ロック用のディレクトリ名
$lockdir = "./yoyaku/yoyakulock";
#更新日記録ファイル
$updfile = './yoyaku/upddate.txt';
################################################################################
# 変更不可の設定
$self = $ENV{'SCRIPT_NAME'};
#曜日文字列
@wdaystr= ('日', '月', '火', '水', '木', '金', '土');
#日数
@days_leap = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@days_normal = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
################################################################################
#
# 実行開始
#
################################################################################
#実行開始
&main;
exit;
################################################################################
#
# メイン
#
################################################################################
#メイン関数
sub main
{
#フォームデータのデコード
&form_decode;
# 出力文字セットを決定
if ($output_code eq 'sjis')
{
$charset = 'Shift_JIS';
}
elsif ($output_code eq 'euc')
{
$charset = 'euc-jp';
}
#横長カレンダー対応のためカレンダー幅をここで調整
if ($FORM{'disptype'} == 1) {
$calwidth = $colwidth_day * 31 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 32 * 1 * 2 # 32セル * 1dot * 左右
+ 33 * 2; # 33本 * 2dot
} elsif ($FORM{'disptype'} == 2) {
$calwidth = $colwidth_day * 16 + $colwidth_rowtitle;
#微調整(テーブルの線幅、セルの隙間などの分を余計にとる)
$calwidth = $calwidth
+ 17 * 1 * 2 # 17セル * 1dot * 左右
+ 18 * 2; # 18本 * 2dot
}
#処理分岐
if ($FORM{'mode'} eq 'show') {
&show;
} elsif ($FORM{'mode'} eq 'edit') {
&edit;
} elsif ($FORM{'mode'} eq 'save') {
&save;
} elsif ($FORM{'mode'} eq 'editstr') {
&editstr;
} elsif ($FORM{'mode'} eq 'savestr') {
&savestr;
} elsif ($FORM{'mode'} eq 'mng') {
&mng;
} elsif ($FORM{'mode'} eq 'ssishow') {
&ssishow;
} elsif ($FORM{'mode'} eq '') {
&mng;
} elsif ($FORM{'mode'} eq 'updtime') {
&updtime;
} else {
&error("CGIに渡されたパラメータが不正です。");
}
}
################################################################################
#
# 汎用的な関数
#
################################################################################
#フォームデータのデコード
sub form_decode
{
local($form);
local(@pairs);
local($name, $value);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $form, $ENV{'CONTENT_LENGTH'});
} else {
$form = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$form);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/>/>/g;
$value =~ s/</g;
&jcode'convert(*value, 'euc');
&jcode'convert(*name, 'euc');
$FORM{$name} = $value;
}
}
#HTML出力
sub print_html
{
local($html) = @_;
&jcode'convert(*html, $output_code);
print "Content-type: text/html\n\n";
print $html;
}
#うるう年判定
sub is_leap_year
{
local($year) = @_;
if ($year % 4 != 0) {
return 0;
} elsif ($year % 100 != 0) {
return 1;
} elsif ($year % 400 != 0) {
return 0;
} elsif ($year % 4000 != 0) {
return 1;
} else {
return 0;
}
}
#指定月の日数を取得
sub get_days
{
local($year, $month) = @_;
local($is_leap);
#うるう年か?
$is_leap = is_leap_year($year, $month);
#日数を返す
if ($is_leap) {
return $days_leap[$month];
} else {
return $days_normal[$month];
}
}
#指定日の曜日を取得
sub get_wday
{
local($year, $month, $day, $wday) = @_;
if ($month <= 2) {
$year--;
$month += 12;
}
$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13*$month + 8)/5) + $day) % 7;
return $wday;
}
#ロック
sub lock
{
local($lockdir) = @_;
local($pre_time, $timeflag, $i, $rc);
($pre_time) = (stat($lockdir))[9];
$timeflag = time() - $pre_time;
$i=1;
while(1) {
if (mkdir("$lockdir", 0755)) {
$rc = 1;
last;
}
if ($i == 1) {
if ($timeflag > 300) {
rmdir($lockdir);
}
} elsif ($i < 6) {
sleep(1);
} else {
$rc = 0;
last;
}
$i++;
}
return $rc;
}
#ロック解除
sub unlock
{
local($lockdir) = @_;
rmdir($lockdir);
}
################################################################################
#
# プログラム内で共通に使えそうな関数
#
################################################################################
#対象年月を取得
sub get_target_month
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#相対指定があればそれを優先
if ($FORM{'next'} ne '') {
#現在日を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
#月を追加
$month += $FORM{'next'};
#年の繰越
$year += int($month / 12);
$month = $month % 12;
$month++;
return ($year, $month);
}
#フォームで渡された年月を分解
($year, $month) = split(/\//, $FORM{'month'});
#適正範囲内であればそのまま採用(2000年〜2099年を想定)
if (($year > 1999) && ($year < 2100) && ($month > 0) && ($month < 13)) {
return ($year, $month);
}
#適正範囲内でない場合、現在の年月日を採用
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
return ($year, $month);
}
#状態文字列を読み込む
sub read_strfile
{
local($stat, $str, $longstr);
#ファイルを開く
open(IN, $strfile);
while () {
#デコード
($stat, $str, $longstr) = split(/<>/,$_);
#該当データを設定
$STATUSSTR[$stat] = $str;
$STATUSSTRL[$stat] = $longstr;
}
close(IN);
}
#祝日を読み込む
sub read_holiday
{
local($year, $month) = @_;
local($y, $m, $d);
#初期化
@HOLIDAY = ();
#ファイルを開く
open(IN, $holidayfile);
while () {
#デコード
($y, $m, $d) = split(/\//,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
push(@HOLIDAY, $d);
}
}
close(IN);
}
#古いデータを削除する
sub delete_old_data
{
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#yyyymmddの形に変換
local($datevalue) = $year * 10000 + $month * 100 + $mday;
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(古いデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y * 10000 + $m * 100 + $d) >= $datevalue) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
}
#祝日判定
sub is_holiday
{
local($year, $month, $day) = @_;
foreach (@HOLIDAY) {
if ($day == $_) {
return 1;
}
}
return 0;
}
################################################################################
#
# エラー表示
#
################################################################################
#エラー
sub error
{
local($msg) = @_;
local($html);
#メッセージの処理
if ($msg ne '') {
$msg = "エラーメッセージ:
$msg";
}
#HTML作成
$html = << "EOM";
エラー
CGIエラーが発生しました。
ブラウザの「戻る」で前の画面に戻ってください。
$msg
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室表示
#
################################################################################
#空室表示
sub show
{
local($html);
local($calender);
local($copyright);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況
戻る
宿 花屋徳兵衛 空室状況一覧
$STATUSSTR[1] | $STATUSSTRL[1] |
$STATUSSTR[2] | $STATUSSTRL[2] |
$STATUSSTR[3] | $STATUSSTRL[3] |
|
$STATUSSTR[0] | $STATUSSTRL[0] |
$STATUSSTR[4] | $STATUSSTRL[4] |
|
$calender
$copyright
EOM
#表示
&print_html($html);
}
#カレンダー表示部を取得
sub get_calender
{
local($html) = '';
local($year, $month, $edit) = @_;
if ($FORM{'disptype'} == 1) {
$html = &get_calender1($year, $month, $edit);
} elsif ($FORM{'disptype'} == 2) {
$html = &get_calender2($year, $month, $edit);
} else {
$html = &get_calender0($year, $month, $edit);
}
return $html;
}
#標準カレンダータイプのカレンダーを取得
sub get_calender0
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($i, $j, $k);
local($days);
local($firstwday);
local($lastwday);
local($holiday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初と最後の曜日を取得
$firstwday = &get_wday($year, $month, 1);
$lastwday = &get_wday($year, $month, $days);
#カレンダーの枠の形に合わせて、隙間部分の日を-1で初期化
for ($i = 0; $i < $firstwday; $i++) {
$calday[$i] = -1;
}
for ($i = 0; $i < $days; $i++) {
$calday[$firstwday + $i] = $i+1;
}
for ($i = 0; $i < 6 - $lastwday; $i++) {
$calday[$firstwday + $days + $i] = -1;
}
$caldays = $firstwday + $days + (6-$lastwday);
#テーブル開始
$html .= "\n";
$html .= "$year年$month月 |
\n";
#曜日名
$html .= "\n";
for ($i = 0; $i < 7; $i++) {
$html .= "$wdaystr[$i] | \n";
}
$html .= "
\n";
#週ごとにHTML作成
for ($i = 0; $i < $caldays / 7; $i++) {
#日付表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
} else {
$html .= " | \n";
}
}
$html .= "
\n";
#空室状況表示
$html .= "\n";
for ($j = 0; $j < 7; $j++) {
#日付を取得
$day = $calday[$i * 7 + $j];
#正の日付なら普通に表示・負なら隙間部分として処理
if ($day > 0) {
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($showpname) { $html .= "$periodname[$l] | "; }
$html .= "$STATUSSTR[$stats[$l]] | ";
}
$html .= " | \n";
} else {
$html .= "";
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$l";
}
$html .= "$periodname[$l] ";
}
$html .= " | \n";
}
} else {
$html .= " | ";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#横長タイプのカレンダーを取得
sub get_calender1
{
local($html) = '';
local($year, $month, $edit) = @_;
local($day);
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, $days);
return $html;
}
#横長タイプ(上下2段)のカレンダーを取得
sub get_calender2
{
local($html) = '';
local($year, $month, $edit) = @_;
local($days);
local($firstwday);
#対象データを取得
&read_datafile($year, $month);
#日数を取得
$days = &get_days($year, $month);
#最初の曜日を取得
$firstwday = &get_wday($year, $month, 1);
# 1段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 1, 16);
$html .= "
";
# 2段目
$html .= &get_calender_row($year, $month, $edit, $firstwday, 17, $days);
return $html;
}
# 横長カレンダーの1段分
sub get_calender_row
{
local($year, $month, $edit, $firstwday, $stday, $edday) = @_;
local($html) = '';
local($span);
local($day);
local($i, $j, $k);
local($calwidth);
local($holiday);
#カレンダー幅を計算(実際にこのテーブルに含まれる日数に基づいた計算)
$calwidth = ($edday - $stday + 1) * $colwidth_day + $colwidth_rowtitle;
#微調整
$calwidth = $calwidth
+ ($edday - $stday + 2) * 1 * 2 # セル数 * 1dot * 左右
+ ($edday - $stday + 3) * 2; # 本数 * 2dot
#年月日のrowspanを計算
if ($showpname) {
$span = 2;
} else {
$span = 2 + $periods;
}
#テーブル開始
$html =<<"EOM";
$year年$month月 |
EOM
#日付
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$day | \n";
} else {
$html .= "$day | \n";
}
}
$html .= "
\n";
#曜日名
$html .= "\n";
for ($i = $stday; $i <= $edday; $i++) {
$day = $i;
$wday = ($firstwday + $i - 1) % 7;
$holiday = &is_holiday($year, $month, $day);
if ($holiday) {
$html .= "$wdaystr[$wday] | \n";
} else {
$html .= "$wdaystr[$wday] | \n";
}
}
$html .= "
\n";
#状態枠ごとにHTML作成
for ($i = 0; $i < $periods; $i++) {
$html .= "\n";
#状態枠名
if ($showpname) {
$html .= "$periodname[$i] | \n";
}
#日ごとにHTML作成
for ($j = $stday; $j <= $edday; $j++) {
$day = $j;
@stats = split(/;/, $STATUS[$day]);
#編集モード以外は表示するだけ、編集モード時はコンボボックスで表示
if (!$edit) {
$html .= "$STATUSSTR[$stats[$i]] | \n";
} else {
if ($i == 0) {
$selname = "stat$day";
} else {
$selname = "stat$day-$i";
}
$html .= " | \n";
}
}
$html .= "
\n";
}
#テーブル終了
$html .= "
\n";
return $html;
}
#対象データを取得
sub read_datafile
{
local($year, $month) = @_;
local($y, $m, $d, $stat);
local($i);
#今日以降の初期値を作成
local($default_stat_1day) = '';
for ($i = 0; $i < $periods; $i++) {
$default_stat_1day .= $default_stat;
$default_stat_1day .= ';';
}
#現在日を取得
$ENV{'TZ'} = "JST-9";
local($sec,$min,$hour,$nd,$nm,$ny) = localtime(time);
$ny = 1900 + $ny;
$nm++;
#データを初期化
for ($i = 1; $i < 32; $i++) {
$STATUS[$i] = 0;
#今日以降のデータ未設定日は $default_stat にする
if (($year*10000+$month*100+$i) >= ($ny*10000+$nm*100+$nd)) {
$STATUS[$i] = $default_stat_1day;
}
}
#ファイルを開く
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/,$_);
#該当データを設定
if (($y == $year) && ($m == $month)) {
$STATUS[$d] = $stat;
}
}
close(IN);
}
################################################################################
#
# 空室表示(SSIバージョン)
#
################################################################################
#空室表示
sub ssishow
{
local($html);
local($calender);
#古いデータを削除
&delete_old_data;
#対象年月を取得
local($year, $month) = &get_target_month();
#前後の月を取得
local($prevyear, $prevmonth) = ($year, $month-1);
local($nextyear, $nextmonth) = ($year, $month+1);
if ($prevmonth == 0) {
$prevyear--;
$prevmonth = 12;
}
if ($nextmonth == 13) {
$nextyear++;
$nextmonth = 1;
}
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 0);
#HTML作成
$html = $calender;
#表示
&print_html($html);
}
################################################################################
#
# 空室編集
#
################################################################################
#空室編集
sub edit
{
local($html);
local($calender);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#状態文字列を取得
&read_strfile;
#祝日を取得
&read_holiday($year, $month);
#カレンダー表示部を取得
$calender = &get_calender($year, $month, 1);
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
$year年$month月の空室状況:編集モード
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 空室保存
#
################################################################################
#空室保存
sub save
{
local($html);
local(@lines);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#対象年月を取得
local($year, $month) = &get_target_month();
#日数を取得
local($days) = &get_days($year, $month);
#日数分のデータを書き込み可能な書式に変換
local($day);
local($tmpline);
local($varname);
for ($day = 1; $day < $days+1; $day++) {
$stats = '';
for ($l = 0; $l < $periods; $l++) {
if ($l == 0) {
$varname = "stat$day";
} else {
$varname = "stat$day-$l";
}
$stats .= "$FORM{$varname};";
}
$tmpline = "$year<>$month<>$day<>$stats<>\n";
push(@lines, $tmpline);
}
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#現在のデータを読み込む(更新対象のデータは除く)
local($y, $m, $d, $stat);
open(IN, $datafile);
while () {
#デコード
($y, $m, $d, $stat) = split(/<>/, $_);
#該当データを設定
if (($y != $year) || ($m != $month)) {
push(@lines, $_);
}
}
close(IN);
#ファイルを更新
open(OUT, ">$datafile");
print OUT @lines;
close(OUT);
#更新日記録ファイルを更新
open(OUT, ">$updfile");
print OUT "dummy text";
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 文字列の編集
#
################################################################################
#文字列の編集
sub editstr
{
local($html);
local($copyright);
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#状態文字列を取得
&read_strfile;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
状態文字列の編集
$copyright
EOM
#表示
&print_html($html);
}
################################################################################
#
# 文字列の編集を保存
#
################################################################################
#文字列の編集を保存
sub savestr
{
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#新しいデータを作成
local(@lines);
push(@lines, "0<>$FORM{'str0'}<>$FORM{'strl0'}<>\n");
push(@lines, "1<>$FORM{'str1'}<>$FORM{'strl1'}<>\n");
push(@lines, "2<>$FORM{'str2'}<>$FORM{'strl2'}<>\n");
push(@lines, "3<>$FORM{'str3'}<>$FORM{'strl3'}<>\n");
push(@lines, "4<>$FORM{'str4'}<>$FORM{'strl4'}<>\n");
#ロック
if (!&lock($lockdir)) {
&error("ロック処理に失敗しました。");
return;
}
#ファイルを更新
open(OUT, ">$strfile");
print OUT @lines;
close(OUT);
#ロック解除
&unlock($lockdir);
#管理画面に戻る
&mng;
}
################################################################################
#
# 管理画面
#
################################################################################
#管理画面
sub mng
{
local($html);
local($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst);
local($copyright);
#パスワードが指定されていない場合はパスワード入力画面を表示
if ($FORM{'pwd'} eq '') {
&pwd_input;
return;
}
#パスワードチェック
if ($FORM{'pwd'} ne $pwd) {
&error("パスワードが違います。");
return;
}
#現在の日時を取得
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year = 1900 + $year;
$month++;
#著作権表示部を取得
$copyright = &get_copyright;
#HTML作成
$html = << "EOM";
空室状況管理画面
戻る
空室状況管理画面
■ 空室状況の編集
■ 空室状況文字の編集
$copyright
EOM
#表示
&print_html($html);
}
#パスワード入力画面
sub pwd_input
{
local($html) = '';
#HTML作成
$html = << "EOM";
パスワード入力
EOM
#表示
&print_html($html);
}
################################################################################
#
# 更新日の取得
#
################################################################################
#更新日時をSSIで表示
sub updtime
{
local($html);
local($updtime);
#ファイルの更新日を取得
$updtime = &get_upddate($updfile);
#HTML作成
$html = $updtime;
#表示
&print_html($html);
}
#ファイルの更新日を取得
sub get_upddate
{
local($file) = @_;
local($updtime) = $updtime_format;
local($tmp);
#呼び出し時に書式指定があればそれを優先
if ($FORM{'fmt'} ne '') {
$updtime = $FORM{'fmt'};
}
#ファイルの更新日を取得
local($mtime) = (stat($file))[9];
local($s,$m,$h,$day,$mon,$year) = localtime($mtime);
#localtimeの値を調整
$year = 1900 + $year;
$mon++;
#年(YYYY)
$updtime =~ s/YYYY/$year/;
#年(YY)
$tmp = sprintf("%02d", $year % 100);
$updtime =~ s/YY/$tmp/;
#月(MM)
$tmp = sprintf("%02d", $mon);
$updtime =~ s/MM/$tmp/;
#月(M)
$updtime =~ s/M/$mon/;
#日(DD)
$tmp = sprintf("%02d", $day);
$updtime =~ s/DD/$tmp/;
#日(D)
$updtime =~ s/D/$day/;
#時(hh)
$tmp = sprintf("%02d", $h);
$updtime =~ s/hh/$tmp/;
#時(h)
$updtime =~ s/h/$h/;
#分(mm)
$tmp = sprintf("%02d", $m);
$updtime =~ s/mm/$tmp/;
#分(m)
$updtime =~ s/m/$m/;
#秒(ss)
$tmp = sprintf("%02d", $s);
$updtime =~ s/ss/$tmp/;
#秒(s)
$updtime =~ s/s/$s/;
return $updtime;
}
################################################################################
#
# 著作権表示の取得
#
################################################################################
#著作権表示の取得
sub get_copyright
{
#著作権
local($copyright) = << "EOM";
EOM
return $copyright;
}
################################################################################