#! /usr/bin/ruby DOMAINNAME = "oku.edu.mie-u.ac.jp" COUNTDIR = "/var/oml/" def incr_count(countfile) c = 0 begin File.open(countfile, "r+") do |f| f.flock(File::LOCK_EX) x = f.read(4) c = ((x[0] * 256 + x[1]) * 256 + x[2]) * 256 + x[3] + 1 x[0] = (c >> 24) & 255 x[1] = (c >> 16) & 255 x[2] = (c >> 8) & 255 x[3] = c & 255 f.rewind f.write(x[0..3]) f.flock(File::LOCK_UN) end rescue File.open(countfile, "w") do |f| f.flock(File::LOCK_EX) f.write("\000\000\000\001") c = 1 f.flock(File::LOCK_UN) end end return c end def getheader $buf = gets() if $buf == nil if $buf == nil or $buf =~ /\A[\r\n]*\z/ return nil end line = $buf $buf = gets() while $buf =~ /\A[ \t]/ line += $buf $buf = gets() end return line end opt = Hash.new # command-line options while ARGV[0] =~ /^-(.)$/ ARGV.shift opt[$1] = true end mlname = ARGV[0]; ARGV.shift distfile = ARGV[0]; ARGV.shift distname = ARGV[0]; ARGV.shift exit if mlname == nil distname = "dist-" + mlname if distname == nil subjectregexp = Regexp.new('\Asubject\:\s*(re\:\s*)*(\[' + mlname + '(:\d+)?\]\s*)?(.*)\z', Regexp::IGNORECASE | Regexp::MULTILINE) header = "" subject = "\n" envfrom = nil fromlist = nil while line = getheader if line =~ /\Afrom\s+((\S*).*)\z/mi header += "X-Envelope-From: #{$1}" envfrom = $2 elsif line =~ /\Afrom:(.*)\z/mi fromlist = $1 if opt['f'] header += "From: #{mlname}@#{DOMAINNAME}\n" header += "X-" + line else header += line end elsif line =~ /\Adisposition-notification-to:(.*)\z/mi # do nothing elsif !opt['r'] and line =~ /\Areply-to:(.*)\z/mi header += "X-" + line elsif line =~ subjectregexp subject = $4 else header += line end end if !fromlist ok = false elsif fromlist =~ /viagra/i # 例 ok = false elsif distfile ok = false if opt['e'] and envfrom lowerfromlist = envfrom.downcase else lowerfromlist = fromlist.downcase end File.foreach(distfile) do |line| if line =~ /^\#\-\s*(\S*)/ ok = false if lowerfromlist.include?($1.downcase) elsif line =~ /^\#?\s*(\S*)\s*\(.*?\)\s*$/ ok = true if lowerfromlist.include?($1.downcase) elsif line =~ /^\#?\s*(\S*)/ ok = true if lowerfromlist.include?($1.downcase) end end else ok = true end if ok count = incr_count("#{COUNTDIR}#{mlname}.cnt") if opt['f'] header += "Subject: " # 携帯でSubject:が長いと読みにくいということなので elsif opt['c'] header += "Subject: [#{mlname}] " else header += sprintf("Subject: [%s:%04d] ", mlname, count) end else header += sprintf("Subject: Undelivered: [%s] ", mlname) end header += subject header += "Reply-To: #{mlname}@#{DOMAINNAME}\n" if !opt['r'] header += "Errors-To: #{mlname}-admin@#{DOMAINNAME}\n" if ok pipe = "|/usr/sbin/sendmail -oi -f #{mlname}-admin #{distname}" else pipe = "|/usr/sbin/sendmail -oi -f #{mlname}-admin #{mlname}-admin" end open(pipe, "w") do |p| p.print header p.print "\n" while line = gets p.print line end end