Grundstruktur

Inhalte dieser Sektion:

Dieser Abschnitt befasst sich mit dem Grundgerüst unseres Packages. Am Ende dieser Seite wird das Programm - zumindest theoretisch - bereits lauffähig sein.

Als ersten Schritt erstellen wir unser Package, binden externe Standard-Module ein und deklarieren eine Subroutine sendMail. An diese Subroutine sollen über das Hash %mail sämtliche relevanten Daten vom Hauptprogramm übergeben werden.

Die Grundstruktur sieht also wie folgt aus:
package mail;

###
# Module aufrufen
###
use CGI::Carp qw(fatalsToBrowser);

###
# Variablen exportieren
###
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($mail_error);
@EXPORT_OK = qw();

###
# Standard-Variablen
###
my $mailprog = "/usr/lib/sendmail";
$mail_error = undef;

###################################


###################################
####        Send Mail         #####
###################################
sub sendMail {
	my %mail = @_;

	# Hier folgen alle weiteren Anweisungen
	# [...]
}

Hinweise:

  1. Es empfiehlt sich, sämtliche Daten über ein Hash zu übergeben (my %mail = @_;), ansatt beispielweise mehrere Skalare zu verwenden. Wie wir später noch sehen werden, sollen nicht alle möglichen Variablen Pflicht-Werte darstellen, und auf diese Weise können auch wirklich nur die Werte übergeben werden, die tatsächlich benötigt werden.
  2. Die globale Variable $mail_error gibt uns eine Möglichkeit, Fehlermeldungen an das aufrufende Programm zurückzugeben. Die Variable wird über das Exporter-Modul an das aufrufende Programm exportiert und kann dort weiter verwendet werden.
  3. Die Variable $mailprog beeinhaltet den Pfad zu dem Mail-Programm des Servers, standardmäßig auf UNIX-basierten Servern /usr/lib/sendmail. Grundsätzlich muss diese Variable nicht gleich zu Programm-Beginn deklariert werden, es is jedoch vorteilhaft, da dieser Wert angepasst werden muss, falls das Mailprogramm an einem anderen Ort liegt.

Was machen wir nun mit diesem Mail-Programm sendmail? Technisch gesehen übergeben wir unsere gewünschten Informationen als Daten-Stream an ein File-Handle, das eine Pipe zum angegebenen Programm geöffnet hat. Das mag jetzt etwas abstrakt klingen, bedeutet aber konkret nichts anderes, als dass wir die altbekannte print-Anweisung so "umbiegen", dass sie ihre Anweisungen eben an unser Mail-Programm anstelle des STDOUT-Streams übergibt - genauso, wie wir mittels open auch jede x-beliebige Datei beschreiben können:

#[...]

sub sendMail {
	my %mail = @_;

	###
	# Mail-Programm starten
	###
	if ( open(MAIL,"|$mailprog -t") ) {
		# Daten an Mail-Programm übergeben
		print MAIL "To: $mail{'to'}\n";
		print MAIL "From: $mail{'from'}";
		print MAIL " ($mail{'namefrom'})" if ( exists($mail{'namefrom'}) );
		print MAIL "\n";
		print MAIL "Cc: $mail{'cc'}\n" if ( exists($mail{'cc'}) );
		print MAIL "Bcc: $mail{'bcc'}\n" if ( exists($mail{'bcc'}) );
		print MAIL "Subject: $mail{'subject'}\n";
		print MAIL "MIME-Version: 1.0\n";
		print MAIL "Content-Type: text/plain;\n\tcharset=\"iso-8859-1\"\n\n";
		print MAIL "$mail{'text'}\n\n";
		close(MAIL);
		return 1;
	}
	# Fehler beim Öffnen
	else {
		$mail_error = "Fehler beim Starten des Mail-Programms: $!";
		print STDERR $mail_error;
		return undef;
	}
}

Erklärung:

Mit open(MAIL,"|$mailprog -t") definieren wir ein Filehandle MAIL, das auf das Mail-Programm zeigt. Da open() bei einem Fehler den Wert false, ansonsten true zurückgibt, können wir gleichzeitig mit einer if-Anweisung Fehler abfangen. Bei erfolgreichem Ausführen des Mail-Programms soll dann an das aufrufende Programm der Wert 1, ansonsten undef zurückgegeben werden. Zudem wird im Falle eines Fehlers die Fehlermeldung auf STDERR geschrieben und in der globalen Variable $mail_error gespeichert.

Als nächstes werden die Header-Informationen abgearbeitet. An dieser Stelle wird auch deutlich, wieso sich die Wert-Übergabe mittels eines Hashs anbietet: Optionale Angaben wie Cc, Bcc können durch die Bedingung if ( exists($mail{'cc'}) ) nur dann angegeben werden, wenn sie wirklich benötigt werden.

Zu guter Letzt geben wir den Content-Type (momentan lassen wir nur plain-text E-Mails zu) und den Zeichensatz (charset) an, gefolgt von der eigentlichen Nachricht.

Hinweis:

Das Package ist nun bereits theoretisch lauffähig. Allerdings ist es in dieser Form noch absolut davon abhängig, dass es vom aufrufenden Programm nur korrekte Daten erhält. Im Klartext: Momentan könnte man damit noch jede Menge Unsinn anstellen. Dies werden wir im nächsten Abschnitt ändern.

« Aufbau einer E-Mail
Sicherheits-Abfragen »