summaryrefslogtreecommitdiff
path: root/sample/net-imap.rb
blob: b93ecb746e699699431ebe515cadd4e0b08e09f7 (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
require 'net/imap'
require "getoptlong"

$stdout.sync = true
$port = nil
$user = ENV["USER"] || ENV["LOGNAME"]
$auth = "login"
$ssl = false
$starttls = false

def usage
  <<EOF
usage: #{$0} [options] <host>

  --help                        print this message
  --port=PORT                   specifies port
  --user=USER                   specifies user
  --auth=AUTH                   specifies auth type
  --starttls                    use starttls
  --ssl                         use ssl
EOF
end

begin
  require 'io/console'
rescue LoadError
  def _noecho(&block)
    system("stty", "-echo")
    begin
      yield STDIN
    ensure
      system("stty", "echo")
    end
  end
else
  def _noecho(&block)
    STDIN.noecho(&block)
  end
end

def get_password
  print "password: "
  begin
    return _noecho(&:gets).chomp
  ensure
    puts
  end
end

def get_command
  printf("%s@%s> ", $user, $host)
  if line = gets
    return line.strip.split(/\s+/)
  else
    return nil
  end
end

parser = GetoptLong.new
parser.set_options(['--debug', GetoptLong::NO_ARGUMENT],
  ['--help', GetoptLong::NO_ARGUMENT],
  ['--port', GetoptLong::REQUIRED_ARGUMENT],
  ['--user', GetoptLong::REQUIRED_ARGUMENT],
  ['--auth', GetoptLong::REQUIRED_ARGUMENT],
  ['--starttls', GetoptLong::NO_ARGUMENT],
  ['--ssl', GetoptLong::NO_ARGUMENT])
begin
  parser.each_option do |name, arg|
    case name
    when "--port"
      $port = arg
    when "--user"
      $user = arg
    when "--auth"
      $auth = arg
    when "--ssl"
      $ssl = true
    when "--starttls"
      $starttls = true
    when "--debug"
      Net::IMAP.debug = true
    when "--help"
      usage
      exit
    end
  end
rescue
  abort usage
end

$host = ARGV.shift
unless $host
  abort usage
end

imap = Net::IMAP.new($host, :port => $port, :ssl => $ssl)
begin
  imap.starttls if $starttls
  class << password = method(:get_password)
    alias to_str call
  end
  imap.authenticate($auth, $user, password)
  while true
    cmd, *args = get_command
    break unless cmd
    begin
      case cmd
      when "list"
        for mbox in imap.list("", args[0] || "*")
          if mbox.attr.include?(Net::IMAP::NOSELECT)
            prefix = "!"
          elsif mbox.attr.include?(Net::IMAP::MARKED)
            prefix = "*"
          else
            prefix = " "
          end
          print prefix, mbox.name, "\n"
        end
      when "select"
        imap.select(args[0] || "inbox")
        print "ok\n"
      when "close"
        imap.close
        print "ok\n"
      when "summary"
        unless messages = imap.responses["EXISTS"][-1]
          puts "not selected"
          next
        end
        if messages > 0
          for data in imap.fetch(1..-1, ["ENVELOPE"])
            print data.seqno, ": ", data.attr["ENVELOPE"].subject, "\n"
          end
        else
          puts "no message"
        end
      when "fetch"
        if args[0]
          data = imap.fetch(args[0].to_i, ["RFC822.HEADER", "RFC822.TEXT"])[0]
          puts data.attr["RFC822.HEADER"]
          puts data.attr["RFC822.TEXT"]
        else
          puts "missing argument"
        end
      when "logout", "exit", "quit"
        break
      when "help", "?"
        print <<EOF
list [pattern]                  list mailboxes
select [mailbox]                select mailbox
close                           close mailbox
summary                         display summary
fetch [msgno]                   display message
logout                          logout
help, ?                         display help message
EOF
      else
        print "unknown command: ", cmd, "\n"
      end
    rescue Net::IMAP::Error
      puts $!
    end
  end
ensure
  imap.logout
  imap.disconnect
end