package lib; ############################################################ # ウェッブカレンダ&スケジューラ用ライブラリ # # Ver 0.21b Time::Localモジュールを使用しないようにした。 # # ---------------------------------------------------------- # オリジナル情報 # 制作者: Koji Onishi # 制作日: 98.10.15 # 種類: フリーウエア # 動作確認: FreeBSD & perl5 # ############################################################ require "jcode.pl"; ############################################################ # 月末の数字 @monthday = ('31','28','31','30','31','30','31','31','30','31','30','31'); ########################################################### # 返信があるかないかをチェックする # 引数:ファイルパス # 戻値:1=存在する #    0=存在しない、またはサイズが0である sub check_henshin { local($file) = @_; if(-r "$file"){ if(-z "$file"){ return 0; } return 1; }else{ return 0 } } ############################################################ # ディレクトリがあるかないかをチェックし、 # なければ書込みモードでディレクトリを作成する # 引き数:ディレクトリパス # 戻り値:1=ディレクトリが存在する、もしくはディレクトリが作成された #     0=ディレクトリを作成できない # sub check_make_dir { local($dir,$dir_pms) = @_; if(-d "$dir"){ return 1; }else{ if(mkdir("$dir",0777)){ chmod $dir_pms, "$dir"; system "touch $dir/index.html"; return 1; }else{ return 0; } } } ############################################################ # Windows対応flock # 引き数:ロックファイル名 # 戻り値:1=ロックファイルが存在する #     0=ロックファイルが存在しない # sub flock_on { local($lockfile) = @_; if(-f "$lockfile"){ return 1; }else{ if(open(LOCK,">$lockfile")){ print LOCK "lock"; close(LOCK); chmod $file_permission, "$lockfile"; return 0; }else{ &error_make_lockfile; return 0; } } } ############################################################ # Windows対応unflock # 引き数:ロックファイル名 # 戻り値:なし # sub flock_off { local($lockfile) = @_; if(-f "$lockfile"){ unlink("$lockfile"); } } ############################################################ # 月末の数字を求める # 引き数:年、月 # 戻り値:月末の数字 # sub getgetumatu { local($year,$mon) = @_; if($mon != 2){ return(@monthday[$mon-1]); }else{ if(&leapyear($year)){ return(29); }else{ return(28); } } } ############################################################ # 曜日を求める # 引き数:年、月、日 # 戻り値:曜日の数字 # 0="日",1="月",2="火",3="水",4="木",5="金",6="土" # sub getyoubi { local($year,$mon,$day) = @_; $time = &gettime($year,$mon,$day); ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = gmtime($time); return($wday); } ############################################################ # localtimeやgmtimeの引き数にできる数字を求める # 引き数:年、月、日 # 戻り値:localtimeやgmtimeの引き数にできる数字 # sub gettime { local($year,$mon,$day) = @_; local($daynum,$time,$i); $daynum = 0; $mon = $mon - 1; $daynum += ($year-1)*365+int(($year-1)/4)-int(($year-1)/100)+int(($year-1)/400); for($i = 0; $i < $mon; $i++){ $daynum += $monthday[$i]; if($i == 1 && &leapyear($year)){ $daynum++; } } $daynum += $day; $time = ($daynum - 719163) * 24 * 60 * 60; return ($time); } ############################################################ # 年月日時分秒(ローカルタイム)を秒数に変換する # 引き数:年、月、日、時、分、秒(ローカルタイム) # 戻り値:引数に対する秒数 # sub gettimelocal { local($year,$mon,$day,$hour,$min,$sec) = @_; local(@epoch) = localtime(0); $tzmin = $epoch[2] * 60 + $epoch[1]; # minutes east of GMT if ($tzmin > 0) { $tzmin = 24 * 60 - $tzmin; # minutes west of GMT $tzmin -= 24 * 60 if $epoch[5] == 70; # account for the date line } local($time) = &gettime($year,$mon,$day) + $hour*60*60 + $min*60 + $sec + $tzmin*60; return ($time); } ############################################################ # 閏年の判定 # 引き数:年 # 戻り値:1=閏年、0=閏年じゃない # sub leapyear { local($year) = @_; if(($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0){ return 1; }else{ return 0; } } ############################################################ # 2000年問題に対応した日付けを求める # 引き数:gettimeやtimeの戻り値 # 戻り値:年、月、日、曜日、時間、分、秒 # sub getdatetime { local($time) = @_; if($time eq ""){$time = time;} ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime($time); $year = $year+1900; $mon = $mon+1; # $mon = sprintf("%02d", $mon); # $day = sprintf("%02d", $day); $wday = @wdays[$wday]; # $hour = sprintf("%02d", $hour); # $min = sprintf("%02d", $min); # $sec = sprintf("%02d", $sec); return($year,$mon,$day,$wday,$hour,$min,$sec); } ############################################################ # WEBから送信されたフォームを読み込む # 引き数:jcode.plの文字コード(sjis,jis,euc,etc) # 戻り値:フォームの配列(%FORM) # sub read_input { $charset = $_[0]; $charset = 'euc' if ( $charset eq '' ); local ($buffer, @pairs, $pair, $envname, $value, %FORM); $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST"){ read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else{ $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs){ ($envname, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s//>/g; $value =~ s/\r\n/
/g; $value =~ s/\n/
/g; $value =~ s/\t/ /g; &jcode'convert(*value, $charset); # &jcode'convert(*envname, $charset); $FORM{$envname} = $value; } %FORM; } ############################################################ # WEBから送信されたフォームを読み込みメインルーチンへ渡す # 引き数:jcode.plの文字コード(sjis,jis,euc,etc) # 戻り値:フォームの配列(form{'name'}) # sub getinputfromweb { %main'form = &read_input( @_ ); } ############################################################ # クッキーのデータを読み込む # 引き数:jcode.plの文字コード(sjis,jis,euc,etc) # 戻り値:クッキーの配列(%COOKIE) # sub read_cookie { $charset = $_[0]; $charset = 'euc' if ( $charset eq '' ); local($cookies, @pairs, $pair, $cookie_name, $cookie_value, %COOKIE); $cookies = $ENV{'HTTP_COOKIE'}; @pairs = split(/;\s/, $cookies); foreach $pair (@pairs){ ($cookie_name, $cookie_value) = split(/=/, $pair); $cookie_value =~ tr/+/ /; $cookie_value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*cookie_value, $charset); $COOKIE{$cookie_name} = $cookie_value; } %COOKIE; } ############################################################ # クッキーのデータを読み込みメインルーチンへ渡す # 引き数:jcode.plの文字コード(sjis,jis,euc,etc) # 戻り値:クッキーの配列(cookie{'name'}) # sub get_cookie{ %main'cookie = &read_cookie( @_ ); } ############################################################ # クッキーを食べさせる # 引き数:クッキー名、クッキーの値、削除までの日数 # 戻り値:クッキーのヘッダ # sub set_cookie{ local($cookie_name, $cookie_value, $expires) = @_; local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$result); if($expires != 0){ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time + $expires*24*60*60); $year = $year+1900; $sec = sprintf("%02d", $sec); $min = sprintf("%02d", $mihtn); $hour = sprintf("%02d", $hour); @week_str = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); $wday = @week_str[$wday]; @month_str = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); $mon = @month_str[$mon]; $gm_date = "$wday, $mday\-$mon\-$year $hour:$min:$sec GMT"; }else{ $gm_date = "Thu, 1-Jan-1980 00:00:00 GMT"; } # $result = "$cookie_name=$cookie_value; expires=$gm_date; domain=$ENV{'SERVER_NAME'}; path=$ENV{'SCRIPT_NAME'}; secure "; # $result = "$cookie_name=$cookie_value; expires=$gm_date; domain=$ENV{'SERVER_NAME'}"; $result = "$cookie_name=$cookie_value; expires=$gm_date;"; print "Set-Cookie: $result\n"; } ############################################################ # クッキーを削除 # 引き数:クッキー名 # 戻り値:クッキーのヘッダ # sub expire_cookie{ local($cookie_name) = @_; &set_cookie($cookie_name, 0, 0); } ############################################################ # 動作内容 :文字列の暗号化 # 引数 :平文 # 戻り値 :暗号 # sub MakeCrypt{ local($plain) = @_; local(@char,$f,$now,@saltset,$pert1,$pert2,$nsalt,$salt); @saltset = ('a'..'z','A'..'Z','0'..'9','.','/'); # 暗号が構成される文字群 $now = time; srand(time|$$); $f = splice(@saltset,rand(@saltset),1) . splice(@saltset,rand(@saltset),1); ($pert1,$pert2) = unpack("C2",$f); $week = $now / (60*60*24*7) + $pert1 + $pert2 - length($plain); $nsalt = $saltset[$week % 64] . $saltset[$now % 64]; $result = crypt($plain,$nsalt); if ($result =~ /^\$1\$/) { $salt = 3; } else { $salt = 0; } if (crypt($plain,substr($result,$salt,2)) ne $result || $result eq ''){ return ''; } return $result; } ############################################################ # 動作内容:スケジュールデータを時間順にソート sub sort_data { local(@datakeys); local(@datalist) = @_; foreach (@datalist){ push(@datakeys, (split(/\t/))[9]); # 終了「分」でソート } @datalist = @datalist[sort bydatakeys $[..$#datalist]; @datakeys = (); foreach (@datalist){ push(@datakeys, (split(/\t/))[8]); # 終了「時」でソート } @datalist = @datalist[sort bydatakeys $[..$#datalist]; @datakeys = (); foreach (@datalist){ push(@datakeys, (split(/\t/))[7]); # 開始「分」でソート } @datalist = @datalist[sort bydatakeys $[..$#datalist]; @datakeys = (); foreach (@datalist){ push(@datakeys, (split(/\t/))[6]); # 開始「時」でソート } @datalist = @datalist[sort bydatakeys $[..$#datalist]; sub bydatakeys { $datakeys[$a] <=> $datakeys[$b]; } return @datalist; } ####################################################### # URL又はメールアドレスならばリンクを張る # sub inline_link { local($_) = @_; $_ =~ s/([^=^\"]|^)((http|ftp):[!#-9\?=A-~]+)/$1$2<\/a>/g; $_ =~ s/([\w\-\_]+\@[\w\-\_\.]+)/$1<\/a>/g; return($_); } ################################################################### # 繰り返しデータ処理 年 # 引 数:西暦,年繰返しファイル名 # 戻 値:年繰返しリスト sub kurikaeshi_yearly { local($year,$yearlydata,$yearlydata2) = @_; local($shun,$yearlysize,$yearly_mon,$yearly_day,$yearly_dat,$yearly_flag,$j,$weekday,$yearly_day_tmp); local(@renkyuu,@yearly_tmp,@furikae,$furikaesize,$w_youbi,$weekcnt,$cntstart_day,$cntstart_youbi,$tmpcnt); local(@yearly) = (); if(open(DATA,"<$yearlydata")){ if($year < 2000){ while () { if($_ !~ /^#/){chop; push(@yearly, $_);}} } else { while () { if(!/^#|体育の日|成人の日/){chop; push(@yearly, $_);}} } } # 春分の日の割出し(1980年以降に適用) $shun = int(20.8431+0.242194*($year-1980)-int(($year-1980)/4)); push(@yearly,"3\t$shun\t春分の日\t1"); # 秋分の日の割出し(1980年以降に適用) $shuu = int(23.2488+0.242194*($year-1980)-int(($year-1980)/4)); push(@yearly,"9\t$shuu\t秋分の日\t1"); # 振替休日のチェック @furikae = (); $yearlysize = $#yearly; for($j = 0; $j <= $yearlysize; $j++){ ($yearly_mon,$yearly_day,$yearly_dat,$yearly_flag) = split(/\t/,@yearly[$j]); $weekday = &lib'getyoubi($year,$yearly_mon,$yearly_day); if ($weekday == 0 && $yearly_flag == 1 && $yearly_dat ne "憲法記念日" && $yearly_dat ne "国民の休日"){ $yearly_day_tmp = $yearly_day + 1; push(@furikae,"$yearly_mon\t$yearly_day_tmp\t振替休日\t1"); } } $furikaesize = $#furikae; if ($furikaesize >= 1){push(@yearly,@furikae);} # 改正祝日法により2000年以降、成人の日は1月第2月曜日、体育の日は10月第2月曜日 # いとう氏に感謝!! if($year >= 2000) { @renkyuu = (); @yearly_tmp = (); if(open(DATA,"<$yearlydata2")){ while () { if($_ !~ /^#/){chop; push(@yearly_tmp, $_);}} close(DATA); } for($i = 0; $i <= $#yearly_tmp; $i++){ ($yearly_mon,$weekcnt,$w_youbi,$yearly_dat,$yearly_flag) = split(/\t/,@yearly_tmp[$i]); if($weekcnt == 1){$cntstart_day = 1;} elsif($weekcnt == 2){$cntstart_day = 8;} elsif($weekcnt == 3){$cntstart_day = 15;} elsif($weekcnt == 4){$cntstart_day = 22;} elsif($weekcnt == 5){$cntstart_day = 29;} $cntstart_youbi = &lib'getyoubi($year,$yearly_mon,$cntstart_day); $tmpcnt = $w_youbi - $cntstart_youbi; if($tmpcnt < 0){ $yearly_day_tmp = $cntstart_day + (7 + $tmpcnt); } else { $yearly_day_tmp = $cntstart_day + $tmpcnt; } push(@renkyuu,"$yearly_mon\t$yearly_day_tmp\t$yearly_dat\t$yearly_flag"); } $renkyuusize = $#renkyuu; if($renkyuusize >= 1){push(@yearly,@renkyuu);} } return(@yearly); } sub kurikaeshi_monthly { local(@montjly) = (); local($monthlydata) = @_; if(open(DATA,"<$monthlydata")){ while () { if($_ !~ /^#/){chop; push(@monthly, $_);}} close(DATA); } return(@monthly); } sub kurikaeshi_weekly { local(@weekly) = (); local($weeklydata) = @_; if(open(DATA,"<$weeklydata")){ while () { if($_ !~ /^#/){chop; push(@weekly, $_);}} close(DATA); } return(@weekly); } ########################################################## # 年に一回のスケジュールの読み込み sub getyearly { local($flag) = 0; local($mon_day,@yearly) = @_; local(@yearly_dat) = (); local($ii); for($ii = 0; $ii <= $#yearly; $ii++){ ($yearly_mon,$yearly_day,$yearly_dat,$yearly_flag) = split(/\t/,@yearly[$ii]); if("$mon_day" eq "$yearly_mon/$yearly_day"){ $flag += $yearly_flag; push(@yearly_dat,$yearly_dat); } } if($#yearly_dat >= 0){ return($flag,@yearly_dat); } else { return(0); } } ########################################################## # 月に一回のスケジュールの読み込み sub getmonthly { local($flag) = 0; local($day,@monthly) = @_; local(@monthly_dat) = (); local($ii,$monthly_day,$monthly_hour,$monthly_minits,$monthly_dat,$monthly_flag,$shu); for($ii = 0; $ii <= $#monthly; $ii++){ ($monthly_day,$monthly_hour,$monthly_minits,$monthly_dat,$monthly_flag,$shu) = split(/\t/,@monthly[$ii]); if("$day" eq "$monthly_day"){ $flag += $monthly_flag; push(@monthly_dat,join("\t",$monthly_dat,$monthly_hour,$monthly_minits,$shu)); } } if($#monthly_dat >= 0){ return($flag,@monthly_dat); } else { return(0); } } ########################################################## # 週に一回のスケジュールの読み込み sub getweekly { local($youbi,@weekly) = @_; local($flag) = 0; local(@weekly_dat) = (); local($ii); for($ii = 0; $ii <= $#weekly; $ii++){ ($weekly_wday,$weekly_hour,$weekly_minits,$weekly_dat,$weekly_flag) = split(/\t/,@weekly[$ii]); if($youbi == $weekly_wday){ $flag += $weekly_flag; push(@weekly_dat,join("\t",$weekly_dat,$weekly_hour,$weekly_minits)); } } if($#weekly_dat >= 0){ return($flag,@weekly_dat); } else { return(0); } } ###################################################### # エラー表示 sub error_illeagal_passwd { print qq(

