Objavljeno: 25.6.2005 12:53 | Avtor: Dalibor Kranjčič | Monitor Junij 2005

Perl - programska izvedba poštnega odjemalca in odjemalca FTP

Perl (Practical Extraction and Report Langauge) je programski jezik, ki je bil prvotno namenjen pregledovanju in obdelavi tekstovnih datotek ter ustvarjanju poročil iz pridobljenih podatkov, vendar danes ponuja veliko več. Prosto dostopni perlovski moduli nadgradijo obstoječo funkcionalnost z vnaprej pripravljenimi razredi, funkcijami in rutinami. Z vključevanjem teh v kodo lahko povsem preprosto pošljemo sporočilo elektronske pošte ali preslikamo datoteko v oddaljeni računalnik s prenosom FTP.

Prvo različico perla je izdal gospod Larry Wall leta 1987. Sintaksa perla je zelo jasna in učinkovita ter zajema najboljše lastnosti programov za obdelavo besedil v Linuxu, na primer sed in awk, in programskega jezika C. Perl je ponavadi že del standardnih distribucij Linuxa, razen določenih modulov, katerih namestitev izvedemo posebej.

Perlovski moduli

Perlovski moduli so prosto dostopni. Najdemo jih v spletnem arhivu CPAN (Comprehensive Perl Archive Network) na spletni strani http://www.cpan.org/. Arhiv CPAN ponuja veliko raznovrstnih perlovskih modulov, na primer: omrežni moduli, moduli za obdelavo podatkov in razhroščevanje, moduli za upravljanje časa, matematični moduli itn. V arhivu CPAN so tudi dokumentacija in navodila za perl ter distribucije perla za različne operacijske sisteme.

V nadaljevanju bomo opisali uporabo modulov perl za branje in pošiljanje sporočil elektronske pošte ter prenos datotek v oddaljen računalnik s protokolom FTP. Za tako funkcionalnost potrebujemo naslednje module:

Net::FTP

modul za izvedbo odjemalca FTP

Net::SMTP

modul za povezovanje s strežnikom za odhajajočo pošto SMTP

Mail::POP3Client

modul za povezovanje s strežnikom za prihajajočo pošto POP3

IO::Handle

modul vhodno/izhodnih funkcij

Več informacij o modulih dobimo z uporabo ukaza perldoc v ukazni lupini (podobno kot ukaz man).

Zgled uporabe ukaza perldoc v ukazni lupini:

# perldoc Net::FTP

NAME

Net::FTP - FTP Client class

SYNOPSIS

use Net::FTP;

$ftp = Net::FTP->new("some.host.name", Debug => 0);

$ftp->login("anonymous",'me@here.there');

$ftp->cwd("/pub");

$ftp->get("that.file");

$ftp->quit;

(Izsek izpisa ukaza perldoc).

Namestitev perlovskih modulov

Na glavni spletni strani arhiva CPAN kliknemo povezavo PerlModules. Odprla se bo spletna stran, na kateri izberemo iskalnik modulov Randy Kobe's serach. V vnosno polje Find vpišemo ime modula, na primer Net::FTP. V precejšnjem številu izpisov izberemo samo povezavo Net::FTP. Modul prenesemo k sebi s klikom povezave Download.

Preneseno datoteko v formatu tar.gz raztegnemo v ukazni lupini z ukazom tar:

# tar -xzvf perl_modul.tar

Nato v ukazni lupini vpišemo še naslednje ukaze:

# perl Makefile.PL

# make

# make test

# make install

Zgornji postopek ni rutina za vse namestitve modulov. Pred vsako namestitvijo se svetuje predhodno branje datotek INSTALL in README, ki sta sestavni del datoteke za namestitev modula.

Zagon programa v perlu

Perl navadno deluje kot tolmač (interpreter), ki vsak ukaz, zapisan v navadni datoteki, sproti prevaja v strojno kodo in sproti izvaja.

Program oziroma datoteko, ki vsebuje ukaze programskega jezika perl, lahko "zaženemo" v ukazni lupini z ukazom perl, ki mu sledi ime te datoteke.

Zgled:

# perl ./ime_datoteke

ali pa

# /Pot_do_ukaza_perl/perl ./ime_datoteke

Zagon programa v perlu je mogoč tudi le s sklicevanjem na ime datoteke (programa) v ukazni lupini. V ta namen na začetku datoteke dodamo vrstico #!/usr//bin/perl, ki določa pot do izvršljive datoteke oziroma ukaza perl.

#!/usr/bin/perl

# Komentar: To je program oziroma datoteka ping, ki vsebuje ukaze jezika perl.

