summaryrefslogtreecommitdiff
path: root/sample/from.rb
blob: f21b1d10f5950949119488908e50ec5602c1c520 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#! /usr/local/bin/ruby

module ParseDate
  MONTHS = {
    'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
    'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
    'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 }
  MONTHPAT = MONTHS.keys.join('|')
  DAYPAT = 'mon|tue|wed|thu|fri|sat|sun'
  
  def parsedate(date) 
    if date.sub(/(#{DAYPAT})/i, ' ')
      dayofweek = $1
    end
    if date.sub(/\s+(\d+:\d+(:\d+)?)/, ' ')
      time = $1
    end
    if date =~ /19(\d\d)/
      year = $1
    end
    if date.sub(/\s*(\d+)\s+(#{MONTHPAT})\S*\s+/i, ' ')
      dayofmonth = $1
      monthname  = $2
    elsif date.sub(/\s*(#{MONTHPAT})\S*\s+(\d+)\s+/i, ' ')
      monthname  = $1
      dayofmonth = $2
    elsif date.sub(/\s*(#{MONTHPAT})\S*\s+(\d+)\D+/i, ' ')
      monthname  = $1
      dayofmonth = $2
    elsif date.sub(/\s*(\d\d?)\/(\d\d?)/, ' ')
      month  = $1
      dayofmonth = $2
    end
    if monthname
      month = MONTHS[monthname.tolower]
    end
    if ! year && date =~ /\d\d/
      year = $&
    end
    return year, month, dayofmonth
  end

end

include ParseDate

def decode64(str)
  e = -1;
  c = ","
  for line in str.split("\n")
    line.tr 'A-Za-z0-9+/', "\000-\377"
    line.each_byte { |ch|
      e+=1
      if e==0
	c = ch << 2
      elsif e==1
	c |= ch >>4
	string += [c].pack('c')
	c = ch << 4
      elsif e == 2
	c |= ch >> 2
	string += [c].pack('c'); 
	c = ch << 6
      elsif e==3
	c |= ch
	string += [c].pack('c')
	e = -1;
      end
    }
  end
  return string;
end

def j2e(str)
  while str =~ /\033\$B([^\033]*)\033\(B/
    s = $1
    pre, post = $`, $'
    s.gsub(/./) { |ch|
      (ch[0]|0x80).chr
    }
    str = pre + s + post
  end
  str
end

def decode_b(str)
  while str =~ /=\?ISO-2022-JP\?B\?(.*)=\?=/
    pre, post = $`, $'
    s = decode64($1)
    str =  pre + s + post
  end
  j2e(str)
end

if $ARGV[0] == '-w'
  wait = TRUE
  $ARGV.shift
end

class Mail

  def Mail.new(f)
    if !f.is_kind_of(IO)
      f = open(f, "r")
      me = super
      f.close
    else
      me = super
    end
    return me
  end

  def initialize(f)
    @header = {}
    @body = []
    while f.gets()
      $_.chop
      continue if /^From /	# skip From-line  
      break if /^[ \t]*$/	# end of header
      if /^(\S+):\s*(.*)/
	@header[attr = $1.capitalize] = $2
      elsif attr
	sub(/^\s*/, '')
	@header[attr] += "\n" + $_
      end
    end

    return if ! $_

    while f.gets()
      break if /^From /
      @body.push($_)
    end
  end

  def header
    return @header
  end

  def body
    return @body
  end

end

$ARGV[0] = '/usr/spool/mail/' + ENV['USER'] if $ARGV.length == 0

$outcount = 0;
def fromout(date, from, subj)
  return if !date
  y = m = d = 0
  y, m, d = parsedate(date) if date
  from = "sombody@somewhere" if ! from
  subj = "(nil)" if ! subj
  from = decode_b(from)
  subj = decode_b(subj)
  printf "%-02d/%02d/%02d [%-28.28s] %-40.40s\n", y, m, d, from, subj
  $outcount += 1
end

for file in $ARGV
  continue if !File.exists(file)
  f = open(file, "r")
  while !f.eof
    mail = Mail.new(f)
    fromout mail.header['Date'], mail.header['From'], mail.header['Subject']
  end
  f.close
end

if $outcount == 0
  print "You have no mail.\n"
  sleep 2 if wait
elsif wait
  system "stty cbreak -echo"
  getc()
  system "stty cooked echo"
end