1#! /usr/local/bin/ruby
2
3require "time"
4require "kconv"
5
6class String
7  def kjust(len)
8    res = ''
9    rlen = 0
10    self.each_char do |char|
11      delta = char.bytesize > 1 ? 2 : 1
12      break if rlen + delta > len
13      rlen += delta
14      res += char
15    end
16    res += ' ' * (len - rlen) if rlen < len
17    res
18  end
19end
20
21def fromout(date, from, subj)
22  return 0 if !date
23  y, m, d = Time.parse(date).to_a.reverse[4, 3] if date
24  y ||= 0; m ||= 0; d ||= 0
25  from ||= "sombody@somewhere"
26  from.delete!("\r\n")
27  from = from.kconv(Encoding.default_external).kjust(28)
28  subj ||= "(nil)"
29  subj.delete!("\r\n")
30  subj = subj.kconv(Encoding.default_external).kjust(40)
31  printf "%02d/%02d/%02d [%s] %s\n", y%100, m, d, from, subj
32  return 1
33end
34
35def get_mailfile(user)
36  file = user
37  unless user
38    file = ENV['MAIL']
39    user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME']
40  end
41
42  if file == nil or !File.exist?(file)
43    [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
44      path = "#{m}/mail/#{user}"
45      if File.exist?(path)
46	file = path
47	break
48      end
49    end
50  end
51  file
52end
53
54def from_main
55  if ARGV[0] == '-w'
56    wait = true
57    ARGV.shift
58  end
59  file = get_mailfile(ARGV[0])
60
61  outcount = 0
62  if File.exist?(file)
63    atime = File.atime(file)
64    mtime = File.mtime(file)
65    open(file, "r") do |f|
66      until f.eof?
67	header = {}
68	f.each_line do |line|
69	  next if /^From / =~ line # skip From-line
70	  break if /^$/ =~ line	 # end of header
71
72	  if /^(?<attr>\S+?):\s*(?<value>.*)/ =~ line
73	    attr.capitalize!
74	    header[attr] = value
75	  elsif attr
76	    header[attr] += "\n" + line.lstrip
77	  end
78	end
79
80	f.each_line do |line|
81	  break if /^From / =~ line
82	end
83	outcount += fromout(header['Date'], header['From'], header['Subject'])
84      end
85    end
86    File.utime(atime, mtime, file)
87  end
88
89  if outcount == 0
90    print "You have no mail.\n"
91    sleep 2 if wait
92  elsif wait
93    system "stty cbreak -echo"
94    $stdin.getc
95    system "stty cooked echo"
96  end
97end
98
99if __FILE__ == $0
100  from_main
101end
102
103__END__
104
105=begin
106
107= from.rb
108
109== USAGE
110
111ruby from.rb [-w] [username_or_filename]
112
113=end
114