# Komentar: Program ping preveri, ali je racunalnik v krajevnem omrezju viden.

use Net::Ping;

$host='Naslov_IP ali_gostiteljsko ime';

$p = Net::Ping->new();

print "$host je ziv.\n" if $p->ping($host);

$p->close();

Z ukazom chmod najprej nastavimo dovoljenje za izvajanje zgornjega programa in ga nato zaženemo v ukazni lupini kot uporabnik root:

# chmod a+x ping

#./ping

Poštni odjemalec

V nadaljevanju bomo opisali program mailclient, ki izvaja branje zadnjih sporočil elektronske pošte, prispelih v poštni strežnik za prihajajočo pošto POP3. Vsaka vrstica kode, ki jo začnemo z znakom #, predstavlja komentar. Takoj za prvotnimi komentarji sledi vrstica use strict, poimenovana še pragma, ki poudarja uporabo najbolj striktnih pravil za prevajanje kode. Nadaljujemo še s pragmo use warnings, ki poskrbi za izpis vseh možnih opozorilnih sporočil. Ukazi use se prav tako uporabljajo za vključevanje modulov perl v kodo:

use Mail::POP3Client; - Modul za povezovanje s poštnim strežnikom POP3.

use IO::Handle; - Zbirka metod za izvajanje vhodno/izhodnih operacij.

Konstante v perlu so deklarirane s pragmo use constant. Za deklaracijo spremenljivk uporabimo ključno besedo my. Znak $ pred spremenljivko označuje skalarni značaj spremenljivke.

Sporočila beremo v zanki do-while s časovnimi premori, ki so določeni s parametrom TIME. Pogoj zanke je, da število trenutnega poštnega sporočila $cnt ne preseže števila vseh prispelih poštnih sporočil, ki ga dobimo z metodo $pop->Count.

Pred vstopom v zanko ustvarimo povezavo na strežnik POP3 z metodo $pop->new:

$pop = Mail::POP3Client -> new (ACCOUNT, PASSWORD, HOSTNAME, PORT, DEBUG);

Uporabljeni so naslednji parametri povezave:

HOSTNAME

Gostiteljsko ime poštnega strežnika.

ACCOUNT

Uporabniško ime za povezavo na poštni strežnik.

PASSWORD

Geslo za povezavo na poštni strežnik.

MAILFILE

Datoteka, v katero se vpisujejo prebrana sporočila.

PORT

Vrata za povezovanje na strežnik POP3.

DEBUG

Vrednost, večja od 1, pomeni, da je razhroščevanje ob povezovanju vključeno.

V zanki najprej izvedemo odpiranje datoteke MAILFILE z ukazom open. Datoteka MAILFILE bo zdaj označena z ročico datoteke MESSAGE. V nadaljevanju ustvarimo nov objekt razreda IO::Handle oziroma modula vhodno/izhodnih funkcij. Objektu priredimo datoteko MAILFILE z metodo fdopen, ki ji kot argument posredujemo datotečni deskriptor. Pretvorbo ročice datoteke MESSAGE v datotečni deskriptor izvede metoda fileno. Sporočila preberemo z metodo $pop->BodyToFile. Vhodna parametra te metode sta objekt $fd in številka poštnega sporočila.

#!/usr/bin/perl

# Program mailclient - To je pravi postni odjemalec.

# Program vpise zadnja prispela sporocila v

# postni streznik POP3 v datoteko MAILFILE.

use strict;

use warnings;

# *** Moduli ***

# Modul za povezovanje s streznikom POP3

use Mail::POP3Client;

# Modul vhodno/izhodnih funkcij

use IO::Handle;

# *** Konstantni parmetri ***

# Ime postnega streznika

use constant HOSTNAME    => 'pop3.company.net';

# Uporabnisko ime

use constant ACCOUNT     => 'uporabnisko_ime';

# Geslo

use constant PASSWORD    => 'geslo';

# Datoteka v katero se vpisujejo sporocila

use constant MAILFILE    => '/home/uporabnik/mail';

# Casovni interval branja sporocila

use constant TIME  => 5;

# Vrata streznika POP3

use constant PORT   => 110;

# Razhroscevanje ob povezavi je vkljuceno

use constant DEBUG  => 1;

# Deklaracija spremenljivk

# Spremenljivka streznika POP3 (objekta Mail::POP3)

my $pop;

# Stevilka sporocila elekt. poste (trenutna)

my $cnt=1;

# Pa zacnemo...

# Ustvarimo novo povezavo na streznik POP3 (konstruktor)

$pop = Mail::POP3Client -> new

