Project: Mailvisa
Code Location: git://repo.or.cz/mailvisa.gitmaster
Browse
/
Outline
Download File
mailvisa.rb
### Defaults

confdir = ENV['HOME'] + '/settings/mailvisa'
sockpath = 'mailvisad.sock'
blocksize = 16384
threshold = 0.5
passthrough = true	# output message
header = true		# output X-Spam headers
errorcodes = false	# suppress error codes if true
endl = "\015\012"
input = $stdin
output = $stdout

Spam_status = 160

require 'socket'

### Functions

def usage
	'USAGE: ' + $0 + ' [options]'
end

help = <<EOT
Valid options are:

-c <path>	Look for files in <path> (default: $HOME/settings/mailvisa)
-q		Do not output message or X-Spam headers
-e		Do not use exit status to indicate spam
-b <num>	Read <num> bytes at a time (default: 16384)
-t <num>	Threshold for flagging messages as spam (default: 0.5)
-m <command>	Pipe output to <command>
-s <path>	Use <path> to connect to mailvisad (default: mailvisad.sock)
EOT

### Main program

## Parse command line
i = 0
while i < ARGV.length
	case ARGV[i]
	when '-c'
		i = i + 1
		confdir = ARGV[i]
	when '-q', '--quiet'
		passthrough = false
		header = false
	when '-e'
		errorcodes = true
	when '-s', '--socket'
		i = i + 1
		sockpath = ARGV[i]
	when '-b', '--blocksize'
		i = i + 1
		blocksize = ARGV[i].to_i
	when '-m', '--mda'
		i = i + 1
		output = IO.popen ARGV[i], 'w'
	when '-t'
		i = i + 1
		threshold = ARGV[i].to_f
	when '-h'
		puts usage
		print "\n" + help
		exit
	when /^-/
		$stderr.puts 'Unknown option: ' + ARGV[i]
		$stderr.puts usage
		$stderr.puts 'Use "' + $0 + ' -h" to list valid options'
		exit 0x80
	else
		input = open ARGV[i]
	end
	i = i + 1
end

sockpath = confdir + '/' + sockpath if sockpath.index('/') == nil

status = 0
msg = input.read blocksize
begin
	## Send first block of message to filter
	conn = UNIXSocket.open(sockpath)
	conn.print msg
	conn.flush

	## Get message score
	conn.close_write
	score = conn.read.to_f
	conn.close
	status = score > threshold ? Spam_status : 0
rescue
	$stderr.puts $!
	status = 1 # Indicate error
end

## X-Spam header
if header && (status == 0 || status == Spam_status)
	output.print 'X-Spam: ' + (status == 0 ? 'false' : 'true') + endl
end

## Passthrough (verbose output)
if passthrough
	while true
		output.print msg
		msg = input.read blocksize
		break if msg == nil
	end
end

# Return value
exit errorcodes ? 0 : status