#!/usr/local/bin/ruby # # $Date: 2006/08/10 11:49:57 $ # # Copyright (c) 2000-2005 M.T. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the author nor the names of its contributors may # be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # -- Mail ChecKer -- # This CGI access POP3 server to read mail and to remove the mail from server. # This script suppports APOP also. # # Set your CGI directory in wwwbase & your e-mail address in wwwadmin # # If you have an OpenSSL Library, # (http://www.ruby-lang.org/en/raa-list.rhtml?name=OpenSSL) # you can also connect to ``POP3 over SSL'' server. # Set support_ssl true if you wish this feature. # wwwbase = "https://your.host.name/directory/mck/" wwwadmin = "mailto:account@host.name" support_ssl = true if (support_ssl) then require 'pops' else require 'net/pop' end require 'cgi' require 'nkf' # begin workaround for ruby 1.6.5 if (RUBY_VERSION < "1.6.6") module Net class ProtocolError def initialize( msg, resp = nil) super msg @response = resp end end end end # end workaround class Mail def initialize(popm, range = '1000', rl = Array.new) @headerhash = nil begin @id = CGI::escape(popm.uidl) rescue $error = $! @id = nil return end @header = nil begin if (rl.include?(id)) then case range when 'all' @content = popm.pop.gsub("\r", "") when '1000' @content = popm.top(1000).gsub("\r", "") else @content = popm.top(0).gsub("\r", "") end @content =~/\n\n/ @header = $` + "\n" else @header = popm.header.gsub("\r", "") end @header = @header.gsub(/\n[\t ]+/, " ").split("\n") rescue $error = $! end end # initialize def [](header_name) if (@headerhash.nil?) then headerhash_initialize end @headerhash[header_name] end def []=(header_name, value) if (@headerhash.nil?) then headerhash_initialize end @headerhash[header_name] = value end def id; @id; end def set_id(_id); @id = _id; end def header; @header; end def content; @content; end private def headerhash_initialize @headerhash = Hash.new for item in @header do item =~/^([\w\-]*?):\s?/i @headerhash[$1.upcase] = $' end end end # class Mail class MailHolder def initialize(server, account, passwd, proto = 'apop', number = 500, range = '1000', rl = Array.new, dl = Array.new) @mailholder = Array.new @idlist = Array.new case proto when 'apop' popobject = Net::APOP.new(server) when 'pop3s' popobject = Net::POP3s.new(server) else popobject = Net::POP3.new(server) end begin idx1 = 1 idx2 = 1 counter = 0 popobject.start(account, passwd) do |pop| pop.each do |popm| break if counter >= number mail = Mail.new(popm, range, rl) if (mail.id.nil?) then mail.set_id('nouidl_' + idx1.to_s) idx1 = idx1 + 1 if (dl.include?(mail.id)) then popm.delete counter -= 1 else mail.set_id('nouidl_' + idx2.to_s) @mailholder.push(mail) @idlist.push(mail.id) idx2 = idx2 + 1 end else @mailholder.push(mail) @idlist.push(mail.id) if (dl.include?(mail.id)) then popm.delete counter -= 1 end end counter += 1 end end rescue $error = $! @idlist = nil end end # initialize def idlist; return @idlist; end def [](id) for mail in @mailholder do if (mail.id == id) then return mail end end end end # class MailHolder class SupportScript def SupportScript::check() <<'EOD' EOD end # SupportScript::check def SupportScript::show_button() <<'EOD' EOD end # SupportScript::show_button end # class SupportScript holder = nil server = '' account = '' passwd = '' proto = "apop" range = "1000" retrlist = Array.new delelist = Array.new cgi = CGI.new("html4Tr") if (RUBY_VERSION < "1.8") for key in cgi.keys do case key when "Server" server = '' if ((server = cgi['Server'][0].read).nil?) when "Account" account = '' if ((account = cgi['Account'][0].read).nil?) when "Password" passwd = '' if ((passwd = cgi['Password'][0].read).nil?) when "Proto" proto = cgi['Proto'][0].read when "Range" range = cgi['Range'][0].read else if (key =~/retr$/ && cgi[key][0].read == "1") then retrlist.push($`) elsif (key =~/dele$/ && cgi[key][0].read == "1") then delelist.push($`) end end end else # end workaround for ruby 1.6 for key in cgi.keys do case key when "Server" server = cgi['Server'] when "Account" account = cgi['Account'] when "Password" passwd = cgi['Password'] when "Proto" proto = cgi['Proto'] when "Range" range = cgi['Range'] else if (key =~/retr$/ && cgi[key] == "1") then retrlist.push($`) elsif (key =~/dele$/ && cgi[key] == "1") then delelist.push($`) end end end end # for ruby 1.8 feature if (!(server.empty? || account.empty? || passwd.empty?)) then holder = MailHolder.new(server, account, passwd, proto, 500, range, retrlist, delelist) end cgi.out("charset"=>"EUC-JP") do cgi.html do "\n" + cgi.head do cgi.title { "Mail Checker" } + cgi.base("HREF"=>"#{wwwbase}") end + "\n\n" + cgi.body do cgi.h1 { "Mail Checker" } + "\n" + cgi.form("METHOD"=>"post", "ACTION"=>ENV['SCRIPT_NAME']) do "\n" + (if (!holder.nil?) then if (holder.idlist.nil?) then cgi.p do "<#{$error}>" + cgi.br + "Can't login to the POP server!" + "Please confirm your description." end + "\n" else SupportScript::check() + cgi.table('BORDER'=>"1") do counter = 0 "\n" + cgi.tr do cgi.th { "num" } + cgi.th { "RETR" } + cgi.th { "DELE" } + cgi.th { "From" } + cgi.th { "Subject" } end + "\n" + (holder.idlist.collect do |id| if (id =~/^nouidl/) then counter += 1 cgi.tr do cgi.th { counter } + cgi.th { } + cgi.th do cgi.input('TYPE'=>'checkbox', 'NAME'=>"#{id}dele", 'VALUE'=>'1') end + cgi.td('COLSPAN'=>'2') do "Can't get UIDL" end end + "\n" elsif (!delelist.include?(id)) then counter += 1 if (holder[id].header.nil?) then cgi.tr do cgi.th { counter } + cgi.th { } + cgi.th do cgi.input('TYPE'=>'checkbox', 'NAME'=>"#{id}dele", 'VALUE'=>'1') end + cgi.td('COLSPAN'=>'2') do "Can't get mail header" end end + "\n" else cgi.tr do cgi.th { counter } + cgi.th do cgi.input('TYPE'=>'checkbox', 'NAME'=>"#{id}retr", 'VALUE'=>'1') end + "\n" + cgi.th do cgi.input('TYPE'=>'checkbox', 'NAME'=>"#{id}dele", 'VALUE'=>'1') end + "\n" + cgi.td do if (holder[id]['FROM'].nil?) holder[id]['FROM'] = '' '' else "#{NKF::nkf('-me', holder[id]['FROM']).gsub(//,'>')}" end end + cgi.td do if (holder[id]['SUBJECT'].nil?) holder[id]['SUBJECT'] = '' '' else "#{NKF::nkf('-me', holder[id]['SUBJECT']).gsub(//,'>')}" end end end + "\n" end end end).join end + "\n" + # cgi.table SupportScript::show_button() end end).to_s + cgi.p do "POP Server " + (if (!server.empty?) cgi.input('TYPE'=>'text', 'NAME'=>'Server', 'VALUE'=>"#{server}") else cgi.input('TYPE'=>'text', 'NAME'=>'Server') end) + "\n" + "Protocol " + cgi.select('NAME'=>'Proto') do (if (proto == 'apop') cgi.option('VALUE'=>'apop', 'SELECTED'=>true) else cgi.option('VALUE'=>'apop') end) + "APOP\n" + (if (support_ssl) then if (proto == 'pop3s') then cgi.option('VALUE'=>'pop3s', 'SELECTED'=>true) else cgi.option('VALUE'=>'pop3s') end + "POP3 over SSL\n" end).to_s + (if (proto == 'pop3') cgi.option('VALUE'=>'pop3', 'SELECTED'=>true) else cgi.option('VALUE'=>'pop3') end) + "POP3" end + "\n" + # cgi.select "Range " + cgi.select('NAME'=>'Range') do if (range == 'all') cgi.option('VALUE'=>'all', 'SELECTED'=>true) else cgi.option('VALUE'=>'all') end + "ALL\n" + if (range == '1000') cgi.option('VALUE'=>'1000', 'SELECTED'=>true) else cgi.option('VALUE'=>'1000') end + "1000 lines\n" + if (range == '0') cgi.option('VALUE'=>'0', 'SELECTED'=>true) else cgi.option('VALUE'=>'0') end + "Header" end end + "\n" + # cgi.p cgi.p do "Account name " + if (!account.empty?) cgi.input('TYPE'=>'text', 'NAME'=>'Account', 'VALUE'=>"#{account}") else cgi.input('TYPE'=>'text', 'NAME'=>'Account') end + "\n" + "Password " + cgi.input('TYPE'=>'password', 'NAME'=>'Password') end + "\n" + cgi.p do cgi.input('TYPE'=>'submit', 'NAME'=>'Submit') + " " + cgi.input('TYPE'=>'reset', 'NAME'=>'Reset') end end + "\n" + # cgi.form cgi.div('CLASS'=>'footer', 'ALIGN'=>"right") do cgi.a('HREF'=>'http://mstk.que.jp/scripts/') do "Mail Checker" end + cgi.br + "\nPowered by " + cgi.a('HREF'=>'http://www.ruby-lang.org/') do "Ruby" end + " version #{RUBY_VERSION}" end + (if !(retrlist.empty? || holder.nil? || holder.idlist.nil?) retrlist.sort! do |id1, id2| holder.idlist.index(id1) <=> holder.idlist.index(id2) end "\n" + retrlist.collect do |id| cgi.hr + cgi.pre do (NKF::nkf('-me', holder[id].content).gsub(/&/,'&').gsub(//,'>').gsub(/\t/, ' ')) end + "\n" end.join end).to_s end #cgi.body end # cgi.html end # cgi.out exit