(ACCOUNT, PASSWORD, HOSTNAME, PORT, DEBUG);

# Prebere zadnja prispela sporocila

do {

# Odpiranje datoteke MAILFILE, v katero se pisejo postna sporocila

open(MESSAGE, """, MAILFILE) or die

"Ni mozno odpiranje datoteke za pisanje !\n";

# Konstruktor:Ustvarimo novi objekt razreda IO::Handle

my $fd = new IO::Handle();

# Objektu priredimo datoteko, ki je dolocena

# z rocico datoteke MESSAGE. Funkcija fileno izvede

# pretvorbo rocice datoteke MESSAGE v datotecni deskriptor

$fd->fdopen(fileno(MESSAGE) , "w");

# Pisanje postnega sporocila pod

# stevilko $cnt v datoteko MAILFILE

$pop->BodyToFile($fd, $cnt);

# Zapiranje datoteke

close(MESSAGE);

# Povecaj stevec za 1

$cnt++;

# Casovna pavza

sleep(TIME);

# Izvajaj od ukaza "do" do sem, vse dokler je

# trenutna st. sporocila manjsa od celotnega

# st. zadnjih prispelih sporocil v streznik

} while ($cnt <= $pop->Count);

# Zapremo povezavo s streznikom POP3

$pop->Close;

# Ocitno konec

Odjemalec FTP

Podali bomo zgled izvedbe odjemalca FTP v perlu s programom ftpclient. Program vključuje dvojno funkcionalnost: prenos datoteke v oddaljeni računalnik s protokolom FTP in obveščanje o morebitnem neuspešnem prenosu s pošiljanjem sporočila elektronske pošte. V tem smislu sta v kodo vključena modul za izvedbo odjemalca FTP (Net::FTP) in modul za izvedbo odjemalca za komunikacijo s strežnikom odhajajoče pošte SMTP (Net:SMTP).

Za povezovanje na strežnika uporabimo naslednje parametre:

FTPSERVER

Gostiteljsko ime ali naslov IP strežnika FTP.

USER

Uporabniško ime za povezavo na strežnik FTP.

PASSWORD

Geslo za povezavo na strežnik FTP.

DIR

Mapa na strežniku FTP, v katero bo preslikana datoteka FILE.

FILE

Datoteka, ki jo preslikamo v strežnik FTP.

TIME

Časovni premor med pošiljanjem datoteke FILE.

SMTPSERVER

Gostiteljsko ime ali naslov IP strežnika SMTP.

MAILFROM

Naš naslov elektronske pošte.

MAILTO

Naslov prejemnika sporočil elektronske pošte.

Prenos datoteke v strežnik se izvaja ciklično v zanki while s časovnimi premori, ki so določeni s parametrom TIME. Najprej izvedemo povezavo na strežnik FTP s pomočjo metode Net::FTP->new, ki nastopa kot izraz v kontrolni strukturi unless. Ukaz znotraj te kontrolne strukture se izvede samo, če je pogoj, ki ga preverjamo, neveljaven, oziroma če je bilo ustvarjanje nove povezave neuspešno. V nasprotnem primeru temu sledi izvajanje ukazov za prijavo na strežnik, premik v mapo, prenos datoteke in zaključevanje seje FTP (login, cwd, put in quit). Pri vsakem ukazu, ki se posreduje v strežnik FTP, preverjamo, ali se je pravilno zaključil s pomočjo ključnih besed or die, ki jim sledi logična spremenljivka, ki jo preverjamo v nadaljevanju. Ob neuspešni prijavi neuspešnega dostopa do mape in neuspešnega prenosa datoteke ali zaključevanja seje program izpiše opozorilo in pošlje poštno sporočilo s funkcijo sendmail.

Funkcija sendmail uporablja naslednje metode za pošiljanje poštnega sporočila:

new (SMTP_streznik)

Konstruktor - ustvarimo nov objekt Net::SMTP, pri čemer je SMTP_streznik gostiteljsko ime ali naslov IP strežnika SMTP.

mail (Posiljatelj)

Začetek prenosa za dostavo poštnega sporočila - pošlje ukaz MAIL v strežnik.

to (Prejemniki)

Obvestilo strežniku o prejemnikih poštnega sporočila.

data

Pove strežniku, da vrstice, ki sledijo, predstavljajo poštno sporočilo - pošlje ukaz DATA v strežnik.

datasend

Ukaz za pošiljanje glave (Head) in telesa (Body) poštnega sporočila.

quit

Pošlje ukaz QUIT v oddaljeni strežnik SMTP in zapre povezavo.

#!/usr/bin/perl

# Program je odjemalec FTP, ki prenasa datoteko FILE

# na streznik FTP. Ob napaki pri prenosu FTP

# program poslje sporocilo na postni naslov MAILTO

use strict;

use warnings;

# *** Moduli ***

# Modul za izvedbo odjemalca FTP

use Net::FTP;

# Modul za izvedbo protokola SMTP

use Net::SMTP;

# *** Konstantni parametri ***

# Ime streznika FTP

use constant FTPSERVER   => 'ftp.server.com';

# Uporabnisko ime za dostop v streznik FTP

use constant USER     => 'uporabnik';

# Geslo za dostop v streznik FTP

use constant PASS   => 'geslo';

# Mapa v strezniku FTP, v katero preslikamo datoteko

use constant DIR   => '/home/uporabnik/dir';

# Datoteka, ki jo prenasamo v streznik FTP

use constant FILE   => '/home/uporabnik/values';

# Cas ponovitve prenosa datoteke FILE

use constant TIME  => 5;

# Ime streznika SMTP

use constant SMTPSERVER => 'smtp.random.net';

# Nas naslov elektronske poste

use constant MAILFROM    => 'ime.priimek\@random.net';

# Naslov prejemnika sporocil

use constant MAILTO     => 'ime.priimek\@company.net';

# Logicne konstante

use constant FALSE  => 0;

use constant TRUE   => 1;

# Deklaracija spremenljivk

my $no_conn;

my $no_login;

my $no_dir;

my $no_transfer;

my $no_quit;

my $smtp;

my $ftpobj;

# Inicializacija spremenljivk

$no_conn = $no_login = $no_dir = $no_transfer = $no_quit = FALSE;

# Neskoncna zanka

while (TRUE) {

# Konstruktor: ustvarimo nov objekt Net::FTP

unless($ftpobj = Net::FTP->new(FTPSERVER, Timeout=>30, Debug=>1)) {

$no_conn = TRUE;

} else {

# Prijava na streznik FTP

$ftpobj-> login(USER, PASS) or $no_login = TRUE;

# Premik v mapo DIR

$ftpobj-> cwd (DIR) or $no_dir = TRUE;

# Preslikava datoteke FILE na streznik FTP

$ftpobj-> put (FILE) or $no_transfer = TRUE;

# Konec seje FTP

$ftpobj-> quit or $no_quit = TRUE;

}

#****************************************************

# Preverjanje uspesnosti prenosa: ob

# neuspesni prijavi, zavrnjenem dostopu do mape

# in neuspesnem prenosu datoteke posljemo sporocilo

# elektronske poste s pomocjo funkcije sendmail.

#****************************************************

if ($no_conn == TRUE) {

&sendmail("Ni povezave s streznikom!");

} elsif ($no_login == TRUE) {

&sendmail("Ni mozna prijava v streznik!");

} elsif ($no_dir == TRUE) {

&sendmail("Ni mozen dostop do mape v strezniku!");

} elsif ($no_transfer == TRUE) {

&sendmail("Ni mozen prenos datoteke v streznik ali

datoteka ne obstaja!");

} elsif ($no_quit == TRUE) {

&sendmail("Ne morem koncati ftp seje!");

} else {

print "Ocitno vse OK. \n";

}

# Ponastavi

$no_conn = $no_login = $no_dir = $no_transfer = $no_quit = FALSE;

# Casovna pavza - interval vnovicnega posiljanja datoteke

sleep (TIME);

}

# Funkcija posilja sporocilo elektronske poste

# msg - besedilo sporocila elektronske poste

sub sendmail {

my ($msg) = @_;

# Konstruktor::Ustvarimo nov objekt Net::SMTP

$smtp = Net::SMTP->new(SMTPSERVER, Debug => 1) or

die "Ne morem ustvariti povezave na streznik SMTP!";

$smtp->mail(MAILFROM);

$smtp->to(MAILTO);

# Zacetek sporocila

$smtp->data();

# Ustvarjanje glave postnega sporocila

$smtp->datasend("To: ", MAILTO, "\n");

$smtp->datasend("From: ", MAILFROM, "\n");

$smtp->datasend("Subject: Vase pojasnilo... \n");

$smtp->datasend("\n");

# Vsebina postnega sporocila

$smtp->datasend($msg);

# Konec sporocila

$smtp->dataend();

# Zapiranje povezave

$smtp->quit();

}

Naroči se na redna tedenska ali mesečna obvestila o novih prispevkih na naši spletni strani!

Komentirajo lahko le prijavljeni uporabniki

 
  • Polja označena z * je potrebno obvezno izpolniti
  • Pošlji