vpopmail 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/emailcheck.rb +97 -9
- data/examples/vdelfakemail.rb +131 -0
- data/examples/vlearn.rb +49 -12
- data/lib/vpopmail.rb +3 -3
- data/lib/vpopmail/domain.rb +2 -2
- data/lib/vpopmail/folder.rb +2 -2
- data/lib/vpopmail/imapdb.rb +3 -3
- data/lib/vpopmail/message.rb +67 -18
- data/lib/vpopmail/user.rb +2 -2
- metadata +3 -2
data/examples/emailcheck.rb
CHANGED
@@ -1,11 +1,99 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2006 (c) Gildas Cherruel
|
4
|
+
# All rights reserved.
|
5
|
+
# See LICENSE.txt for permissions.
|
6
|
+
#++
|
3
7
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
VPOPMail::logger = log
|
8
|
+
require 'rubygems'
|
9
|
+
require 'getoptlong'
|
10
|
+
require_gem 'vpopmail'
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
$APPNAME = File::basename(__FILE__, '.rb')
|
13
|
+
$log = nil
|
14
|
+
$VERBOSE = true
|
15
|
+
$OPTS = GetoptLong.new(
|
16
|
+
["--domain", "-d", GetoptLong::REQUIRED_ARGUMENT],
|
17
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
18
|
+
["--log", GetoptLong::OPTIONAL_ARGUMENT],
|
19
|
+
["--silent", "-s", GetoptLong::NO_ARGUMENT],
|
20
|
+
["--verbose", "-v", GetoptLong::NO_ARGUMENT])
|
21
|
+
|
22
|
+
#------------------------------------------------------------------------------------------
|
23
|
+
# function: Verbose {{{
|
24
|
+
def Verbose(p_string)
|
25
|
+
$log.info p_string if !$log.nil?
|
26
|
+
puts p_string if $VERBOSE
|
27
|
+
end # }}}
|
28
|
+
|
29
|
+
#------------------------------------------------------------------------------------------
|
30
|
+
# function: usage {{{
|
31
|
+
def usage(p_error = nil, p_errno = 0, p_wantQuit = true)
|
32
|
+
puts "Usage: #{__FILE__} [options] [email_address]"
|
33
|
+
puts "Error: #{p_error}" if ! p_error.nil?
|
34
|
+
puts "Options:"
|
35
|
+
puts " -d domain, --domain=domain Sets the domain to use when querying remote Mail servers"
|
36
|
+
puts " -h, --help Prints this help."
|
37
|
+
puts " --log[=file], -l [file] Will log in [file] or /var/log/#{$APPNAME}.log"
|
38
|
+
puts " The application does not log by default."
|
39
|
+
puts " -s, --silent Proceed silently."
|
40
|
+
puts " -v, --verbose Proceed verbosely."
|
41
|
+
exit p_errno if p_wantQuit
|
42
|
+
end # }}}
|
43
|
+
|
44
|
+
#------------------------------------------------------------------------------------------
|
45
|
+
# function: find_domain {{{
|
46
|
+
def find_postmaster(p_domainname = nil)
|
47
|
+
if p_domainname.nil? or p_domainname.empty? then
|
48
|
+
begin
|
49
|
+
IO.foreach('/etc/resolv.conf') do |line|
|
50
|
+
line.gsub!(/\s*[;#].*/,"")
|
51
|
+
next unless line =~ /\S/
|
52
|
+
case line
|
53
|
+
when /^\s*domain\s+(\S+)/
|
54
|
+
p_domainname = $1
|
55
|
+
break
|
56
|
+
when /^\s*search\s+(.*)/
|
57
|
+
p_domainname = $1.split(" ").first
|
58
|
+
break
|
59
|
+
end
|
60
|
+
end
|
61
|
+
rescue
|
62
|
+
p_domainname= 'localdomain'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
return "postmaster@#{p_domainname}"
|
66
|
+
end # }}}
|
67
|
+
|
68
|
+
#------------------------------------------------------------------------------------------
|
69
|
+
# main {{{
|
70
|
+
domainname = nil
|
71
|
+
logfile = nil
|
72
|
+
|
73
|
+
$OPTS.each {|opt, arg| # {{{
|
74
|
+
case opt
|
75
|
+
when "--domain" then domainname = arg
|
76
|
+
when "--help" then usage()
|
77
|
+
when "--log" then logfile = arg.empty? ? "/var/log/qmail/#{$APPNAME}.log" : arg
|
78
|
+
when "--silent" then $VERBOSE = false
|
79
|
+
when "--verbose" then $VERBOSE = true
|
80
|
+
end
|
81
|
+
} # }}}
|
82
|
+
|
83
|
+
if !logfile.nil? then
|
84
|
+
require 'logger'
|
85
|
+
$log = Logger.new(logfile)
|
86
|
+
VPOPMail::logger = $log
|
87
|
+
$log.info "=========================== Starting #{$APPNAME}"
|
88
|
+
end
|
89
|
+
|
90
|
+
if ARGV.size == 0 then
|
91
|
+
$log.error "There is no email to validate!" if !$log.nil?
|
92
|
+
usage("Missing email address argument")
|
93
|
+
exit 1
|
94
|
+
end
|
95
|
+
address = ARGV[0]
|
96
|
+
valid = VPOPMail::Message.validAddress?(address, find_postmaster(domainname))
|
97
|
+
Verbose "Address #{address} is " + (valid ? "valid" : "invalid")
|
98
|
+
exit valid ? 0 : 1
|
99
|
+
# }}}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2006 (c) Gildas Cherruel
|
4
|
+
# All rights reserved.
|
5
|
+
# See LICENSE.txt for permissions.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'getoptlong'
|
10
|
+
require 'net/smtp'
|
11
|
+
require_gem 'vpopmail'
|
12
|
+
|
13
|
+
$APPNAME = File::basename(__FILE__, '.rb')
|
14
|
+
$log = nil
|
15
|
+
$dryrun = false
|
16
|
+
$VERBOSE = true
|
17
|
+
$OPTS = GetoptLong.new(
|
18
|
+
["--domain", "-d", GetoptLong::REQUIRED_ARGUMENT],
|
19
|
+
["--folder", "-f", GetoptLong::REQUIRED_ARGUMENT],
|
20
|
+
["--user", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
21
|
+
|
22
|
+
["--dry-run", "-n", GetoptLong::NO_ARGUMENT],
|
23
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
24
|
+
["--log", GetoptLong::OPTIONAL_ARGUMENT],
|
25
|
+
["--silent", "-s", GetoptLong::NO_ARGUMENT],
|
26
|
+
["--verbose", "-v", GetoptLong::NO_ARGUMENT])
|
27
|
+
|
28
|
+
#------------------------------------------------------------------------------------------
|
29
|
+
# function: Verbose {{{
|
30
|
+
def Verbose(p_string)
|
31
|
+
$log.info p_string if !$log.nil?
|
32
|
+
puts p_string if $VERBOSE
|
33
|
+
end # }}}
|
34
|
+
|
35
|
+
#------------------------------------------------------------------------------------------
|
36
|
+
# function: usage {{{
|
37
|
+
def usage(p_error = nil, p_errno = 0, p_wantQuit = true)
|
38
|
+
puts "Usage: #{__FILE__} [options]"
|
39
|
+
puts "Error: #{p_error}" if ! p_error.nil?
|
40
|
+
puts "Options:"
|
41
|
+
puts " -d domain, --domain=domain Will work only on this vpopmail domain. (Default: all)"
|
42
|
+
puts " -f folder, --folder=folder Will work only on this vpopmail folder. (Default: inbox)"
|
43
|
+
puts " -u user, --user=user Will work only on this vpopmail user. (Default: all)"
|
44
|
+
puts " -h, --help Prints this help."
|
45
|
+
puts " --log[=file], -l [file] Will log in [file] or /var/log/#{$APPNAME}.log"
|
46
|
+
puts " The application does not log by default."
|
47
|
+
puts " -n, --dry-run Do not delete any message."
|
48
|
+
puts " -s, --silent Proceed silently."
|
49
|
+
puts " -v, --verbose Proceed verbosely."
|
50
|
+
exit p_errno if p_wantQuit
|
51
|
+
end # }}}
|
52
|
+
|
53
|
+
#------------------------------------------------------------------------------------------
|
54
|
+
# function: validate {{{
|
55
|
+
def validate(p_message, p_folder, p_cache = {})
|
56
|
+
Verbose "Processing: #{p_message.id}"
|
57
|
+
email = p_message.header.reply_to.first
|
58
|
+
email = RMail::Address.parse(p_message.header["Return-Path"])[0] if email.nil?
|
59
|
+
begin
|
60
|
+
valid = p_cache.include?(email) ? p_cache[email] : p_message.validAddress?(email)
|
61
|
+
p_cache[email] = valid
|
62
|
+
Verbose "address: #{email.address} is " + (valid ? "valid" : "invalid")
|
63
|
+
p_message.deleteFrom(p_folder) if !$dryrun && !valid
|
64
|
+
rescue Net::SMTPServerBusy =>p_e
|
65
|
+
Verbose "Impossible to validate address #{email.address}, #{p_e}"
|
66
|
+
end
|
67
|
+
return p_cache
|
68
|
+
end # }}}
|
69
|
+
|
70
|
+
#------------------------------------------------------------------------------------------
|
71
|
+
# main {{{
|
72
|
+
domainname = nil
|
73
|
+
foldername = nil
|
74
|
+
username = nil
|
75
|
+
logfile = nil
|
76
|
+
|
77
|
+
$OPTS.each {|opt, arg| # {{{
|
78
|
+
case opt
|
79
|
+
when "--domain" then domainname = arg
|
80
|
+
when "--folder" then foldername = arg
|
81
|
+
when "--user" then username = arg
|
82
|
+
|
83
|
+
when "--dry-run" then $dryrun = true
|
84
|
+
when "--help" then usage()
|
85
|
+
when "--log" then logfile = arg.empty? ? "/var/log/qmail/#{$APPNAME}.log" : arg
|
86
|
+
when "--silent" then $VERBOSE = false
|
87
|
+
when "--verbose" then $VERBOSE = true
|
88
|
+
end
|
89
|
+
} # }}}
|
90
|
+
|
91
|
+
if !logfile.nil? then
|
92
|
+
require 'logger'
|
93
|
+
$log = Logger.new(logfile)
|
94
|
+
VPOPMail::logger = $log
|
95
|
+
$log.info "=========================== Starting #{$APPNAME}"
|
96
|
+
end
|
97
|
+
|
98
|
+
if domainname.nil? and username =~ /(.*)@(.*)/ then
|
99
|
+
username = $1
|
100
|
+
domainname = $2
|
101
|
+
end
|
102
|
+
|
103
|
+
if !domainname.nil? and !username.nil? then
|
104
|
+
domain = VPOPMail::Domain.FindDomains(domainname)[0]
|
105
|
+
Verbose "Analyzing domain #{domain.name}"
|
106
|
+
user = VPOPMail::User.FindUsers(domain, username)[0]
|
107
|
+
Verbose "Analyzing user #{user.name}"
|
108
|
+
folder = VPOPMail::Folder.new(user, foldername)
|
109
|
+
Verbose "Analyzing folder #{folder}, size = #{folder.size}"
|
110
|
+
messageid = ARGV.size == 0 ? nil : ARGV[0]
|
111
|
+
|
112
|
+
if !messageid.nil? and !messageid.empty? then
|
113
|
+
message = VPOPMail::Message.new(folder, messageid)
|
114
|
+
validate(message, folder)
|
115
|
+
else
|
116
|
+
cache = {}
|
117
|
+
folder.each {|message| cache = validate(message, folder, cache) }
|
118
|
+
end
|
119
|
+
else
|
120
|
+
cache = {}
|
121
|
+
VPOPMail::Domain.FindDomains.each { |domain|
|
122
|
+
Verbose "Analyzing domain #{domain.name}"
|
123
|
+
VPOPMail::User.FindUsers(domain).each { |user|
|
124
|
+
Verbose "Analyzing user #{user.name}"
|
125
|
+
folder = VPOPMail::Folder.new(user) # Opening the inbox
|
126
|
+
Verbose "Analyzing folder #{folder}, size = #{folder.size}"
|
127
|
+
folder.each {|message| cache = validate(message, folder, cache) }
|
128
|
+
}
|
129
|
+
}
|
130
|
+
end
|
131
|
+
exit 0
|
data/examples/vlearn.rb
CHANGED
@@ -1,47 +1,67 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2006 (c) Gildas Cherruel
|
4
|
+
# All rights reserved.
|
5
|
+
# See LICENSE.txt for permissions.
|
6
|
+
#++
|
7
|
+
|
8
|
+
require 'rubygems'
|
2
9
|
require 'getoptlong'
|
3
|
-
|
10
|
+
require_gem 'vpopmail'
|
4
11
|
|
5
12
|
$CFG = { "Junk Folder" => "Junk E-mails",
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
"Learn SPAM Folder" => "Learn Junk",
|
14
|
+
"Learn HAM Folder" => "Learn Good",
|
15
|
+
"archive user" => "postmaster",
|
16
|
+
"archive SPAM Folder" => "SPAM",
|
17
|
+
"archive HAM Folder" => "HAM",
|
18
|
+
}
|
12
19
|
|
20
|
+
$APPNAME = File::basename(__FILE__, '.rb')
|
21
|
+
$log = nil
|
22
|
+
$dryrun = false
|
13
23
|
$VERBOSE = true
|
14
24
|
$OPTS = GetoptLong.new(
|
15
25
|
["--domain", "-d", GetoptLong::REQUIRED_ARGUMENT],
|
16
26
|
["--folder", "-f", GetoptLong::REQUIRED_ARGUMENT],
|
17
27
|
["--ham", GetoptLong::NO_ARGUMENT],
|
18
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
19
|
-
["--silent", "-s", GetoptLong::NO_ARGUMENT],
|
20
28
|
["--spam", GetoptLong::NO_ARGUMENT],
|
21
29
|
["--user", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
30
|
+
|
31
|
+
["--dry-run", "-n", GetoptLong::NO_ARGUMENT],
|
32
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
33
|
+
["--log", GetoptLong::OPTIONAL_ARGUMENT],
|
34
|
+
["--silent", "-s", GetoptLong::NO_ARGUMENT],
|
22
35
|
["--verbose", "-v", GetoptLong::NO_ARGUMENT])
|
23
36
|
|
24
37
|
#------------------------------------------------------------------------------------------
|
25
38
|
# function: Verbose {{{
|
26
39
|
def Verbose(p_string)
|
40
|
+
$log.info p_string if !$log.nil?
|
27
41
|
puts p_string if $VERBOSE
|
28
42
|
end # }}}
|
29
43
|
|
44
|
+
#------------------------------------------------------------------------------------------
|
30
45
|
# function: usage {{{
|
31
46
|
def usage(p_error = nil, p_errno = 0, p_wantQuit = true)
|
32
|
-
puts "Usage:
|
47
|
+
puts "Usage: #{__FILE__} [options] [filename]"
|
33
48
|
puts "Error: #{p_error}" if ! p_error.nil?
|
34
49
|
puts "Options:"
|
35
50
|
puts " -d domain, --domain=domain Will work only on this vpopmail domain. (Default: all)"
|
51
|
+
puts " -f folder, --folder=folder Will work only on this vpopmail folder. (Default: inbox)"
|
36
52
|
puts " -u user, --user=user Will work only on this vpopmail user. (Default: all)"
|
37
53
|
puts " --ham Will consider messages as good messages"
|
38
54
|
puts " --spam Will consider messages as spam/junk messages"
|
39
55
|
puts " -h, --help Prints this help."
|
56
|
+
puts " --log[=file], -l [file] Will log in [file] or /var/log/#{$APPNAME}.log"
|
57
|
+
puts " The application does not log by default."
|
58
|
+
puts " -n, --dry-run Do not delete any message."
|
40
59
|
puts " -s, --silent Proceed silently."
|
41
60
|
puts " -v, --verbose Proceed verbosely."
|
42
61
|
exit p_errno if p_wantQuit
|
43
62
|
end # }}}
|
44
63
|
|
64
|
+
#------------------------------------------------------------------------------------------
|
45
65
|
# function: loadFolder {{{
|
46
66
|
def loadFolder(p_user, p_name = nil)
|
47
67
|
begin
|
@@ -52,24 +72,41 @@ def loadFolder(p_user, p_name = nil)
|
|
52
72
|
end
|
53
73
|
end # }}}
|
54
74
|
|
75
|
+
#------------------------------------------------------------------------------------------
|
55
76
|
# main {{{
|
56
77
|
domainname = nil
|
57
78
|
foldername = nil
|
58
79
|
username = nil
|
59
80
|
kind = nil
|
81
|
+
logfile = nil
|
60
82
|
|
61
|
-
$OPTS.each {|opt, arg|
|
83
|
+
$OPTS.each {|opt, arg| # {{{
|
62
84
|
case opt
|
63
85
|
when "--domain" then domainname = arg
|
64
86
|
when "--folder" then foldername = arg
|
65
87
|
when "--user" then username = arg
|
66
88
|
when "--ham" then kind = "ham"
|
67
89
|
when "--spam" then kind = "spam"
|
90
|
+
|
91
|
+
when "--dry-run" then $dryrun = true
|
68
92
|
when "--help" then usage()
|
93
|
+
when "--log" then logfile = arg.empty? ? "/var/log/qmail/#{$APPNAME}.log" : arg
|
69
94
|
when "--silent" then $VERBOSE = false
|
70
95
|
when "--verbose" then $VERBOSE = true
|
71
96
|
end
|
72
|
-
}
|
97
|
+
} # }}}
|
98
|
+
|
99
|
+
if !logfile.nil? then
|
100
|
+
require 'logger'
|
101
|
+
$log = Logger.new(logfile)
|
102
|
+
VPOPMail::logger = $log
|
103
|
+
$log.info "=========================== Starting #{$APPNAME}"
|
104
|
+
end
|
105
|
+
|
106
|
+
if domainname.nil? and username =~ /(.*)@(.*)/ then
|
107
|
+
username = $1
|
108
|
+
domainname = $2
|
109
|
+
end
|
73
110
|
|
74
111
|
if !domainname.nil? and !username.nil? and !foldername.nil? then
|
75
112
|
domain = VPOPMail::Domain.FindDomains(domainname)[0]
|
data/lib/vpopmail.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: vpopmail.rb
|
6
|
+
# Version: $Id: vpopmail.rb 12 2006-10-09 08:49:52Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
$:.unshift(File.dirname(__FILE__)) unless
|
@@ -27,8 +27,8 @@ module VPOPMail
|
|
27
27
|
module VERSION #:nodoc:
|
28
28
|
MAJOR = 1
|
29
29
|
MINOR = 0
|
30
|
-
TINY =
|
31
|
-
BUILD = %q$Id: vpopmail.rb
|
30
|
+
TINY = 1
|
31
|
+
BUILD = %q$Id: vpopmail.rb 12 2006-10-09 08:49:52Z gildasc $
|
32
32
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
33
33
|
end # }}}
|
34
34
|
|
data/lib/vpopmail/domain.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: domain.rb
|
6
|
+
# Version: $Id: domain.rb 7 2006-10-08 21:06:36Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
require 'rmail'
|
@@ -30,7 +30,7 @@ class Domain
|
|
30
30
|
@@logger = nil
|
31
31
|
def self.logger ; @@logger ; end
|
32
32
|
def self.logger=(p_object) ; @@logger = p_object ; end
|
33
|
-
def logger
|
33
|
+
def logger ; @@logger ; end
|
34
34
|
def logger=(p_object) ; @@logger = p_object ; end
|
35
35
|
# }}}
|
36
36
|
|
data/lib/vpopmail/folder.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: folder.rb
|
6
|
+
# Version: $Id: folder.rb 7 2006-10-08 21:06:36Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
require 'rexml/document'
|
@@ -31,7 +31,7 @@ class Folder
|
|
31
31
|
@@logger = nil
|
32
32
|
def self.logger ; @@logger ; end
|
33
33
|
def self.logger=(p_object) ; @@logger = p_object ; end
|
34
|
-
def logger
|
34
|
+
def logger ; @@logger ; end
|
35
35
|
def logger=(p_object) ; @@logger = p_object ; end
|
36
36
|
# }}}
|
37
37
|
|
data/lib/vpopmail/imapdb.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: imapdb.rb
|
6
|
+
# Version: $Id: imapdb.rb 10 2006-10-09 08:41:47Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
require 'rexml/document'
|
@@ -30,7 +30,7 @@ class IMAPDB
|
|
30
30
|
@@logger = nil
|
31
31
|
def self.logger ; @@logger ; end
|
32
32
|
def self.logger=(p_object) ; @@logger = p_object ; end
|
33
|
-
def logger
|
33
|
+
def logger ; @@logger ; end
|
34
34
|
def logger=(p_object) ; @@logger = p_object ; end
|
35
35
|
# }}}
|
36
36
|
|
@@ -128,7 +128,7 @@ class IMAPDB
|
|
128
128
|
begin
|
129
129
|
lines = IO.readlines(@filename)
|
130
130
|
rescue Errno::ENOENT
|
131
|
-
logger.
|
131
|
+
logger.warn "Folder #{@folder.name}: IMAPDB does not exist, nothing to do" if !@@logger.nil?
|
132
132
|
return Array.new
|
133
133
|
end
|
134
134
|
if lines[0] !~ /^1 (\d+) (\d+)/ then
|
data/lib/vpopmail/message.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: message.rb
|
6
|
+
# Version: $Id: message.rb 9 2006-10-09 01:12:10Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
require 'rexml/document'
|
@@ -27,20 +27,25 @@ class SMTP
|
|
27
27
|
#--------------------------------------------------------------------------------------
|
28
28
|
# method: validAddress? {{{
|
29
29
|
#++
|
30
|
+
#
|
31
|
+
# === Possible Exceptions
|
32
|
+
# * SMTPServerBusy
|
30
33
|
def validAddress?(p_address, p_local)
|
31
34
|
begin
|
32
35
|
mailfrom p_local
|
33
36
|
rcptto p_address
|
34
|
-
|
37
|
+
rescue SMTPServerBusy => p_e
|
38
|
+
raise p_e
|
35
39
|
rescue SMTPFatalError
|
36
|
-
begin
|
37
|
-
getok('RSET')
|
38
|
-
rescue
|
39
|
-
end
|
40
40
|
return false
|
41
41
|
rescue Exception => p_e
|
42
42
|
STDERR.puts "Unknown Error! #{p_e}"
|
43
43
|
return false
|
44
|
+
ensure
|
45
|
+
begin
|
46
|
+
getok('RSET')
|
47
|
+
rescue
|
48
|
+
end
|
44
49
|
end
|
45
50
|
return true
|
46
51
|
end # }}}
|
@@ -66,7 +71,7 @@ class Message
|
|
66
71
|
@@logger = nil
|
67
72
|
def self.logger ; @@logger ; end
|
68
73
|
def self.logger=(p_object) ; @@logger = p_object ; end
|
69
|
-
def logger
|
74
|
+
def logger ; @@logger ; end
|
70
75
|
def logger=(p_object) ; @@logger = p_object ; end
|
71
76
|
# }}}
|
72
77
|
|
@@ -103,28 +108,44 @@ class Message
|
|
103
108
|
# This methods queries the DNS of the domain contains in <tt>p_address</tt> for its
|
104
109
|
# MX Servers. Then it will use the SMTP protocol to query the MX servers for the validity
|
105
110
|
# of <tt>p_address</tt>
|
111
|
+
#
|
112
|
+
# === Possible Exceptions
|
113
|
+
# * SMTPServerBusy
|
106
114
|
def self.validAddress?(p_address, p_local)
|
107
115
|
p_address = RMail::Address.parse(p_address)[0] if !p_address.kind_of? RMail::Address
|
108
116
|
p_local = RMail::Address.parse(p_local)[0] if !p_local.kind_of? RMail::Address
|
109
117
|
|
110
118
|
logger.info "Checking Domain: #{p_address.domain}" if !@@logger.nil?
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
119
|
+
begin
|
120
|
+
resolver = Net::DNS::Resolver.new
|
121
|
+
answer = resolver.query(p_address.domain, Net::DNS::MX)
|
122
|
+
logger.debug "#{answer.inspect}" if !@@logger.nil?
|
123
|
+
if answer.nil? or answer.header.anCount == 0
|
124
|
+
logger.warn "No nameserver found for domain: #{resolver.errorstring}" if !@@logger.nil?
|
125
|
+
return false
|
126
|
+
end
|
127
|
+
hosts = answer.answer.sort {|x, y| x.preference <=> y.preference}
|
128
|
+
rescue Timeout::Error
|
129
|
+
logger.error "Timeout while querying #{p_address.domain}" if !@@logger.nil?
|
130
|
+
return false
|
131
|
+
rescue NameError => p_e
|
132
|
+
logger.error "NameError while querying #{p_address.domain}, #{p_e}" if !@@logger.nil?
|
117
133
|
return false
|
118
134
|
end
|
119
|
-
hosts = answer.answer.sort {|x, y| x.preference <=> y.preference}
|
120
135
|
|
121
136
|
hosts.each { |host|
|
122
137
|
logger.info "Connecting to MX #{host.exchange}" if !@@logger.nil?
|
123
138
|
begin
|
124
139
|
Net::SMTP.start(host.exchange, 25, p_local.domain) { |smtp|
|
125
140
|
logger.debug "Validating #{p_address.address}" if !@@logger.nil?
|
126
|
-
|
141
|
+
valid = smtp.validAddress?(p_address.address, p_local.address)
|
142
|
+
logger.info "#{p_address.address} valid?: #{valid}" if !@@logger.nil?
|
143
|
+
return valid
|
127
144
|
}
|
145
|
+
rescue Net::SMTPServerBusy => p_e
|
146
|
+
# That means the MX Host does not honor the answer
|
147
|
+
logger.error "#{host.exchange} replied #{p_e}" if !@@logger.nil?
|
148
|
+
raise p_e
|
128
149
|
rescue Errno::ETIMEDOUT => p_e
|
129
150
|
# That means the MX Host does not answer
|
130
151
|
logger.warn "timeout in querying #{host.exchange}" if !@@logger.nil?
|
@@ -147,6 +168,26 @@ class Message
|
|
147
168
|
return Message.validAddress?(p_address, @folder.domain.postmaster)
|
148
169
|
end # }}}
|
149
170
|
|
171
|
+
#--------------------------------------------------------------------------------------
|
172
|
+
# method: header {{{
|
173
|
+
#++
|
174
|
+
# Gives the header of the email
|
175
|
+
#
|
176
|
+
# Returns a RMail::Header object
|
177
|
+
def body
|
178
|
+
return @rmail.header
|
179
|
+
end # }}}
|
180
|
+
|
181
|
+
#--------------------------------------------------------------------------------------
|
182
|
+
# method: body {{{
|
183
|
+
#++
|
184
|
+
# Gives the body of the email
|
185
|
+
#
|
186
|
+
# Returns a String or an array of RMail::Message if the Message is a MIME multipart
|
187
|
+
def body
|
188
|
+
return @rmail.body
|
189
|
+
end # }}}
|
190
|
+
|
150
191
|
#--------------------------------------------------------------------------------------
|
151
192
|
# method: markAs {{{
|
152
193
|
#++
|
@@ -206,6 +247,9 @@ class Message
|
|
206
247
|
# method: load {{{
|
207
248
|
#++
|
208
249
|
# Loads the Message from its file in its <tt>@rmail</tt> attribute (RMail::Message)
|
250
|
+
#
|
251
|
+
# === Possible Exceptions
|
252
|
+
# * Errno::ENOENT
|
209
253
|
def load
|
210
254
|
if @filename == @id then
|
211
255
|
path = @folder.newpath + File::SEPARATOR + @filename
|
@@ -218,10 +262,15 @@ class Message
|
|
218
262
|
stat = File.stat(path)
|
219
263
|
@uid = stat.uid
|
220
264
|
@gid = stat.gid
|
221
|
-
|
222
|
-
|
265
|
+
if !@@logger.nil? then
|
266
|
+
logger.debug "Loaded. uid=#{@uid}, gid=#{@gid}"
|
267
|
+
logger.info "Message: #{@id}"
|
268
|
+
logger.info "Message From: #{@rmail.header.from.inspect}"
|
269
|
+
logger.info "Message Subject: #{@rmail.header.subject}"
|
270
|
+
end
|
271
|
+
rescue Errno::ENOENT => p_e
|
223
272
|
logger.error "Cannot load #{path}" if !@@logger.nil?
|
224
|
-
|
273
|
+
raise p_e
|
225
274
|
end
|
226
275
|
end # }}}
|
227
276
|
|
data/lib/vpopmail/user.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Read COPYRIGHT in the root of VPOPMail library for copyright info
|
4
4
|
# Creator: gildasc@rubyforg.org
|
5
5
|
# Author: $Author: gildasc $
|
6
|
-
# Version: $Id: user.rb
|
6
|
+
# Version: $Id: user.rb 7 2006-10-08 21:06:36Z gildasc $
|
7
7
|
#++
|
8
8
|
|
9
9
|
require 'vpopmail/config'
|
@@ -25,7 +25,7 @@ class User
|
|
25
25
|
@@logger = nil
|
26
26
|
def self.logger ; @@logger ; end
|
27
27
|
def self.logger=(p_object) ; @@logger = p_object ; end
|
28
|
-
def logger
|
28
|
+
def logger ; @@logger ; end
|
29
29
|
def logger=(p_object) ; @@logger = p_object ; end
|
30
30
|
# }}}
|
31
31
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: vpopmail
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2006-10-
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2006-10-09
|
8
8
|
summary: Ruby VPOPMail interface
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- lib/vpopmail/message.rb
|
38
38
|
- lib/vpopmail/user.rb
|
39
39
|
- examples/emailcheck.rb
|
40
|
+
- examples/vdelfakemail.rb
|
40
41
|
- examples/vlearn.rb
|
41
42
|
- Rakefile
|
42
43
|
- install.rb
|