summaryrefslogtreecommitdiff
path: root/lib/net/smtp.rb
blob: 9f534c20c00512b27cba3fd50229c264e69d28b6 (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
#
# smtp.rb  version 1.0.1
#
#   author Minero Aoki <aamine@dp.u-netsurf.ne.jp>
#

require 'net/session'


module Net

  class SMTPSession < Session

    def proto_initialize
      @proto_type = SMTPCommand
      @port       = 25
    end

    def sendmail( mailsrc, fromaddr, toaddrs )
      @proto.mailfrom( fromaddr )
      @proto.rcpt( toaddrs )
      @proto.data
      @proto.sendmail( mailsrc )
    end


    private


    def do_start( helodom = nil )
      unless helodom then
        helodom = ENV[ 'HOSTNAME' ]
      end
      @proto.helo( helodom )
    end

    def do_finish
      @proto.quit
    end

  end

  SMTP = SMTPSession



  class SMTPCommand < Command

    def helo( fromdom )
      @socket.writeline( 'HELO ' << fromdom )
      check_reply( SuccessCode )
    end


    def mailfrom( fromaddr )
      @socket.writeline( 'MAIL FROM:<' + fromaddr + '>' )
      check_reply( SuccessCode )
    end


    def rcpt( toaddrs )
      toaddrs.each do |i|
        @socket.writeline( 'RCPT TO:<' + i + '>' )
        check_reply( SuccessCode )
      end
    end


    def data
      @socket.writeline( 'DATA' )
      check_reply( ContinueCode )
    end


    def sendmail( mailsrc )
      @socket.write_pendstr( mailsrc )
      check_reply( SuccessCode )
    end


    private


    def do_quit
      @socket.writeline( 'QUIT' )
      check_reply( SuccessCode )
    end


    def get_reply
      arr = read_reply
      stat = arr[0][0,3]

      cls = UnknownCode
      case stat[0]
      when ?2 then cls = SuccessCode
      when ?3 then cls = ContinueCode
      when ?4 then cls = ServerBusyCode
      when ?5 then
        case stat[1]
        when ?0 then cls = SyntaxErrorCode
        when ?5 then cls = FatalErrorCode
        end
      end

      return cls.new( stat, arr.join('') )
    end


    def read_reply
      arr = []

      while (str = @socket.readline)[3] == ?- do   # ex: "210-..."
        arr.push str
      end
      arr.push str

      return arr
    end

  end


  unless Session::Version == '1.0.1' then
    $stderr.puts "WARNING: wrong version of session.rb & smtp.rb"
  end

end