gurgitate-mail 1.10.3 → 1.10.5

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,15 @@
1
+ Tests = Dir["test/test_*.rb"]
2
+
3
+
4
+ task :test do
5
+ $:.unshift File.dirname(__FILE__)
6
+ require './test/runtests'
7
+
8
+ testcases = Tests.map do |file|
9
+ load file
10
+ eval("TC_" + File.basename(file,".rb").sub(/^test_/,'').capitalize)
11
+ end
12
+
13
+ runtests testcases
14
+ end
15
+
@@ -1,4 +1,4 @@
1
- #!./bin/ruby -w
1
+ #!BUILD/bin/ruby -w
2
2
 
3
3
  #------------------------------------------------------------------------
4
4
  # Mail filter invocation script
@@ -12,12 +12,14 @@ require 'pathname'
12
12
  require 'irb'
13
13
  require "gurgitate-mail"
14
14
  require "etc"
15
+ require "tmpdir"
15
16
 
16
17
  class GurgitateTest < Test::Unit::TestCase
17
18
  def setup
18
19
  currentdir = Pathname.new(File.join(File.dirname(__FILE__),
19
20
  "..")).realpath.to_s
20
- @testdir = File.join(currentdir,"test-data")
21
+ @testdir = Dir.mktmpdir
22
+ # @testdir = File.join(currentdir,"test-data")
21
23
  @folders = File.join(@testdir,"folders")
22
24
  FileUtils.rmtree @testdir if File.exists? @testdir
23
25
  Dir.mkdir @testdir
metadata CHANGED
@@ -1,15 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gurgitate-mail
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.3
4
+ hash: 53
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 10
9
+ - 5
10
+ version: 1.10.5
5
11
  platform: ruby
6
12
  authors:
7
13
  - Dave Brown
8
- autorequire: gurgitate-mail
14
+ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-11-08 00:00:00 +09:00
18
+ date: 2010-12-27 00:00:00 +09:00
13
19
  default_executable: gurgitate-mail
14
20
  dependencies: []
15
21
 
@@ -22,16 +28,6 @@ extensions: []
22
28
  extra_rdoc_files: []
23
29
 
24
30
  files:
25
- - lib/gurgitate-mail.rb
26
- - lib/gurgitate/deliver/mh.rb
27
- - lib/gurgitate/deliver/mbox.rb
28
- - lib/gurgitate/deliver/maildir.rb
29
- - lib/gurgitate/message.rb
30
- - lib/gurgitate/header.rb
31
- - lib/gurgitate/mail_headers.rb
32
- - lib/gurgitate/deliver.rb
33
- - lib/gurgitate/mailmessage.rb
34
- - lib/gurgitate/headers.rb
35
31
  - test/test_header.rb
36
32
  - test/runtests.rb
37
33
  - test/test_delivery.rb
@@ -48,6 +44,9 @@ files:
48
44
  - test/test_execute_rules.rb
49
45
  - test/test_configuration.rb
50
46
  - test/test_headers.rb
47
+ - .gemtest
48
+ - Rakefile
49
+ - bin/gurgitate-mail
51
50
  has_rdoc: true
52
51
  homepage: http://www.rubyforge.org/projects/gurgitate-mail/
53
52
  licenses: []
@@ -58,23 +57,44 @@ rdoc_options: []
58
57
  require_paths:
59
58
  - lib
60
59
  required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
61
  requirements:
62
62
  - - ">="
63
63
  - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
64
67
  version: "0"
65
- version:
66
68
  required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
67
70
  requirements:
68
71
  - - ">="
69
72
  - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
70
76
  version: "0"
71
- version:
72
77
  requirements: []
73
78
 
74
79
  rubyforge_project: gurgitate-mail
75
- rubygems_version: 1.3.5
80
+ rubygems_version: 1.3.7
76
81
  signing_key:
77
82
  specification_version: 3
78
83
  summary: gurgitate-mail is a mail filter (and a mail-delivery agent)
79
84
  test_files:
85
+ - test/test_header.rb
80
86
  - test/runtests.rb
