■
クラスを強引に使ってみました。
今日は投稿部分。
自分としては前より分かりやすくなった気がします。
class Axs attr_accessor :host, :addr def initialize(get_host) @host = ENV['REMOTE_HOST'] @addr = ENV['REMOTE_ADDR'] if get_host == 1 && (@host == "" || @host == @addr) require "socket" a = Socket.gethostbyname(@addr) @host = Socket.gethostbyaddr(a[3], a[2]).first end @host = @addr if @host == '' end def ip_check(list) list.split(/\s+/).each do |l| l = l.gsub(/\./,"\\\.") l = l.gsub(/\*/,"\.\*") if /^#{l}/i =~ @addr return true break end end end def host_check(list) list.split(/\s+/).each do |l| l = l.gsub(/\./,"\\\.") l = l.gsub(/\*/,"\.\*") if /^#{l}/i =~ @host return true break end end end def postCheck "POST以外受け付けていません。<br>" if ENV['REQUEST_METHOD'] != "POST" end def refCheck(url) ref = ENV['HTTP_REFERER'].gsub(/\?.*/,'') "不正なアクセスです。<br>" unless ref.index(url) end end class Res attr_accessor :name, :email, :sub, :comment, :url, :pwd attr_accessor :no, :date, :host, :time def initialize @no @date @name @email @sub @comment @url @host @pwd @time end def no_wd(str) # 禁止ワードチェック flg = nil str.split(/,/).each do |l| flg = 1 if @name.index(l) flg = 1 if @comment.index(l) end "禁止ワードが含まれています。<br>" if flg end def jp_wd # 日本語チェック if @comment !~ /[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/ "コメントに日本語が含まれていません。<br>" end end def urlnum(num) # URL個数チェック if num > 0 && num < @comment.scan("ttp://").length "コメント中のURLアドレスは最大#{num}個までです。<br>" end end def formCheck # フォーム内容をチェック err = '' err << "名前が入力されていません。<br>" if @name.empty? err << "コメントが入力されていません。<br>" if @comment.empty? err << "Eメールの入力内容が不正です。<br>" if @email != '' && @email !~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/ return err end def date_now # 現在時刻を取得 t = Time.now @time = t.to_i wk = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'] @date = sprintf("%04d/%02d/%02d(%s) %02d:%02d:%02d", t.year, t.month, t.day, wk[t.wday], t.hour, t.min, t.sec) end def encrypt # パスワードをクリプト salt = [rand(64),rand(64)].pack("C*").tr("\x00-\x3f","A-Za-z0-9./") @pwd = @pwd.crypt(salt) end def save # ログ保存形式のデータを出力 surl = @url ssub = @sub surl = '' if surl == "http://" ssub = '無題' if ssub.empty? "#{@date}<>#{@name}<>#{@email}<>#{ssub}<>#{@comment}<>#{surl}<>#{@host}<>#{@pwd}<>#{@time}<>\n" end end class Log def initialize(log_file) @log_file = log_file @no = 1 end def wCheck(res) # 記事番号取得、二重投稿チェック、連続投稿制限 msg = '' f = File.open(@log_file, "r") f.flock(File::LOCK_EX) # 占有ロック log = f.gets f.flock(File::LOCK_UN) # アンロック f.close no,dat,nam,eml,sub,com,url,hos,pw,tim = log.split(/<>/) # 記事No採番 @no = no.to_i + 1 msg = "二重投稿です。<br>" if res.name == nam && res.comment == com flg = 0 case $regCtl when 1 flg = 1 if $host == hos && res.time.to_i - tim.to_i < $wait when 2 flg = 1 if res.time.to_i - tim.to_i < $wait end if flg == 1 msg << "現在投稿制限中です。もうしばらくたってから投稿をお願いします" end return msg end def regist(res,max) # 投稿保存 f = File.open(@log_file, "r+") f.flock(File::LOCK_EX) # 占有ロック log = f.readlines # 先頭に新しい記事を挿入 log.unshift("#{@no}<>#{res.save}") # 記事数調整 log = log.slice(0, max) # 先頭からmax件を切り出す log.slice(0..max-1)でも同じ # 更新 f.rewind # 書き出し位置を先頭に f.print log f.truncate(f.pos) # これ以降のデータ(古いデータ)があれば削除 f.flush() # バッファをフラッシュ(メモリ上に未書き込みのデータがあれば書き込み) f.flock(File::LOCK_UN) # アンロック f.close end end require 'cgi' cgi = CGI.new if cgi['mode'] == 'regist' axs = Axs.new($gethostbyaddr) # IPとホストを取得 flg = nil unless $deny_addr.empty? # アクセス制限チェック flg = axs.ip_check($deny_addr) end unless $deny_host.empty? flg = axs.host_check($deny_host) end error("アクセスを許可されていません") if flg error_msg = '' res = Res.new # 投稿されたデータでレスオブジェクト?を作成 res.name = cgi['name'] res.email = cgi['email'] res.sub = cgi['sub'] res.comment = cgi['comment'] res.url = cgi['url'] res.pwd = cgi['pwd'] res.host = axs.host res.date_now res.encrypt log = Log.new($logfile) # ログオブジェクト?を作成 error_msg << axs.postCheck.to_s # 投稿エラーをチェック error_msg << axs.refCheck($baseUrl).to_s error_msg << res.no_wd($no_wd).to_s error_msg << res.jp_wd.to_s error_msg << res.urlnum($urlnum).to_s error_msg << res.formCheck.to_s error_msg << log.wCheck(res).to_s error(error_msg) unless error_msg.empty? # エラーがある? log.regist(res,$max) # エラーが無ければ記事を記録 msg = "#{cgi['name']}<>#{cgi['email']}<>#{cgi['url']}<>#{cgi['pwd']}" cookie = CGI::Cookie.new('ASKA_BBS', msg) # クッキーを記録 cookie.expires = Time.now + 60*24*60*60 content = "<a href='./aska.cgi'>書き込み完了</a>" cgi.out("cookie" => cookie){content} exit end