パスワードが間違っています。
ブラウザの「戻る」ボタンを押して、再度パスワードを入力してください。

); exit 1; } sub error_no_passwd { print qq(

パスワードが空欄で処理できません。
ブラウザの「戻る」ボタンを押して、再度パスワードを入力してください。

); exit 1; } sub error_no_passwd2 { print qq(

パスワードが空欄では登録できません。
削除時に必要ですので何かしら入力してください。
ブラウザの「戻る」ボタンを押して、再度パスワードを入力してください。

); exit 1; } sub error_illeagal_time { print qq(

時間設定が異常です。
開始時間と終了時間を確認してください。

); exit 1; } sub error_cant_make_file { print qq(

データファイルを作成できません。
ディレクトリのパーミッションを確認してください。

); exit 1; } sub error_no_input_form { print qq(

記入されていない項目があります。
ブラウザの「戻る」ボタンを押して、空欄を記入してください。

); exit 1; } sub error_file_locking { print qq(

混雑しています。
少し時間をおいてから書き込みをしてください。

); exit 1; } sub error_make_lockfile { print qq(

ロックファイルの作成に失敗しました。
ディレクトリのパーミッションを確認してください。

); exit 1; } sub error_data_write { print qq(

データファイルの作成に失敗しました。
ディレクトリのパーミッションを確認してください。

); exit 1; } sub error_illeagal_email { print "

メールアドレスが正しくありません。

\n"; exit 1; } 1;