#!/usr/bin/env ruby
#
# Hardcoded MHonArc-to-NNTP gateway (v0.1)
# use with MS Outlook Express only 
# (due to rapid developing, supported protocol is very few, but
#		it is sufficient for Outlook Express News viewing)
#
#     2002.6.1. Yang, Chul-Woong (cwyang@aratech.co.kr)
#
# borrowed code from 2ch-nntpd by Daiki Ueno
#
# if you manage MHonArc mailing archive on the web, you can use this
# program to export that to Outlook Express
#
# usage: tcpserver -q 0 [news_port] [this script path]
# 
# Put this script to MHonArc archive root, and make index file as follows
#
# cwyang> $cat news.list
# news
# test
# discussion
# cwyang> ls
# news/ test/ discussion/ news.rb news.list
#

require 'socket'
require 'cgi'

server = Socket.gethostname
$idxfname = "news.list"
$news_prefix = "ara."
$organization = "ARA Networks"
$base_url = "http://foo.aratech.co.kr/mhonarc-list/"
group = nil

def write (str)
		$stdout.write(str.chomp.sub(/\z/, "\n").gsub(/\n/, "\r\n"))
		$stdout.flush
end

def greeting(server)
	write "201 #{server} cwyang's MHonArc-to-NNTP gateway (no posting))."
end

def boardscan
    $boards = {}
    file = File.new ($idxfname)
    file.each do |boardname|
	num = 0
	boardname.chop!
	Dir.entries(boardname).each do |fname|
	    if fname =~ /\Amsg.*html\z/i then
		num=num+1
	    end
	end
	$boards[$news_prerfix+boardname] = [boardname, num]
    end
end

def gethdr(group, index, hdrname)
    if hdrname =~ /message-id/i
	return getexthdr(group, index, hdrname)
    elsif hdrname =~ /references/i
	return getexthdr(group, index, hdrname)
    end
    index = index - 1
    foo = "00000" + index.to_s
    fname = $boards[group][0]+"/msg"+foo[-5..-1]+".html"
    file = File.new(fname)
    file.each do |line|
	if line =~ /<li><b>(#{hdrname}):<\/b>([^<]+)</i
	    return CGI.unescapeHTML($2)
	end
    end
    return "unknown"
end

def getexthdr(group, index, hdrname)
    index = index - 1
    foo = "00000" + index.to_s
    fname = $boards[group][0]+"/msg"+foo[-5..-1]+".html"
    file = File.new(fname)
    if hdrname =~ /message-id/i
	str = "X-Message-Id"
    elsif hdrname =~ /references/i
	str = "X-Reference"
    else
	str = "X-foo"
    end
    file.each do |line|
	if line =~ /<!--#{str}: (\S+) -->/
	    return $1
	end
    end
    return "#{index}"
end

def writebody(group, index)
    index = index - 1
    foo = "00000" + index.to_s
    fname = $boards[group][0]+"/msg"+foo[-5..-1]+".html"
    file = File.new(fname)
    file.each do |line|
	write (line)
    end
end

boardscan()
greeting(server)

while $stdin.gets
	cmds = $_.split
	case cmds[0]
	when /\Ahelp\z/i
		write <<EOF
100 Legal commands
  group newsgroup
  mode
  help
  list active
  quit
  xhdr subject range 
  article [MessageID|Number]
.
EOF
	when /\Aquit\z/i
		write "205 ."
		exit
	when /\Amode\z/i
		greeting(server)
	when /\Alist\z/i
		write "215 list of newsgroups follows"
		boardscan()
		$boards.each do |key, val|
			write "#{key} 1 #{val[1]} n"
		end
		write "."
	when /\Agroup\z/i	
		if data = $boards[cmds[1]]
			write "211 #{data[1]} 1 #{data[1]} #{cmds[1]}"
			group = cmds[1]
		else
			write "411 No such group #{cmds[1]} #{$boards}"
		end
	when /\Axhdr\z/i		
		unless group
			write "412 Not in a newsgroup"
			next
		end
		cat = cmds[1]
		range = cmds[2].split('-')
		s = range[0].to_i
		e = range[1].to_i
		write "221 Header follows"

		for i in s..e
			res = gethdr(group, i, cat)
			write "#{i} #{res.strip}"
		end
		write "."
	when /\Aarticle\z/i			
		unless group
			write "412 Not in a newsgroup"
			next
		end
		subject = $boards[group][0]
		total = $boards[group][1]
		num = cmds[1]
		if num =~ /\A\d+\z/
			num = num.to_i
			if num < 1 or num > total
				write "423 Bad article number"
				next
			end
		else
			next		# optimistic case.
		end

		write "220 #{num} #{num} article"
		write "Subject: "+ gethdr(group, num, "subject");
		write "From: "+ gethdr(group, num, "from");
		write "To: "+ gethdr(group, num, "to");
		write "Newsgroups: "+ group;
		write "Organization: " + $organization;
		write "Content-Type: text/html;"
		write ""
		write '<html><base href="'+$baseurl+subject+'/">'
		writebody(group, num)
		write "."
	else
		write "500 What? #{cmds}"		
	end						
end