Nov 23

Seit gestern schlug ich mich mit einem Problem rum, mittels des CPAN-Modules Net::FTP von einem passivem FTP-Server eine Datei zu laden. Leider schlugen alle Versuche immer fehl. Anbei das Beispiel-Script:


#/usr/local/bin/perl

use strict;
use Net::FTP;

# benötigte Variablen
my ($ftpserver, $ftppath, $ftpdatei, $modtime, $update) = ("")x5;
my $ftppassiv = 1;
my $ftpport = 21;
my $ftpuser = "gast";
my $ftppassword = "geheim";
my $ftplink = "ftp.comnart.de/logs/www.comnart.de_ftp_access.log.zip";
my $lokaledatei = "access.log";
my $zipname = "www.comnart.de_ftp_access.log";

# FTP Link zerlegen
if ($ftplink =~ /^(.*?)\/(.*\/)?(.*?)$/) {
$ftpserver = $1;
$ftppath = $2;
$ftpdatei = $3;
} else {
die "Kann den FTP Link nicht zerlegen!\n";
}

# FTP Verbindung aufbauen
my $ftp = Net::FTP->new(
$ftpserver,
PORT => $ftpport,
PASSIVE => $ftppassiv,
Timeout => 60) or die "Konnte die FTP-Verbindung nicht aufbauen: $@\n";

# FTP Login
$ftp->login($ftpuser, $ftppassword) or die "Konnte nicht einloggen";

# Verzeichniss wechseln falls nötig
$ftp->cwd($ftppath) if $ftppath;

# ÜbertragungsModus umschalten, entsprechend der Datei-Endung
## XML, Text, CSV und HTML Dateien im ASCII-Modus
$ftp->ascii() if $ftpdatei =~ /\.(txt|csv|html|xml)$/i;
## Zip, XLS und DBase Dateien im BINÄR-Modus
$ftp->binary() if $ftpdatei =~ /\.(gz|zip|xls|dbf|bz2)$/i;

# FTP-Feature MDTM verfügbar?
if ($ftp->feature( 'MDTM' )) {
$modtime = $ftp->mdtm($ftpdatei)
or print "Konnte das Datum der Datei $ftpdatei: nicht lesen: $@\n";
} else {
# Alternativ Verzeichniss auslesen und Datum extrahieren
my $ls = $ftp->dir();
foreach my $entry (parse_dir($ls)) {
my ($name, $type, $size, $mtime, $mode) = @$entry;
if ($type eq 'f') {
next unless ($name eq $ftpdatei);
$modtime = $mtime;
}
}
}

# Überprüfen, ob die Datei lokal schon aktuell & vorhanden ist
my @lokalinfo = stat($lokaledatei);
if ($modtime ne $lokalinfo[9])
{
# Alte Datei loeschen
unlink $lokaledatei or do print "Fehler beim löschen der alten lokalen Datei! $lokaledatei";

if ($zipname){
my $extraktok = 0;
# Neue Datei per FTP holen
$ftp->get($ftpdatei,$lokaledatei.".zip") or die "Konnte die Datei $ftpdatei -> ".$lokaledatei.".zip nicht empfangen: $@\n";

# Datei entpacken
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new();
die "Winzip 'read error' " if $zip->read($lokaledatei.'.zip') != AZ_OK;
if ($zip->extractMember($zipname,$lokaledatei) != AZ_OK) {
print "Winzip 'write error' ";
} else {
$extraktok = 1;
}

# Zip-Datei loeschen
if ($extraktok) {
unlink $lokaledatei.'.zip' or print "Fehler beim löschen der gezippten Datei!";
} else {
print "Fehler beim Entpacken, Datei nicht gefunden ";
}

} else {
$ftp->get($ftpdatei,$lokaledatei) or do print "Konnte die Datei $ftpdatei: nicht empfangen: $@\n";
$update = 1;
}
} else {
$update = 0;
}

$ftp->close() or print "Konnte Verbindung nicht schließen";

if ($update) {
# Zeitstempel größer aktuelle Zeit?
$modtime = time if ($modtime > time); # Zeit auf Server größer aktueller Zeit
$modtime = time if ($modtime < 1); # Hack: Hier sollte man sich was besseres einfallen lassen ;)
# Neue Datei mit Zeitstempel setzen
utime ($modtime,$modtime,$lokaledatei);
print "Download der Datei erfolgreich! (Timestamp: $modtime)\n";
} else {
print "Datei ist aktuell (Timestamp: $modtime)\n";
}

exit(0);

Im passiven Modus funktionierte alles bis zum

$ftp->get($ftpdatei,$lokaledatei) or do print "Konnte die Datei $ftpdatei: nicht empfangen: $@\n";

an dieser Stelle brach das Script mit der Meldung, das ein Abruf der Datei nicht möglich sei ab.

Nach langer Suche bei Google fand ich in diesem Forum den passenden Tip! :)
Die Lösung ist eigentlich ziemlich simpel. Einfach vor dem Login folgende Zeile einfügen:

