+++ /dev/null
---- ./collect_diffs.rb~ 2004-12-10 01:51:21.000000000 +0200
-+++ ./collect_diffs.rb 2005-02-15 23:09:26.000000000 +0200
-@@ -357,13 +357,14 @@
- [ "--to", "-t", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
-- [ "--from", "-u", GetoptLong::REQUIRED_ARGUMENT ]
-+ [ "--from", "-u", GetoptLong::REQUIRED_ARGUMENT ],
-+ [ "--charset", GetoptLong::REQUIRED_ARGUMENT ]
- )
-
- # arguments to pass though to 'cvsspam.rb'
- $passthroughArgs = Array.new
- opts.each do |opt, arg|
-- if ["--to", "--config", "--from"].include?(opt)
-+ if ["--to", "--config", "--from", "--charset"].include?(opt)
- $passthroughArgs << opt << arg
- end
- if ["--debug"].include?(opt)
---- ./cvsspam.rb~ 2005-02-15 23:23:15.000000000 +0200
-+++ ./cvsspam.rb 2005-02-15 23:22:24.000000000 +0200
-@@ -1170,6 +1170,7 @@
- $repository_name = nil
- # 2MiB limit on attached diffs,
- $mail_size_limit = 1024 * 1024 * 2
-+$arg_charset = nil
-
- require 'getoptlong'
-
-@@ -1177,7 +1178,8 @@
- [ "--to", "-t", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
-- [ "--from", "-u", GetoptLong::REQUIRED_ARGUMENT ]
-+ [ "--from", "-u", GetoptLong::REQUIRED_ARGUMENT ],
-+ [ "--charset", GetoptLong::REQUIRED_ARGUMENT ]
- )
-
- opts.each do |opt, arg|
-@@ -1185,6 +1187,8 @@
- $config = arg if opt=="--config"
- $debug = true if opt=="--debug"
- $from_address = arg if opt=="--from"
-+ # must use different variable as the config is readed later.
-+ $arg_charset = arg if opt == "--charset"
- end
-
-
-@@ -1227,6 +1231,10 @@
- blah("Config file '#{$config}' not found, ignoring")
- end
-
-+if $arg_charset != nil
-+ $charset = $arg_charset
-+end
-+
- if $recipients.empty?
- fail "No email recipients defined"
- end
+++ /dev/null
---- ./cvsspam.rb~ 2005-05-14 23:28:39.000000000 +0300
-+++ ./cvsspam.rb 2005-05-19 13:19:50.000000000 +0300
-@@ -1444,7 +1444,7 @@
- tr.head {border-bottom-width:1px;border-bottom-style:solid;}
- tr.head td {padding:0;padding-top:.2em;}
- .task {background-color:#ffff00;}
-- .comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
-+ .comment {white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd}
- .error {color:red;}
- hr {border-width:0px;height:2px;background:black;}
- --></style>
+++ /dev/null
-Index: collect_diffs.rb
-===================================================================
-RCS file: /var/lib/cvs/cvsspam/collect_diffs.rb,v
-retrieving revision 1.24
-diff -u -r1.24 collect_diffs.rb
---- collect_diffs.rb 20 Feb 2005 13:35:15 -0000 1.24
-+++ collect_diffs.rb 27 Feb 2005 17:35:12 -0000
-@@ -157,7 +157,8 @@
- fail "CVSROOT ('#{cvsroot}') doesn't match log preamble ('#{$path}')"
- end
-
-- $repository_path = $path.slice(cvsroot.length+1, $path.length-cvsroot.length-1)
-+ $repository_path = $path.slice(cvsroot.length, $path.length-cvsroot.length)
-+ $repository_path.sub!(/^\//, "") # remove leading '/', if present
-
- if $use_modern_argument_list
- changes = collect_modern_style_args(cvs_info)
+++ /dev/null
---- cvsspam-0.2.11/cvsspam.rb 2005-02-21 21:52:45.000000000 +0200
-+++ cvsspam-0.2.11.patched/cvsspam.rb 2005-02-21 21:52:18.000000000 +0200
-@@ -122,24 +122,49 @@
- # long values with header continuation lines as needed
- def rfc2047_encode_quoted(io, start, rest)
- raise "no charset" if @charset.nil?
-- code_begin = "=?#{@charset}?#{@encoding}?"
-+ code_begin = marker_start_quoted
- start << code_begin
-- rest.each_byte do |b|
-- code = if b>126 || b==UNDERSCORE || b==TAB
-- sprintf("=%02x", b)
-- elsif b == SPACE
-- "_"
-- else
-- b.chr
-- end
--
-+ each_char_encoded(rest) do |code|
- if start.length+code.length+2 > @right_margin
-- io.puts(start + "?=")
-+ io.puts(start + marker_end_quoted)
- start = " " + code_begin
- end
- start << code
- end
-- io.puts(start + "?=")
-+ io.puts(start + marker_end_quoted)
-+ end
-+
-+ # return a string representing the given character-code in quoted-printable
-+ # format
-+ def quoted_encode_char(b)
-+ if b>126 || b==UNDERSCORE || b==TAB
-+ sprintf("=%02x", b)
-+ elsif b == SPACE
-+ "_"
-+ else
-+ b.chr
-+ end
-+ end
-+
-+ public
-+
-+ # yields a quoted-printable version of each byte in the given string
-+ def each_char_encoded(text)
-+ text.each_byte do |b|
-+ yield quoted_encode_char(b)
-+ end
-+ end
-+
-+ # gives the string "?=",which is used to mark the end of a quoted-printable
-+ # characte rsequence
-+ def marker_end_quoted
-+ "?="
-+ end
-+
-+ # gives a string starting "=?", and including a charset specification, that
-+ # marks the start of a quoted-printable character sequence
-+ def marker_start_quoted
-+ "=?#{@charset}?#{@encoding}?"
- end
-
- # test to see of the given string contains non-ASCII characters
-@@ -1145,6 +1170,60 @@
- end
- end
-
-+# an RFC 822 email address
-+class EmailAddress
-+ def initialize(text)
-+ if text =~ /^\s*([^<]+?)\s*<\s*([^>]+?)\s*>\s*$/
-+ @personal_name = $1
-+ @address = $2
-+ else
-+ @personal_name = nil
-+ @address = text
-+ end
-+ end
-+
-+ attr_accessor :personal_name, :address
-+
-+ def has_personal_name?
-+ return !@personal_name.nil?
-+ end
-+
-+ def encoded
-+ if has_personal_name?
-+ "#{encoded_personal_name} <#{address}>"
-+ else
-+ @address
-+ end
-+ end
-+
-+ def to_s
-+ if has_personal_name?
-+ "#{personal_name} <#{address}>"
-+ else
-+ @address
-+ end
-+ end
-+
-+ private
-+
-+ def encoded_personal_name
-+ personal_name.split(" ").map{|word| encode_word(word)}.join(" ")
-+ end
-+
-+ # rfc2047 encode the word, if it contains non-ASCII characters
-+ def encode_word(word)
-+ if $encoder.requires_rfc2047?(word)
-+ encoded = $encoder.marker_start_quoted
-+ $encoder.each_char_encoded(word) do |code|
-+ encoded << code
-+ end
-+ encoded << $encoder.marker_end_quoted
-+ return encoded
-+ end
-+ word
-+ end
-+end
-+
-
- cvsroot_dir = "#{ENV['CVSROOT']}/CVSROOT"
- $config = "#{cvsroot_dir}/cvsspam.conf"
-@@ -1183,10 +1262,10 @@
- )
-
- opts.each do |opt, arg|
-- $recipients << arg if opt=="--to"
-+ $recipients << EmailAddress.new(arg) if opt=="--to"
- $config = arg if opt=="--config"
- $debug = true if opt=="--debug"
-- $from_address = arg if opt=="--from"
-+ $from_address = EmailAddress.new(arg) if opt=="--from"
- # must use different variable as the config is readed later.
- $arg_charset = arg if opt == "--charset"
- end
-@@ -1218,7 +1297,7 @@
- end
- # helper function called from the 'config file'
- def addRecipient(email)
-- $recipients << email
-+ $recipients << EmailAddress.new(email)
- end
- # 'constant' used from the 'config file'
- class GUESS
-@@ -1333,6 +1412,7 @@
- end
-
- $encoder = HeaderEncoder.new
-+# TODO: maybe we should use the system-default value instead of ISO Latin 1?
- $encoder.charset = $charset.nil? ? "ISO-8859-1" : $charset
-
-
-@@ -1572,19 +1652,19 @@
- # Tries to look up an 'alias' email address for the given string in the
- # CVSROOT/users file, if the file exists. The argument is returned unchanged
- # if no alias is found.
--def sender_alias(address)
-+def sender_alias(email)
- if File.exists?($users_file)
- File.open($users_file) do |io|
- io.each_line do |line|
- if line =~ /^([^:]+)\s*:\s*(['"]?)([^\n\r]+)(\2)/
-- if address == $1
-- return $3
-+ if email.address == $1
-+ return EmailAddress.new($3)
- end
- end
- end
- end
- end
-- address
-+ email
- end
-
- # A handle for code that needs to add headers and a body to an email being
-@@ -1628,8 +1708,8 @@
- blah("invoking '#{cmd}'")
- IO.popen(cmd, "w") do |mail|
- ctx = MailContext.new(mail)
-- ctx.header("To", recipients.join(','))
-- ctx.header("From", from) if from
-+ ctx.header("To", recipients.map{|addr| addr.encoded}.join(','))
-+ ctx.header("From", from.encoded) if from
- yield ctx
- end
- end
-@@ -1657,18 +1737,18 @@
-
- def send(from, recipients)
- if from == nil
-- from = ENV['USER'] || ENV['USERNAME'] || 'cvsspam'
-+ from = EmailAddress.new(ENV['USER'] || ENV['USERNAME'] || 'cvsspam')
- end
-- unless from =~ /@/
-- from = "#{from}@#{ENV['HOSTNAME']||'localhost'}"
-+ unless from.address =~ /@/
-+ from.address = "#{from.address}@#{ENV['HOSTNAME']||'localhost'}"
- end
- smtp = Net::SMTP.new(@smtp_host)
- blah("connecting to '#{@smtp_host}'")
- smtp.start()
-- smtp.ready(from, recipients) do |mail|
-+ smtp.ready(from.address, recipients.map{|addr| addr.address}) do |mail|
- ctx = MailContext.new(IOAdapter.new(mail))
-- ctx.header("To", recipients.join(','))
-- ctx.header("From", from) if from
-+ ctx.header("To", recipients.map{|addr| addr.encoded}.join(','))
-+ ctx.header("From", from.encoded) if from
- ctx.header("Date", Time.now.utc.strftime(DATE_HEADER_FORMAT))
- yield ctx
- end
+++ /dev/null
---- cvsspam-0.2.11/cvsspam.rb~ 2005-02-16 21:00:04.000000000 +0200
-+++ cvsspam-0.2.11/cvsspam.rb 2005-02-16 21:00:46.000000000 +0200
-@@ -930,7 +930,7 @@
-
- # start the diff output, using the given lines as the 'preamble' bit
- def start_output(*lines)
-- println("<hr /><a name=\"file#{$fileEntries.size+1}\" /><div class=\"file\">")
-+ println("<hr /><a name=\"file#{$fileEntries.size}\" /><div class=\"file\">")
- case $file.type
- when "A"
- print("<span class=\"pathname\" id=\"added\">")
+++ /dev/null
-Index: cvsspam.rb
-===================================================================
-RCS file: /var/lib/cvs/cvsspam/cvsspam.rb,v
-retrieving revision 1.69
-diff -u -r1.69 cvsspam.rb
---- cvsspam.rb 13 May 2005 20:06:55 -0000 1.69
-+++ cvsspam.rb 14 May 2005 10:53:33 -0000
-@@ -1235,6 +1235,7 @@
- $debug = false
- $recipients = Array.new
- $sendmail_prog = "/usr/sbin/sendmail"
-+$hostname = ENV['HOSTNAME'] || 'localhost'
- $no_removed_file_diff = false
- $no_added_file_diff = false
- $no_diff = false
-@@ -1748,7 +1749,7 @@
- from = EmailAddress.new(ENV['USER'] || ENV['USERNAME'] || 'cvsspam')
- end
- unless from.address =~ /@/
-- from.address = "#{from.address}@#{ENV['HOSTNAME']||'localhost'}"
-+ from.address = "#{from.address}@#{$hostname}"
- end
- smtp = Net::SMTP.new(@smtp_host)
- blah("connecting to '#{@smtp_host}'")
-@@ -1764,6 +1765,40 @@
- end
- end
-
-+
-+def make_msg_id(localpart, hostpart)
-+ "<cvsspam-#{localpart}@#{hostpart}>"
-+end
-+
-+
-+# replaces control characters, and a selection of other characters that
-+# may not appear unquoted in an RFC822 'word', with underscores. (It
-+# doesn't actually zap '.' though.)
-+def zap_header_special_chars(text)
-+ text.gsub(/<>()\[\]@,;:\\[\000-\037\177]/, "_")
-+end
-+
-+
-+# Mail clients will try to 'thread' together a conversation over
-+# several email messages by inspecting the In-Reply-To and References headers,
-+# which should refer to previous emails in the conversation by mentioning
-+# the value of the previous message's Message-Id header. This function invents
-+# values for these headers so that, in the special case where a *single* file
-+# is committed to repeatedly, the emails giving notification of these commits
-+# can be threaded together automatically by the mail client.
-+def inject_threading_headers(mail)
-+ return unless $fileEntries.length == 1
-+ file = $fileEntries[0]
-+ name = zap_header_special_chars(file.path)
-+ unless file.fromVer == "NONE"
-+ mail.header("References", make_msg_id("#{name}.#{file.fromVer}", $hostname))
-+ end
-+ unless file.toVer == "NONE"
-+ mail.header("Message-ID", make_msg_id("#{name}.#{file.toVer}", $hostname))
-+ end
-+end
-+
-+
- if $smtp_host
- require 'net/smtp'
- mailer = SMTPMailer.new($smtp_host)
-@@ -1775,6 +1810,7 @@
-
- mailer.send($from_address, $recipients) do |mail|
- mail.header("Subject", mailSubject)
-+ inject_threading_headers(mail)
- mail.header("MIME-Version", "1.0")
- mail.header("Content-Type", "text/html" + ($charset.nil? ? "" : "; charset=\"#{$charset}\""))
- if ENV['REMOTE_HOST']
+++ /dev/null
-Index: collect_diffs.rb
-===================================================================
-RCS file: /var/lib/cvs/cvsspam/collect_diffs.rb,v
-retrieving revision 1.22
-diff -u -r1.22 collect_diffs.rb
---- collect_diffs.rb 22 Dec 2004 13:41:25 -0000 1.22
-+++ collect_diffs.rb 20 Feb 2005 01:01:08 -0000
-@@ -196,6 +196,8 @@
- # record version information
- file.puts "#V #{change.fromVer},#{change.toVer}"
-
-+ # remember that the 'binary' option was set for this file
-+ binary_file = false
- # note if the file is on a branch
- tag = nil
- if change.isRemoval
-@@ -210,6 +212,10 @@
- if status =~ /^\s*Sticky Tag:\s*(.+) \(branch: +/m
- tag = $1
- end
-+
-+ if status =~ /^\s*Sticky Options:\s*-kb/m
-+ binary_file = true
-+ end
- end
- file.puts "#T #{tag}" unless tag.nil?
-
-@@ -232,17 +238,25 @@
- end
- file.puts "#{$repository_path}/#{change.file}"
- diff_cmd << change.file
-- # do a cvs diff and place the output into our temp file
-- blah("about to run #{diff_cmd.join(' ')}")
-- safer_popen(*diff_cmd) do |pipe|
-- # skip over cvs-diff's preamble
-- pipe.each do |line|
-- break if line =~ /^diff /
-- end
-- file.puts "#U #{line}"
-- pipe.each do |line|
-- file.puts "#U #{line}"
-- end
-+ if binary_file
-+ blah("not diffing #{change.file}; has -kb set")
-+ # fake diff lines that will cause cvsspam.rb to consider this a binary
-+ # file,
-+ file.puts "#U diff x x"
-+ file.puts "#U Binary files x and y differ"
-+ else
-+ # do a cvs diff and place the output into our temp file
-+ blah("about to run #{diff_cmd.join(' ')}")
-+ safer_popen(*diff_cmd) do |pipe|
-+ # skip over cvs-diff's preamble
-+ pipe.each do |line|
-+ break if line =~ /^diff /
-+ end
-+ file.puts "#U #{line}"
-+ pipe.each do |line|
-+ file.puts "#U #{line}"
-+ end
-+ end
- end
- # TODO: don't how to do this reliably on different systems...
- #fail "cvsdiff did not give exit status 1 for invocation: #{diff_cmd.join(' ')}" unless ($?>>8)==1
+++ /dev/null
---- collect_diffs.rb.org 2004-12-11 21:38:10.000000000 +0100
-+++ collect_diffs.rb 2004-12-11 21:46:35.235302401 +0100
-@@ -100,7 +100,7 @@
- def collect_antique_style_args(cvs_info)
- # remove leading slashes that may appear due to the user entering trailing
- # slashes in their CVSROOT specification
-- cvs_info.sub!(/^\/+/, "")
-+ cvs_info = cvs_info.sub(/^\/+/, "")
-
- unless cvs_info.slice(0, $repository_path.length+1) == "#{$repository_path} "
- fail "calculated repository path ('#{$repository_path}') doesn't match start of command line arg ('#{cvs_info}')"
+++ /dev/null
---- ./cvsspam.rb 2004-12-10 01:51:21.000000000 +0200
-+++ ./cvsspam.rb 2005-02-15 21:46:58.000000000 +0200
-@@ -1568,9 +1568,9 @@
- if File.exists?($users_file)
- File.open($users_file) do |io|
- io.each_line do |line|
-- if line =~ /^([^:]+)\s*:\s*([^\n\r]+)/
-+ if line =~ /^([^:]+)\s*:\s*(['"]?)([^\n\r]+)(\2)/
- if address == $1
-- return $2
-+ return $3
- end
- end
- end