Deutsche PerlFAQ
perlfaq9 - Netzwerke
Dieser Abschnitt behandelt Fragen bezüglich Netzwerken, dem Internet und einiges über das Web.
(Alan Flavell <flavell+www@a5.ph.gla.ac.uk> antwortet...)
Das Common Gateway Interface (CGI) spezifiziert eine Softwareschnittstelle zwischen einem Programm (``CGI-Skript'') und einem Webserver (HTTPD). Es ist nicht Perl-spezifisch und es seine eigenen FAQs und Tutorials und Usenet-Gruppe, comp.infosystems.www.authoring.cgi
Die CGI-Spezifikation ist in einem informatorischem RFC skizziert: http://www.ietf.org/rfc/rfc3875
Weiter relevante Dokumentationen sind unter http://www.perl.org/CGI_MetaFAQ.html aufgelistet.
Diese Perl FAQs behandeln einige sehr ausgesuchte CGI-Sachen. Wieauchimmer,
Perl-Programmierer sind sehr gut beraten, das CGI.pm Modul zu benutzen, das
sich um die Details für sie kümmert.
Die Ähnlichkeiten zwischen CGI-Antwort-Headern (definiert in der CGI-Spezifikation) und HTTP-Antwort-Headern (definiert in der HTTP-Sepzifikation, RFC2616) sind gewollt, können aber manchmal verwirrend sein.
Die CGI-Spezifikation definiert zwei Arten von Skripten: Die ``Parsed Header'' Skripte und die ``Non Parsed Header'' (NPH) Skripte. Überprüfe die Dokumentation Deines Servers, was er unterstützt. ``Parsed Header'' Skripte sind in verschiedener Hinsicht einfacher. Die CGI-Spezifikation erlaubt alle der üblichen Darstellungen des Zeilenumbruchs in der CGI Antwort (es ist die Aufgabe des Servers darauf basierend eine richtige HTTP Antwort zu erzeugen). Also ist ``\n'' im Textmodus geschrieben technisch korrekt und empfohlen. NPH Skript sind kniffliger: Sie müssen einen kompletten und fehlerfreien Satz an HTTP-Transaktions Antwort-Headern ausgeben; die HTTP-Spezifikation verlangt, dass die Datensätze mit Carriage-Return und Line-Feed abgeschlossen sind, z.B. ASCII \015\012 im Binärmodus geschrieben.
Die Verwendung von CGI.pm bedeutet exzellente Plattformunabhängigkeit, einschließlich
EBCDIC-Systemen. CGI.pm wählt die passende Zeilenumbruch-Darstellung ($CGI::CRLF)
und setzt den Binärmodus wo es passt.
Verschiedene Dinge können falsch sein. Du kannst den ``Troubleshooting Perl CGI Skript''-Leitfaden unter
http://www.perl.org/troubleshooting_CGI.html
durcharbeiten.
Wenn Du danach zeigen kannst, dass Du die FAQs gelesen hast und dass Dein Problem etwas einfaches ist, das leicht beantwortet werden kann, wirst Du wahrscheinlinch eine nette und hilfreiche Antwort auf Deine Frage bekommen, wenn Du sie auf comp.infosystems.www.authoring.cgi stellst (wenn es etwas mit HTTP oder mit dem CGI-Protokoll zu tun hat). Fragen, die scheinbar Perl-Fragen sind aber in Wirklichkeit CGI-Fragen und auf comp.lang.perl.misc gestellt werden, kommen nicht so gut an.
Die hilfreichen FAQs, verwandte Dokumente und Leitfaden für die Fehlersuche sind in der CGI Meta-FAQ aufgelistet:
http://www.perl.org/CGI_MetaFAQ.html
Benutze das CGI::Carp Modul. Es ersetzt warn und die und zusätzlich
die carp-, croak- und confess-Funktionen aus dem normalen Carp Modul
durch ausführlichere und sichere Versionen. Es schickte diese immer noch zur
normalen Fehler-Logdatei des Servers.
use CGI::Carp;
warn "This is a complaint";
die "But this one is serious";
Die folgende Verwendung von CGI::Carp leitet die Felhler in eine Datei Deiner Wahl um,
und ist innerhalb eines BEGIN-Blocks, um auch Fehler während der Kompilier-Zeit abzufangen.
BEGIN {
use CGI::Carp qw(carpout);
open(LOG, ">>/var/local/cgi-logs/mycgi-log")
or die "Unable to append to mycgi-log: $!\n";
carpout(*LOG);
}
Du kannst für Schwerwiegende Fehler sogar erreichen, dass sie an den Client-Browser zurückgehen, was für Dein eigenes Debugging schön ist, aber den Endbenutzer verwirren könnte.
use CGI::Carp qw(fatalsToBrowser);
die "Bad error here";
Selbst wenn der Fehler auftritt, bevor Du den HTTP-Header ausgeben konntest, wird
das Modul versuchen sich darum zu kümmern, um den gefürchteten 500 Server Error
zu vermeiden. Normale Warnungen mit dem Namen der Anwendung und Zeitstemplet vorangestellt,
landen weiterhin in der Fehler-Logdatei des Servers
(oder wo auch immer Du sie mit carpout hinschickst)
Der korrekteste Weg (wenn auch nicht der schnellste) ist, HTML::Parser vom CPAN
zu benutzen. Ein anderer weitgehend korrekter weg ist, HTML::FormatText zu benutzen,
das nicht nur HTML entfernt, sondern auch ein wenig einfache Formatierung zu dem
resultierenden einfachen Text hinzuzufügen.
Viele Leute unternehmen den einfältigen Versuch mit einem einfältigen Regulären
Ausdruck, wie z.B. s/<.*?>//g, aber das schlägt in vielen Fällen fehl, wei die
Tags vielleicht über mehrere Zeilen gehen, gequotete spitze Klammern enthalten, oder
ein HTML-Kommentar enthalten ist. Dazu vergessen die Leute Entitäten zu
konvertieren -- wie zum Beispiel <.
Hier ist ein ``einfältiger'' Versuch, der für die meisten Dateien funktioniert:
#!/usr/bin/perl -p0777
s/<(?:[^>'"]*|(['"]).*?\1)*>//gs
Wenn Du eine komplettere Lösung haben willst, schau Dir das 3-stufige striphtml Programm unter http://www.cpan.org/authors/Tom_Christiansen/scripts/striphtml.gz an.
Hier ein paar verzwickte Fälle, an die Du denken solltest, wenn Du eine Lösung suchst:
<IMG SRC = "foo.gif" ALT = "A > B">
<IMG SRC = "foo.gif"
ALT = "A > B">
<!-- <A comment> -->
<script>if (a<b && a>c)</script>
<# Just data #>
<![INCLUDE CDATA [ >>>>>>>>>>>> ]]>
Wenn HTML-Kommentare andere Tags enthalten, würden die Lösungen auch an einem Text wie diesen scheitern:
<!-- This section commented out.
<B>You can't see me!</B>
-->
Du kannst leicht alle Arten von URL aus HTML mit HTML::SimpleLinkExtor herausfiltern,
das mit Ankern, Bildern, Objekten, Frames und vielen anderen Tags umgehen kann, die
eine URL enthalten können. Wenn Du etwas komplexeres benötigst, kannst Du Deine eigene
Subklasse von HTML::LinkExtor oder HTML::Parser schreiben. Du könntest sogar
HTML::SimpleLinkExtor als Beispiel für etwas nehmen, dass speziell auf Deine
Bedürfnisse zugeschnitten ist.
Du kannst URI::Find benutzen, um URLs aus einem beliebigen Text-Dokument zu filtern.
Weniger komplette Lösungen, die Reguläre Ausdrücke benutzen, können viel Laufzeit sparen, wenn Du weißt, dass die Eingabe einfach ist. Eine Lösung von Tom Christians läuft 100x schnelle als die meisten Modul-basierten Ansätze, filtert aber nur die URLs von Ankern, bei denen das erste Attribut HREF ist und keine weiteren Attribute hat.
#!/usr/bin/perl -n00
# qxurl - tchrist@perl.com
print "$2\n" while m{
< \s*
A \s+ HREF \s* = \s* (["']) (.*?) \1
\s* >
}gsix;
In diesem Fall bedeutet ``herunterladen'' die Datei-Upload-Funktion von HTML-Formularen
zu benutzen. Du erlaubst dem Webuser eine Datei anzugeben, die zu Deinem Webserver
geschickt werden soll. Für Dich sieht es wie ein Download aus und für den Benutzer sieht
es wie ein Upload aus. Egal wie Du es nennt, Du tust es mit etwas, das als
mulitpart/form-data-Encoding bekannt ist. Das CGI.pm Modul (das als Teil der Standardbibliotheken
mit Perl mitgeliefert wird) unterstützt das in der start_multipart_form()-Methode, die nicht
das gleiche wie die startform()-Methode ist.
Für Code-Beispiele und Details schau Dir den Abschnitt über Datei-Uploads in der CGI.pm-
Dokumentation an.
(beigetragen von brian d foy)
Das CGI.pm-Module (das mit Perl mitgeliefert wird) hat Funktionen, um die HTML-Formularfelder
zu erzeugen. Schau Dir die CGI.pm-Dokumentation für mehr Beispiele an.
use CGI qw/:standard/;
print header,
start_html('Favorite Animals'),
start_form,
"What's your favorite animal? ",
popup_menu(
-name => 'animal',
-values => [ qw( Llama Alpaca Camel Ram ) ]
),
submit,
end_form,
end_html;
(beigetragen von brian d foy)
Benutze die libwww-perl Distribution. Das Modul LWP::Simple kann
Web-Ressourcen holen und Dir deren Inhalt als String zurückgeben:
use LWP::Simple qw(get);
my $html = get( "http://www.example.com/index.html" );
Es kann auch die Ressource direkt in einer Datei speichern:
use LWP::Simple qw(getstore);
getstore( "http://www.example.com/index.html", "foo.html" );
Wenn Du etwas komplizierteres machen musst, kannst Du das Modul LWP::UserAgent
benutzen, um einen eigenen User-Agent (z.B. Browser) zu erstellen um die
Aufgabe zu erledigen. Wenn Du einen interaktiven Webbrowser simulieren willst,
kannst Du das Modul WWW::Mechanize verwenden.
Wenn Du etwas komplexes machen willst, wie z.B. durch viele Seiten und
Formulare oder eine Webseite zu bewegen, kannst Du WWW::Mechanize
verwenden. Schau Dir dessen Dokumentation für alle Details an.
Wenn Du Werte mit der GET-Methode abschicken willst, erstelle eine URL
und kodiere das Formular mit der query_form-Methode:
use LWP::Simple;
use URI::URL;
my $url = url('http://www.perl.com/cgi-bin/cpan_mod');
$url->query_form(module => 'DB_File', readme => 1);
$content = get($url);
Wenn Du die POST-Methode benutzt, erzeuge Dir einen eigenen User-Agent und kodiere den Inhalt entsprechend.
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
$ua = LWP::UserAgent->new();
my $req = POST 'http://www.perl.com/cgi-bin/cpan_mod',
[ module => 'DB_File', readme => 1 ];
$content = $ua->request($req)->as_string;
(beigetragen von brian d foy)
Die % Kodierungen behandeln resvierte Zeichen in URIs, wie es im RFC 2396
Abschnitt 2 beschrieben ist. Diese Kodierung ersetzt das reservierte Zeichen mit
der Hexadezimalen Schreibweise der Nummer des Zeiches in der US-ASCII-Tabelle.
Zum Beispiel wird der Doppelpunkt, :, zu %3A.
In CGI-Skripten, brauchst Du dich um das Dekodieren der URIs kümmern, wenn Du
CGI.pm benutzt. Du solltest Dich nicht selbst um die Behandlung der URI
kümmern, weder in die eine Richtung noch in die andere.
Wenn Du einen String selbst kodieren musst, denke daran, dass Du niemals versuchen
solltest eine bereits zusammengestellte URI zu kodieren. Du musst die Komponenten
einzeln escapen und danach zusammenfügen. Um einen String zu kodieren, kannst Du
das URI::Escape Modul verwenden. Die uri_escape Funktion liefert den
geschützten String zurück:
my $original = "Colon : Hash # Percent %";
my $escaped = uri_escape( $original );
print "$escaped\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25'
Benutze die uri_unescape Funktion, um den String zu dekodieren:
my $unescaped = uri_unescape( $escaped );
print $unescaped; # zurueck beim Original
Wenn Du es selbst machen möchtest, brauchst Du nur einfach die reservierten Zeichen mit ihrer Kodierung zu ersetzen. Eine globale Ersetzung ist ein Weg, das zu tun:
# encode
$string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;
#decode
$string =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg;
Lege die komplette URL des Ziels fest (selbst wenn es auf dem gleichen Server ist). Dies ist eine der zwei unterschiedlichen Arten von CGI ``Location:'' Antworten, die in der CGI-Spezifikation für ein ``Parsed Headers'' Skript definiert sind. Die andere Art (ein absoluter URL-Pfad) wird intern auf dem Server aufgelöst, ohne jede HTTP-Weiterleitung. Die CGI-Spezifikation erlaubt in keinem dieser Fälle relative URLs.
Die Verwendung von CGI.pm ist dringend empfohlen. Dieses Beispiel zeigt die
Weiterleitung mit einer kompletten URL. Diese Weiterleitung wird durch den
Webbrowser gehandhabt.
use CGI qw/:standard/;
my $url = 'http://www.cpan.org/';
print redirect($url);
Dieses Beispiel zeigt die Weiterleitung mit einem absoluten URL-Pfad. Diese Weiterleitung wird durch den Webbrowser gehandhabt.
my $url = '/CPAN/index.html';
print redirect($url);
Aber direkt gecodet, könnte es wie folgt aussehen (das abschließende ``\n'' ist zur Übersichtlichkeit extra angegeben) und benutzt entweder eine komplette URL oder einen absoluten URL-Pfad.
print "Location: $url\n"; # CGI Antwort-Header
print "\n"; # Ende der Header
Um Authentifizierung für Deinen Webserver einzuschalten, musst Du Deinen Webserver konfigurieren. Die Konfiguration ist verschieden bei den unterschiedlichen Typen von Webservern--Apache macht es anders als iPlanet, das es anders als der IIS macht. Prüfe Deine Webserver-Dokumentation für die Details Deines entsprechenden Servers.
Die Module HTTPD::UserAdmin und HTTPD::GroupAdmin bieten eine konsistente
OO Schnittstelle für diese Dateien, egal wie sie gespeichert sind. Datenbanken
können Text, DBM, Berkeley DB oder irgendeine Datenbank mit einem
DBI-kompatiblen Treiber sein. HTTPD::UserAdmin unterstützt Dateien, die für
das ``Basic'' und ``Digest'' Authentifizierungs-Schema verwendet werden. Hier
ein Beispiel:
use HTTPD::UserAdmin ();
HTTPD::UserAdmin
->new(DB => "/foo/.htpasswd")
->add($username => $password);
Schau Dir die Sicherheits-Referenzen an, die in der CGI Meta FAQ aufgeführt sind
http://www.perl.org/CGI_MetaFAQ.html
Für eine ``quick-and-dirty'' Lösung, probiere dies Lösung aus, die aus perlfunc/split abgeleitet ist:
$/ = '';
$header = <MSG>;
$header =~ s/\n\s+/ /g; # merge continuation lines
%head = ( UNIX_FROM_LINE, split /^([-\w]+):\s*/m, $header );
Diese Lösung funktioniert nicht richtig, wenn Du z.B. versuchst alle ``Received''-Zeilen
zu behalten. Ein besserer Ansatz ist es, das Mail::Header-Module vom CPAN (Teil
des MailTools Pakets) zu benutzen.
(beigetragen von brian d foy)
Verwende das CGI.pm-Modul, das mit Perl mitgeliefert wird. Es is schnell, es
ist einfach und es macht wirklich eine ganze Menge um sicherzustellen, dass die
Dinge korrekt funktionieren. Es handhabt GET-, POST- und HEAD-Anfragen, multipart
Formulare, Felder mit mehreren Werten, Query-Strings, Nachrichtentext Kombinationen
und viele andere Dinge, über Dir Du nicht nachdenken willst.
Es geht nicht viel einfacher: Das CGI.pm Modul parst automatisch die Eingabe und
macht jeden Wert über die param()-Funktion verfügbar.
use CGI qw(:standard);
my $total = param( 'price' ) + param( 'shipping' );
my @items = param( 'item' ); # multiple values, same field name
Wenn Du einen Objektorientierten Ansatz möchtest, kann CGI.pm das auch.
use CGI;
my $cgi = CGI->new();
my $total = $cgi->param( 'price' ) + $cgi->param( 'shipping' );
my @items = $cgi->param( 'item' );
Vielleicht möchtest Du auch CGI::Minimal testen, das eine leichtgewichtige Version
der gleichen Sache ist. Andere CGI::* Module auf CPAN können für Dich auch besser
funktionieren.
Viele Leute versuchen ihren eigenen Dekoder zu schreiben (oder einen von einem
anderen Programm kopieren) und laufen dann in eine der vielen ``Fallen'' dieser
Aufgabe. Es ist viel einfacher und weniger mühevoll, CGI.pm zu verwenden.
(teilweise von Aaron Sherman beigetragen)
Das ist keine so einfache Frage wie sie klingt. Es gibt zwei Teile:
a) Wie überprüfe ich, dass eine Mail-Adresse korrekt formatiert ist?
b) Wie überprüfe ich, dass eine Mail-Adresse auf einen gültigen Empfänger verweist?
Ohne eine Mail an die Adresse zu schicken und zu schauen, ob ein Mensch auf der
anderen Seite Dir antwortet, kannst Du Teil b nicht abschließend beantworten,
aber entweder das Email::Valid- oder das RFC::RFC822::Address-Modul können
sowohl Teil a als auch Teil <b> machen, soweit es in real-time möglich ist.
Wenn Du nur Teil a mit einem einfach Regulären Ausdruck prüfen möchtest, um zu sehen, dass eine Adresse nach dem Mail-Header-Standard gültig ist, kannst Du Probleme bekommen, weil es zustellbare Adresse gibt, die nicht RFC-2822-konform sind (der aktuellst Mail-Header-Standard) und nicht-zustellbare Adressen, die konform sind. Wie auch immer, das Folgende wird für gültige RFC-2822-Adressen passen, die keine Kommentare, ``folding whitespaces'' oder irgendwelche anderen obsoleten oder unwesentlichen Elemente haben. Das matcht nur die Adresse selbst:
my $atom = qr{[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+};
my $dot_atom = qr{$atom(?:\.$atom)*};
my $quoted = qr{"(?:\\[^\r\n]|[^\\"])*"};
my $local = qr{(?:$dot_atom|$quoted)};
my $quotedpair = qr{\\[\x00-\x09\x0B-\x0c\x0e-\x7e]};
my $domain_lit = qr{\[(?:$quotedpair|[\x21-\x5a\x5e-\x7e])*\]};
my $domain = qr{(?:$dot_atom|$domain_lit)};
my $addr_spec = qr{$local\@$domain};
Überprüfe eine Adresse einfach mit /^${addr_spec}$/, um zu sehen, ob sie
der RFC2822-Spezifikation folgt. Wie auch immer, weil es unmöglich ist, sicher zu
sein, dass eine solche korrekt geformte Adresse der richtige Weg ist eine
bestimmte Person zu erreichen oder überhaupt mit einer Mailbox verbunden ist, musst
Du sehr vorsichtig sein, wie Du das nutzt.
Unser bester Hinweis für die Überprüfung der Mail-Adresse einer Person, ist, sie ihre Adresse zweimal eingeben zu lassen, so wie Du es normalerweise machst, um ein Passwort zu ändern. Das merzt normalerweise Tippfehler aus. Wenn beide Versionen gleich sind, schicke eine Mail mit einer persönlichen Nachricht an diese Adresse. Wenn Du eine Nachricht zurückbekommst und sie Deinen Anweisungen gefolgt sind, kannst Du einigermaßen sicher sein, dass die Adresse real ist.
Eine verwandte Strategie, die weniger anfällig für Missbrauch ist, ist, ihnen eine PIN (Persönliche ID Nummer) zu geben. Speichere die Adresse und die PIN (am Besten ist sie eine zufällige Nummer) für die spätere Bearbeitung. In der Nachricht, die Du ihnen schickst, forderst Du sie auf, die PIN in ihrer Antwort anzugeben. Wenn die Mail aber zurückkommt oder in einer Abwesenheitsnotiz enthalten ist, wird die PIN auch vorhanden sein. Also ist es das Beste, eine leicht veränderte Version der PIN zurück zu mailen, z.B. mit den Zeichen in umgekehrter Reihenfolge, oder zu jeder Zahl eins hinzuaddiert oder subtrahiert, etc.
Das MIME-Base64 Paket (auf CPAN verfügbar) handhabt das - genauso wie das
MIME/QP-Encoding. BASE64 zu dekodieren wird so einfach wie:
use MIME::Base64;
$decoded = decode_base64($encoded);
Das MIME-Tools Pakete (auf CPAN verfügbar) unterstützt das Herausziehen und
dekodieren von BASE64-kodierten Anhängen und Inhalten direkt aus Mail-Nachrichten.
Wenn der zu dekodierende String kurz ist (kürzer als 84 Bytes) ist ein direkterer
Ansatz, das ``u'' Format der unpack()-Funktion nach einer kleineren Transliteration
zu verwenden:
tr#A-Za-z0-9+/##cd; # loesche nicht-BASE64 Zeichen
tr#A-Za-z0-9+/# -_#; # konvertiere in uuencoded Format
$len = pack("c", 32 + 0.75*length); # Berechne Längen-Byte
print unpack("u", $len . $_); # uudecode und Ausgabe
Auf Systemen, die getpwuid, die $< Variable und das Sys::Hostname
Modul (das Teil der Standard perl Distribution ist) unterstützen, kannst Du wahrscheinlich
versuchen, so etwas zu benutzen:
use Sys::Hostname;
$address = sprintf('%s@%s', scalar getpwuid($<), hostname);
Unternehmensrichtlinien bezüglich Mail-Adressen können dazu führen, dass dies Adressen generiert, die das Mailsystem des Unternehmens nicht akzeptiert. Also solltest Du nach der Mail-Adresse eines Benutzers fragen, wenn das von Bedeutung ist. Weiterhin sind nicht alle Systeme, auf denen Perl läuft, so mitteilsam bei solchen Informationen wie Unix.
Das Mail::Util Modul von CPAN (Teil des MailTools Pakets) bietet eine
mailaddress() Funktion, die versucht, die Mail-Adresse des Benutzers zu erraten.
Es macht einen intelligenteren Rateversuch als der Code oben, indem es Informationen
benutzt, die bei der Installation des Moduls gegeben wurden - aber es kann immer noch
falsch sein. Noch einmal, der beste Weg ist es oft, einfach den Benutzer zu fragen.
Verwende direkt das sendmail Programm:
open(SENDMAIL, "|/usr/lib/sendmail -oi -t -odq")
or die "Can't fork for sendmail: $!\n";
print SENDMAIL <<"EOF";
From: User Originating Mail <me\@host>
To: Final Destination <you\@otherhost>
Subject: A relevant subject line
Body of the message goes here after the blank line
in as many lines as you like.
EOF
close(SENDMAIL) or warn "sendmail didn't close nicely";
Die -oi-Option unterdrückt, dass sendmail eine Zeile, die nur aus einem
einzlenen Punkt besteht, als ``Ende der Nachricht'' interpretiert. Die -t Option
sagt, dass die Header benutzt werden sollen, um zu entscheiden, an wen die
Nachricht geschickt werden soll. Und -odq sagt, dass die Nachricht in die Queue
geschoben werden soll. Diese letzte Option bedeutet, dass Deine Nachrichte nicht
unmittelbar ausgeliefert wird, also lasse es weg, wenn Du eine unmittelbare
Zustellung willst.
Alternativ, weniger bequeme Ansätze beinhalten den direkten Aufruf von mail (manchmal
mailx genannt) oder einfach Port 25 zu öffnen, um eine vertrauliche Konversation
zwischen Dir und dem entfernten SMTP-Daemon, wahrscheinlich sendmail, zu haben.
Oder Du könntest das CPAN-Modul Mail::Mailer verwenden:
use Mail::Mailer;
$mailer = Mail::Mailer->new();
$mailer->open({ From => $from_address,
To => $to_address,
Subject => $subject,
})
or die "Can't open: $!\n";
print $mailer $body;
$mailer->close();
Das Mail::Internet Modul verwendet Net::SMTP, das weniger Unix-bezogen ist als
Mail::Mail, aber weniger zuverlässiger ist. Vermeide nackte SMTP-Kommandos.
Es gibt viele Gründe, einen Mail Transport Agent wie sendmail zu verwenden. Das
schließt das Bilden von Queues, MX-Einträge und Sicherheit ein.
Diese Antwort ist direkt aus der Dokumentation von MIME::Lite herausgezogen.
Erzeugen einer Multipart-Nachricht (z.B. eine mit Anhängen).
use MIME::Lite;
### Create a new multipart message:
$msg = MIME::Lite->new(
From =>'me@myhost.com',
To =>'you@yourhost.com',
Cc =>'some@other.com, some@more.com',
Subject =>'A message with 2 parts...',
Type =>'multipart/mixed'
);
### Add parts (each "attach" has same arguments as "new"):
$msg->attach(Type =>'TEXT',
Data =>"Here's the GIF file you wanted"
);
$msg->attach(Type =>'image/gif',
Path =>'aaa000123.gif',
Filename =>'logo.gif'
);
$text = $msg->as_string;
MIME::Lite beinhaltet auch eine Methode, um diese Dinge zu senden.
$msg->send;
Das benutzt standardmäßig sendmail, kann aber so angepasst werdn, dass es SMTP via the Net::SMTP manpage verwendet.
Auch wenn Du das Mail::Folder Modul von CPAN (Teil des MailFolder Pakets)
oder das Mail::Internet Modul von CPAN (Teil des MailTools Pakets) benutzen
kannst, ist ein Modul oft zu viel. Hier ist ein Mail-Sortierer.
#!/usr/bin/perl
my(@msgs, @sub);
my $msgno = -1;
$/ = ''; # paragraph reads
while (<>) {
if (/^From /m) {
/^Subject:\s*(?:Re:\s*)*(.*)/mi;
$sub[++$msgno] = lc($1) || '';
}
$msgs[$msgno] .= $_;
}
for my $i (sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msgs)) {
print $msgs[$i];
}
Oder mehr kurz und bündig,
#!/usr/bin/perl -n00
# bysub2 - awkish sort-by-subject
BEGIN { $msgno = -1 }
$sub[++$msgno] = (/^Subject:\s*(?:Re:\s*)*(.*)/mi)[0] if /^From/m;
$msg[$msgno] .= $_;
END { print @msg[ sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msg) ] }
(beigetragen von brian d foy)
Das Net::Domain Modul, das Teil der Standard-Distribution seit perl5.7.3 ist,
kann Dir den vollqualifizierten Domain-Namen (FQDN), den Hostnamen oder den
Domain-Namen holen.
use Net::Domain qw(hostname hostfqdn hostdomain);
my $host = hostfqdn();
Das Sys::Hostname Modul, in der Standard-Distribution seit perl5.6, kann cu
den Hostnamen holen.
use Sys::Hostname;
$host = hostname();
Um die IP-Adresse zu bekommen, kannst Du die gethostbyname Built-in Funktion
verwenden und den Namen in eine Nummer umwandeln. Um diese Nummer in die Oktett-Form
mit Punkten (a.b.c.d) zu bekommen, die die meisten Leute erwarten, benutze die
inet_ntoa Funktion aus dem Socket Modul, das ebenfalls mit perl mitkommt.
use Socket;
my $address = inet_ntoa(
scalar gethostbyname( $host || 'localhost' )
);
Benutze das Net::NNTP- oder News::NNTPClient-Modul, die es beide auf dem
CPAN gibt. Das macht Aufgabe wie das holen der Newsgroup-Liste so einfach wie
perl -MNews::NNTPClient
-e 'print News::NNTPClient->new->list("newsgroups")'
LWP::Simple (auf dem CPAN verfügbar) kann Dateien holen aber nicht hochladen.
Net::FTP (ebenfalls auf dem CPAN verfügbar) is komplexer kann aber sowohl Dateien
hochladen als auch holen.
(beigetragen von brian d foy)
Benutze eines der RPC-Module, die Du auf CPAN finden kannst ( http://search.cpan.org/search?query=RPC&mode=all ).
Revision: $Revision$
Datum: $Date$
Für Details über Versionskontrolle und Verfügbarkeit siehe perlfaq.
Copyright (c) 1997-2009 Tom Christiansen, Nathan Torkington und andere Autoren wie genannt. Alle Rechte vorbehalten.
Diese Dokument ist frei; Du kannst es unter den gleichen Bedingungen wie Perl selbst weiterverteilen und/oder verändern.
Unabhängig von der Verteilung, sind alle Code-Beispiele Gemeingut. Dir wird erlaubt und du wirst ermutigt, sie und beliebige davon abgeleitete in deinen Programmen zum Spaß oder für Profit zu verwenden. Ein einfacher Kommentar im Code, der die FAQ würdigt, wäre nett, ist aber nicht erforderlich.
Übersetzung von Renée Bäcker