$ENV{FTP_PASSIVE} = $passiv ? 1 : undef;

und schon funktioniert es auch mit problematischen passiven FTP-Servern!

Tagged with:
Apr 13

Um mit Perl XSL-Transformationen durchführen zu können, wollte ich zunächst das nachfolgende einfache Beispiel aus dem CPAN-Archiv ausprobieren:

use XML::LibXSLT;
use XML::LibXML;

my $xslt = XML::LibXSLT->new();
my $source = XML::LibXML->load_xml(location => 'foo.xml');
my $style_doc = XML::LibXML->load_xml(location=>'bar.xsl', no_cdata=>1);
my $stylesheet = $xslt->parse_stylesheet($style_doc);
my $results = $stylesheet->transform($source);

print $stylesheet->output_as_bytes($results);

Jedoch bekam ich nur folgende Fehlermeldung:

Can't locate object method "load_xml" via package "XML::LibXML"

Die Suche bei Google ergab, das bei Ubuntu 9.10 nur XML::LibXML in der Version 1.68 in den Ubuntu-Quellen vorliegt, die Funktion “load_xml” aber erst in Version 1.70 existiert. Somit blieb nur die Installation über das CPAN-Archiv mittels
perl -MCPAN -e shell .

Das Perl-Modul wurde aus dem CPAN-Archiv erfolgreich installiert, aber das obige Beispiel funktionierte immernoch nicht. Jetzt meldete sich das Perl-Modul XML::LibXSLT mit der Fehlermeldung, das dieses Modul in Version 1.68 auch das Perl-Modul XML::LibXML in Version 1.68 benötigt!
Okay also das Perl-Modul XML::LibXSLT auch in Version 1.70 aus dem CPAN-Archiv installieren. Der Versuch wurde jedoch leider mit folgender Fehlermeldung abgebrochen:

/usr/bin/ld: cannot find -lgdbm

Die Suche bei Google war diesmal nicht so erfolgreich, der einzige Hinweis war, das es wohl an der Library libgdbm.so liegt. Diese war bei mir jedoch bereits installiert und ein libgdbm-perl Paket in den Ubuntu-Quellen gab es nicht, nur Pakete für Ruby und Smalltalk. Jedoch gab es das Paket libgdbm-dev, welches ich installierte und mit somit zur Lösung des Problems führte.

Jetzt funktioniert obiges Beispiel fehlerfrei und ich kann mit dem ausprobieren loslegen! :)

Nachtrag:

Unter Debian waren zusätzlich zur Installation des Paketes libgdbm-dev noch die Pakete libxslt1-dev und libxml2-dev notwendig bevor(!) sich aus dem CPAN-Archiv die aktuellen
Perl-Module XML::LibXML und XML::LibXSLT installieren ließen.
Ohne die Installation dieser Entwicklerpakete meldete der Versuch der CPAN-Archiv Installation folgende Fehler:
looking for -lxml2... no
looking for -llibxml2... no
libxml2 not found

Tagged with:
Mrz 11

Nachdem ich vorgestern endlich mein Nexus One erhalten habe und die Datenflatrate (Internet) von E-Plus gestern morgen Punkt 8 Uhr eingerichtet war, benötigte ich dennoch einen ganzen Tag um festzustellen warum ich nicht per Mobilfunknetz ins Internet kam. Die Einstellungen für den Internetzugang über E-Plus laut deren Homepage und diversen Internetforen waren korrekt.

Ich habe unter Einstellungen -> Drahtlos und Netzwerke -> Mobile Netzwerke -> Zugangspunkte habe ich mittels der Menütaste den Punkt Neuer APN ausgewählt und folgende Daten eingetragen:
Name: E-Plus Internet
APN: internet.eplus.de
Nutzername: eplus
Passwort: gprs
MCC: 262
MNC: 03
Authentifizierungstyp: PAP
APN-Typ: default
alle anderen Parameter habe ich auf nicht festgelegt gelassen.

Soweit ist ja alles Richtig gewesen, jedoch der Versuch über den Browser ins Internet zu gehen waren erfolglos. Und bei Google Maps bekam ich die Fehlermeldung Datenverbindung unterbrochen. Erneuter Verbindungsaufbau. oder Netzwerkfehler.
Die lapidare Antwort der E-Plus Hotline war, dies ist kein Gerät, welches ich von E-Plus bezogen haben, deshalb können sie mir keinen technischen Support geben, ich möchte mich bitte an meinen Gerätehersteller wenden. :(

Die Lösung ist dabei ganz einfach und ich war schon kurz vor dem Aufgeben, als ich durch Zufall irgendwo gelesen habe, wie jemand beiläufig schrieb alles eingerichtet, neu gestartet und es lief. Da machte es mir Klick: Neustart war wohl die Lösung. Und tatsächlich nach dem Aus- und wieder Einschalten des Nexus One funktionierte mein Internet über E-Plus sofort problemlos. Erkennbar, war dies auch daran das neben der Signalstärke des Netzempfangs das Symbol 3G auftauchte.

Tagged with:
preload preload preload