rmail.rb - Kommandozeilen Mailer für Windows

Winfried Mueller, www.reintechnisch.de, Start: 13.05.05, Stand 15.05.05
Ein Kommandozeilenwerkzeug zu haben, mit dem man eben mal schnell eine Mail versenden kann, ist praktisch. Unter Linux gibt es ja das Programm mail dafür. Unter Windows gibt es nichts in der Standard-Ausrüstung. Auch hat man meist keinen Mailserver unter Windows installiert, der einem die Mail per smtp abnehmen könnte.
Also sollte eine kleines Kommandozeilen-Tool entstehen, mit dem ich über den Webserver meines Mailproviders per smtp-auth eine Mail verschicken kann. Mit diesem Werkzeug kann ich auf jedem Windows Rechner eine Mail über meinen Provider verschicken, insofern Ruby installiert und eine Online-Verbindung aufgebaut ist.
# rmail - send a Mail from Command-Line, only for Windows platform
#
# Winfried Mueller, www.reintechnisch.de, Version: 2005/05/14
#
# State: experimental
require "net/smtp"
require "Win32API"
module Config
FROM = "win.mueller@web.de"
A_LOGIN = "win.mueller"
A_PASS = nil
SMTP_SRV = "smtp.web.de"
end
def get_passwd( char=nil, prompt=nil, char_range=0x20..0x7F )
getch = Win32API.new("msvcrt", "_getch", [], 'L')
prompt ||= "Password: "
print prompt
passwd = ""
loop do
c = getch.Call
case c
when 0x0d
break
when char_range
passwd << c.chr
if char
print char
end
else
STDERR.print "\x7" # BEL if not allowed char
end
end
print "\n"
passwd
end
def t_input( prompt=nil )
if prompt
print prompt
end
gets.chomp
end
def tm_input( prompt=nil )
if prompt
puts prompt
end
msg = ""
loop do
s = gets.chomp
if s =~ /^\.$/
break
end
msg << s + "\n"
end
msg
end
class Mail
def initialize( from, to, subject, body )
raise unless from.is_a?(String)
raise unless to.is_a?(String) || to.is_a?(Array)
raise unless body.is_a?(String)
raise unless subject.is_a?(String)
@from = from
@to = []
if to.is_a?( String )
@to << to
elsif to.is_a?( Array )
@to = to.clone
end
@subject = subject
@body = body
end
attr_reader :from, :to, :subject, :body
end
class Mailer
DBG = false
def initialize( smtp_srv, port=25, helo='localhost.localdomain' )
@server = smtp_srv
@port = port
@helo = helo
@auth_account = nil
@auth_pass = nil
@auth_type = nil
end
def set_auth( account, pass, type=:plain )
raise unless (type && account && pass)
raise unless [:plain, :login, :cram_md5].include?(type)
@auth_type = type
@auth_pass = pass
@auth_account = account
end
def send( mail )
mailmsg = "From: #{mail.from}\n"
mailmsg += "To: #{mail.to.join(",\n ")}\n"
mailmsg += "Subject: #{mail.subject}\n\n"
mailmsg += mail.body.chomp
mailmsg + "\n"
if DBG
print mailmsg
else
Net::SMTP.start(@server, @port, @helo,
@auth_account, @auth_pass, @auth_type) do |smtp|
smtp.sendmail( mailmsg, mail.from, mail.to )
end
end
end
end
# App ---------------------------------------------------------------------
from = Config::FROM || t_input( "From: " )
srv = Config::SMTP_SRV || t_input( "SMTP-Server: " )
a_login = Config::A_LOGIN || t_input( "Auth_Login: " )
a_pass = Config::A_PASS || get_passwd( "*", "Auth_Pass: " )
to = t_input( "To: " )
subject = t_input( "Subject: " )
msg = tm_input( "Message (end with .):" )
puts "Sending Mail, wait..."
mail = Mail.new( from, to, subject, msg )
mailer = Mailer.new( srv )
mailer.set_auth( a_login, a_pass )
mailer.send( mail )
Nach Aufruf von rmail gibt man alles ein, was abgefragt wird. Dabei kann man zu Anfang im Modul Config schon einiges vorkonfigurieren, um es nicht jedesmal wieder eingeben zu müssen. Auth_Login ist bei Web.de z.B. die Mailadresse vor dem @-Zeichen, bei user@web.de wäre das also user. Das Auth_Passwort ist das selbe, wie das pop3-Passwort. Bei gmx wäre der Auth_Login die Benutzernummer, Passwort ebenso das von pop3.
Die Message kann mehrere Zeilen beinhalten. Sobald man fertig ist, muss man wie unter Linux, einen Punkt auf die letzte Zeile setzen. Eine Zeile, die nur einen Punkt enthält, ist also das Ende-Kriterium. Jetzt wird die Mail über den Provider versandt.
Das Programm ist objektorientiert aufgebaut, die Klassen Mail und Mailer können also auch in eigenen Projekten verwendet werden, um z.B. automatisch generierte Mails zu versenden. Auch get_passwd und t_input sind wiederverwendbare Komponenten. Im Grunde besteht das Anwendungsprogramm nur aus den letzten Zeilen nach # App ---. Damit das Programm jedoch ohne Abhängigkeiten zu Bibliotheken funktioniert, wurde hier alles in ein Programmfile zusammenkopiert.