87
+ - test/test_delivery.rb
88
+ - test/test_headers_meddling_with_headers.rb
89
+ - test/test_rules.rb
90
+ - test/test_writing.rb
91
+ - test/test_headers_creating_from_hash.rb
92
+ - test/test_mail_headers.rb
93
+ - test/test_deliver.rb
94
+ - test/test_gurgitate_delivery.rb
95
+ - test/gurgitate-test.rb
96
+ - test/test_process.rb
97
+ - test/test_mail_headers_meddling_with_headers.rb
98
+ - test/test_execute_rules.rb
99
+ - test/test_configuration.rb
100
+ - test/test_headers.rb
@@ -1,385 +0,0 @@
1
- #!/opt/bin/ruby
2
- #------------------------------------------------------------------------
3
- # Mail filter package
4
- #------------------------------------------------------------------------
5
-
6
- require 'etc'
7
-
8
- require 'gurgitate/mailmessage'
9
- require 'gurgitate/deliver'
10
-
11
- module Gurgitate
12
- # This is the actual gurgitator; it reads a message and then it can
13
- # do other stuff with it, like saving it to a mailbox or forwarding
14
- # it somewhere else.
15
- #
16
- # To set configuration parameters for gurgitate-mail, use a keyword-
17
- # based system. It's almost like an attribute, only if you give the
18
- # accessor a parameter, it will set the configuration parameter to
19
- # the parameter's value. For instance:
20
- #
21
- # maildir "#{homedir}/Mail"
22
- # sendmail "/usr/sbin/sendmail"
23
- # spoolfile "Maildir"
24
- # spooldir homedir
25
- #
26
- # (This is because of an oddity in Ruby where, even if an
27
- # accessor exists in the current object, if you say:
28
- # name = value
29
- # it'll always create a local variable. Not quite what you
30
- # want when you're trying to set a config parameter. You have
31
- # to say <code>self.name = value</code>, which [I think] is ugly.
32
- #
33
- # In the interests of promoting harmony, of course,
34
- # <code>self.name = value</code> still works.)
35
- #
36
- # The attributes you can define are:
37
- #
38
- # homedir :: Your home directory. This defaults to what your
39
- # actual home directory is.
40
- #
41
- # maildir :: The directory you store your mail in. This defaults
42
- # to the "Mail" directory in your home dir.
43
- #
44
- # logfile :: The path to your gurgitate-mail log file. If you
45
- # set this to +nil+, gurgitate-mail won't log anything.
46
- # The default value is ".gurgitate.log" in your home
47
- # directory.
48
- #
49
- # The following parameters are more likely to be interesting to the
50
- # system administrator than the everyday user.
51
- #
52
- # sendmail :: The full path of your "sendmail" program, or at least
53
- # a program that provides functionality equivalent to
54
- # sendmail.
55
- #
56
- # spoolfile :: The default location to store mail messages, for the
57
- # messages that have been unaffected by your gurgitate
58
- # rules. If an exception is raised by your rules, the
59
- # message will be delivered to the spoolfile.
60
- #
61
- # spooldir :: The location where users' system mail boxes live.
62
- #
63
- # folderstyle :: The style of mailbox to create (and to expect,
64
- # although gurgitate-mail automatically detects the
65
- # type of existing mailboxes). See the separate
66
- # documentation for folderstyle for more details.
67
- class Gurgitate < Mailmessage
68
- include Deliver
69
-
70
- # Instead of the usual attributes, I went with a
71
- # reader-is-writer type thing (as seen quite often in Perl and
72
- # C++ code) so that in your .gurgitate-rules, you can say
73
- #
74
- # maildir "#{homedir}/Mail"
75
- # sendmail "/usr/sbin/sendmail"
76
- # spoolfile "Maildir"
77
- # spooldir homedir
78
- #
79
- # This is because of an oddity in Ruby where, even if an
80
- # accessor exists in the current object, if you say:
81
- # name = value
82
- # it'll always create a local variable. Not quite what you
83
- # want when you're trying to set a config parameter. You have
84
- # to say "self.name = value", which (I think) is ugly.
85
- #
86
- # In the interests of promoting harmony, of course, the previous
87
- # syntax will continue to work.
88
- def self.attr_configparam(*syms)
89
- syms.each do |sym|
90
- class_eval %{
91
- def #{sym} (*vals)
92
- if vals.length == 1
93
- @#{sym} = vals[0]
94
- elsif vals.length == 0
95
- @#{sym}
96
- else
97
- raise ArgumentError,
98
- "wrong number of arguments " +
99
- "(\#{vals.length} for 0 or 1)"
100
- end
101
- end
102
-
103
- # Don't break it for the nice people who use
104
- # old-style accessors though. Breaking people's
105
- # .gurgitate-rules is a bad idea.
106
- attr_writer :#{sym}
107
- }
108
- end
109
- end
110
-
111
- # The directory you want to put mail folders into
112
- attr_configparam :maildir
113
-
114
- # The path to your log file
115
- attr_configparam :logfile
116
-
117
- # The full path of your "sendmail" program
118
- attr_configparam :sendmail
119
-
120
- # Your home directory
121
- attr_configparam :homedir
122
-
123
- # Your default mail spool
124
- attr_configparam :spoolfile
125
-
126
- # The directory where user mail spools live
127
- attr_configparam :spooldir
128
-
129
- # What kind of mailboxes you prefer
130
- # attr_configparam :folderstyle
131
-
132
- # What kind of mailboxes you prefer. Treat this like a
133
- # configuration parameter. If no argument is given, then
134
- # return the current default type.
135
- #
136
- # Depending on what you set this to, some other configuration
137
- # parameters change. You can set this to the following things:
138
- #
139
- # <code>Maildir</code> :: Create Maildir mailboxes.
140
- #
141
- # This sets +spooldir+ to your home
142
- # directory, +spoolfile+ to
143
- # $HOME/Maildir and creates
144
- # mail folders underneath that.
145
- #
146
- # <code>MH</code> :: Create MH mail boxes.
147
- #
148
- # This reads your <code>.mh_profile</code>
149
- # file to find out where you've told MH to
150
- # find its mail folders, and uses that value.
151
- # If it can't find that in your .mh_profile,
152
- # it will assume you want mailboxes in
153
- # $HOME/Mail. It sets +spoolfile+ to
154
- # "inbox" in your mail directory.
155
- #
156
- # <code>Mbox</code> :: Create +mbox+ mailboxes.
157
- #
158
- # This sets +spooldir+ to
159
- # <code>/var/spool/mail</code> and
160
- # +spoolfile+ to a file with your username
161
- # in <code>/var/spool/mail</code>.
162
- def folderstyle(*style)
163
- if style.length == 0 then
164
- @folderstyle
165
- elsif style.length == 1 then
166
- if style[0] == Maildir then
167
- spooldir homedir
168
- spoolfile File.join(spooldir,"Maildir")
169
- maildir spoolfile
170
- elsif style[0] == MH then
171
- mh_profile_path = File.join(ENV["HOME"],".mh_profile")
172
- if File.exists?(mh_profile_path) then
173
- mh_profile = YAML.load(File.read(mh_profile_path))
174
- maildir mh_profile["Path"]
175
- else
176
- maildir File.join(ENV["HOME"],"Mail")
177
- end
178
- spoolfile File.join(maildir,"inbox")
179
- else
180
- spooldir "/var/spool/mail"
181
- spoolfile File.join(spooldir, @passwd.name)
182
- end
183
-
184
- @folderstyle = style[0]
185
- else
186
- raise ArgumentError, "wrong number of arguments "+
187
- "(#{style.length} for 0 or 1)"
188
- end
189
- @folderstyle
190
- end
191
-
192
- # Set config params to defaults, read in mail message from
193
- # +input+
194
- # input::
195
- # Either the text of the email message in RFC-822 format,
196
- # or a filehandle where the email message can be read from
197
- # recipient::
198
- # The contents of the envelope recipient parameter
199
- # sender::
200
- # The envelope sender parameter
201
- # spooldir::
202
- # The location of the mail spools directory.
203
- def initialize(input=nil,
204
- recipient=nil,
205
- sender=nil,
206
- spooldir="/var/spool/mail",
207
- &block)
208
- @passwd = Etc.getpwuid
209
- @homedir = @passwd.dir;
210
- @maildir = File.join(@passwd.dir,"Mail")
211
- @logfile = File.join(@passwd.dir,".gurgitate.log")
212
- @sendmail = "/usr/lib/sendmail"
213
- @spooldir = spooldir
214
- @spoolfile = File.join(@spooldir,@passwd.name )
215
- @folderstyle = MBox
216
- @rules = []
217
-
218
- input_text = ""
219
- input.each_line do |l| input_text << l end
220
- super(input_text, recipient, sender)
221
- instance_eval(&block) if block_given?
222
- end
223
-
224
- def add_rules(filename, options = {}) #:nodoc:
225
- if not Hash === options
226
- raise ArgumentError.new("Expected hash of options")
227
- end
228
- if filename == :default
229
- filename=homedir+"/.gurgitate-rules"
230
- end
231
- if not FileTest.exist?(filename)
232
- filename = filename + '.rb'
233
- end
234
- if not FileTest.exist?(filename)
235
- if options.has_key?(:user)
236
- log("#{filename} does not exist.")
237
- end
238
- return false
239
- end
240
- if FileTest.file?(filename) and
241
- ( ( not options.has_key? :system and
242
- FileTest.owned?(filename) ) or
243
- ( options.has_key? :system and
244
- options[:system] == true and
245
- File.stat(filename).uid == 0 ) ) and
246
- FileTest.readable?(filename)
247
- @rules << filename
248
- else
249
- log("#{filename} has bad permissions or ownership, not using rules")
250
- return false
251
- end
252
- end
253
-
254
- # Deletes (discards) the current message.
255
- def delete
256
- # Well, nothing here, really.
257
- end
258
-
259
- # This is kind of neat. You can get a header by calling its
260
- # name as a method. For example, if you want the header
261
- # "X-Face", then you call x_face and that gets it for you. It
262
- # raises NameError if that header isn't found.
263
- #
264
- # meth::
265
- # The method that the caller tried to call which isn't
266
- # handled any other way.
267
- def method_missing(meth)
268
- headername=meth.to_s.split(/_/).map {|x| x.capitalize}.join("-")
269
- if headers[headername] then
270
- return headers[headername]
271
- else
272
- raise NameError,"undefined local variable or method, or header not found `#{meth}' for #{self}:#{self.class}"
273
- end
274
- end
275
-
276
- # Forwards the message to +address+.
277
- #
278
- # address::
279
- # A valid email address to forward the message to.
280
- def forward(address)
281
- self.log "Forwarding to "+address
282
- IO.popen(@sendmail+" "+address,"w") do |f|
283
- f.print(self.to_s)
284
- end
285
- end
286
-
287
- # Writes +message+ to the log file.
288
- def log(message)
289
- if @logfile then
290
- File.open(@logfile,"a") do |f|
291
- f.flock(File::LOCK_EX)
292
- f.print(Time.new.to_s+" "+message+"\n")
293
- f.flock(File::LOCK_UN)
294
- end
295
- end
296
- end
297
-
298
- # Pipes the message through +program+. If +program+
299
- # fails, puts the message into +spoolfile+
300
- def pipe(program)
301
- self.log "Piping through "+program
302
- IO.popen(program,"w") do |f|
303
- f.print(self.to_s)
304
- end
305
- return $?>>8
306
- end
307
-
308
- # Pipes the message through +program+, and returns another
309
- # +Gurgitate+ object containing the output of the filter
310
- #
311
- # Use it like this:
312
- #
313
- # filter "bogofilter -p" do
314
- # if x_bogosity =~ /Spam/ then
315
- # log "Found spam"
316
- # delete
317
- # return
318
- # end
319
- # end
320
- #
321
- def filter(program,&block)
322
- self.log "Filtering with "+program
323
- IO.popen("-","w+") do |filter|
324
- unless filter then
325
- begin
326
- exec(program)
327
- rescue
328
- exit! # should not get here anyway
329
- end
330
- else
331
- if fork
332
- filter.close_write
333
- g=Gurgitate.new(filter)
334
- g.instance_eval(&block) if block_given?
335
- return g
336
- else
337
- begin
338
- filter.close_read
339
- filter.print to_s
340
- filter.close
341
- rescue
342
- nil
343
- ensure
344
- exit!
345
- end
346
- end
347
- end
348
- end
349
- end
350
-
351
- def process(&block) #:nodoc:
352
- begin
353
- if @rules.size > 0 or block
354
- @rules.each do |configfilespec|
355
- begin
356
- eval File.new(configfilespec).read, nil,
357
- configfilespec
358
- rescue ScriptError
359
- log "Couldn't load #{configfilespec}: "+$!
360
- save(spoolfile)
361
- rescue Exception
362
- log "Error while executing #{configfilespec}: #{$!}"
363
- $@.each { |tr| log "Backtrace: #{tr}" }
364
- folderstyle = MBox
365
- save(spoolfile)
366
- end
367
- end
368
- if block
369
- instance_eval(&block)
370
- end
371
- log "Mail not covered by rules, saving to default spool"
372
- save(spoolfile)
373
- else
374
- save(spoolfile)
375
- end
376
- rescue Exception
377
- log "Error while executing rules: #{$!}"
378
- $@.each { |tr| log "Backtrace: #{tr}" }
379
- log "Attempting to save to spoolfile after error"
380
- folderstyle = MBox
381
- save(spoolfile)
382
- end
383
- end
384
- end
385
- end