Mai 29

Das Perl-Modul WWW::Shorten::Bitly als solches bietet die Moeglichkeit URLs, die zuvor mit bit.ly verkuerzt worden sind, wieder zu “expanden” und auch diverse Clickstatistiken auf diese URLs zu fahren.

Leider hat das Modul ein paar Schoenheitsfehler:

  1. Beim “Expanden” meint das Modul die Methode “GET” nutzen zu wollen. Die API von bit.ly schreibt hier aber ein “POST” vor. Das ist recht zuegig gefixed. Einfach in der Zeile 257 (Methode “expand” der Version 1.14) aus dem get ein post machen -> Fertig :-)
  2. Beim Aufruf der Methode “clicks” auf URLs mit vielen Statistik-Daten (Referrers, etc.) versagt der SAX-Parser auf ganzer Linie. Er quittiert das Parsen mit einer Fehlermeldung a’la: End tag mismatch (nodeKey != nodeValue) [Ln: x, Col: yyyyy]Das Problem laesst sich dadurch loesen, dass man dem XML::Simple Modul sagt, es soll gefaelligst einen Ordentlichen parser benutzen. z.B. den XML::Parser (der zuvor via cpan installiert werden muss (setzt libexpat1-dev vorraus !)). Wir teilen dies dem Bitly Modul nach dem Einbinden von XML::Simple ueber folgenden String mit: $XML::Simple::PREFERRED_PARSER = 'XML::Parser'; … und oh Wunder: Alles funktioniert

In diffs ausgedrueckt sind folgende Aenderungen an WWW::Shorten::Bitly Version 1.14 notwendig:

22a23,24
> $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
>
257c259
< $self->{response} = $self->{browser}->get($self->{BASE} . '/expand', [
---
> $self->{response} = $self->{browser}->post($self->{BASE} . '/expand', [

Ab nun klappt auch das Auslesen mit dem Modul.

Tagged with:
Mai 12

Sachverhalt: Zig dilettantisch benannte Dateien mit Leerzeichen und Umlauten in wiederrum zig Verzeichnissen (Windeutsch: Ordner).

Wunsch: umbennen der Files mit einem Schlage

Lösung:

Shellscript:

#!/bin/bash
find . -depth -execdir rename 's/ä/ae/g;s/ö/oe/g;s/ü/ue/g;s/ß/ss/g;s/ /_/g' "{}" \;
find . -depth -execdir rename 's/Ä/Ae/g;s/Ö/Oe/g;s/Ü/Ue/g;s/ß/ss/g;s/ /_/g' "{}" \;

Tagged with:
Jan 14

Einfach nur Göttlich

Jan 05

… schonmal versucht Abhängigkeiten grafisch darzustellen ? Am besten noch aus Datenbankcontent ?

Klar, man könnte zu irgendwelchen proprietären MindMap-Tools oder gar zu M$-Visio (oh grauss !) greifen. Dabei geht es mit graphviz in Verbindung mit “dot” soooo einfach. Das Ding ist ehrlich einen Blick wert. Zusammen mit der “Connect by Prior” Clause in Oracle ist das Teil der Knaller schlechthin.

Ein wenig Doku dazu (die original-Doku ist recht schwere Kost) gibt es z.B.

Das allerbeste ist, dass MediaWiki das Ding von Haus aus unterstützt, und man derartige Graphen direkt per Wiki-Editor in die Artikel einbetten kann…

Tagged with:
Dez 29

Aufmerksam geworden durch diesen Artikel, mit dem ueber den Proxy geholte Webseiten (genauer gesagt werden alle Images einmal um 180 Grad gedreht) on the Fly manipuliert werden habe ich mir das ganze mal näher angesehen und optimiert.

Vorweg schonmal das Ergebnis (funktioniert TRANSPARENT mit allen JPGs, GIFs und PNGs). Transparent bedeutet in diesem Falle, dass der Anwender in keinerlei Weise mitbekommt, dass es sich hier um ein manipliertes Bild handelt. Die Requests werden quasi 1:1 durchgeleitet.

Wor moechten also alle Bilder, die aus dem LAN via Proxy angefordert werden, einmal um 180 Grad drehen. Folgende Ausgangssituation:

  • Transparenter Squid auf einem Router
  • Webserver auf einem etwas dickeren Rechner im LAN

in /etc/squid/squid.conf folgende Zeile einfügen:

url_rewrite_program /usr/bin/updwn.pl
url_rewrite_children 5

Das File /usr/bin/updwn.pl sollte wie folgt aussehen:

#!/usr/bin/perl
# Runs as proxy:proxy
# input - siehe unten (Array params)
# output - URL - transparent *invisble to Enduser :-) *
$|=1;
while (<>) {
chomp $_;
@params=split(/ /,$_);
# 0 = Request URL
# 1 = Requesting IP/-
# 2 = -
# 3 = Request Method
# 4 = myip= ?
# 5 = myport = ?
$url=$params[0];
if (!($params[1]=~/192\.168\.60\.200/)) { # Nicht rekursiv aufrufen (Boese !!)
$url='http://192.168.60.200/ppics/updwn.pl?u='.$url if ( ($url=~/gif/i) || ($url=~/jpg/i) || ($url=~/jpeg/i) || ($url=~/png/i));
}
print $url."\n";
$count++;
}

Wobei die 192.168.60.200 durch die IP des eigenen Webserver zu ersetzen waere. Die eigentliche “Magie” findet naemlich jetzt im updwn.pl auf dem Webserver statt. Das Ding benutzt, im gegensatz zu dem File, welches in dem Artikel beschrieben wurde, direkt die GD-Library und ruft keinerlei Executables mehr auf. Damit ist das Script ein wenig performanter

Hier der Inhalt von /var/www/ppics/updwn.pl:

use CGI qw/:standard/;
use LWP::UserAgent;
use GD;
binmode STDOUT;

$|=1;
my $url=param(“u”);

chomp $url;
my $ctype=”;
my $content=”;
get_content($url,\$ctype,\$content);
rotate(\$content,\$ctype) if ($ctype=~/image/i);
print “Content-Type: “.$ctype.”\n\n”;
print $content;
print “\n–magicalboundarystring\n” if ($ctype=~m/image/);

sub get_content {
my ($url,$ref_ctype,$ref_content)=@_;
my $ua = LWP::UserAgent->new;
$ua->agent(“MyApp/0.1 “);
my $req = HTTP::Request->new(GET => $url);
my $res = $ua->request($req);
$$ref_ctype=$res->content_type;
$$ref_content=$res->content;
}

sub rotate {
my ($ref_content,$ref_header)=@_;
my $image=undef;
$image=newFromPngData GD::Image($$ref_content) if ($$ref_header=~/png/i);
$image=newFromJpegData GD::Image($$ref_content) if ($$ref_header=~/jpeg/i);
$image=newFromGifData GD::Image($$ref_content) if ($$ref_header=~/gif/i);
$image->rotate180();
$$ref_header=’image/png’;
$$ref_content=$image->png();
}
Wichtig: Die URL sollte nicht aus dem Internet erreichbar sein. Ansonsten hat man einen selbstgebastelten offenen Proxy…

Mithilfe der Parameter des Files /usr/bin/updwn.pl kann man sich jetzt sogar lustige ACLs bauen. (Rotiere nur fuer bestimmte IP’s oder fuer bestimmte URLs, etc…) Der Phantasie sind da keine Grenzen gesetzt.

Tagged with:
Dez 28

Oh wie wahr….

Nov 22

Man kennt das. Gerade frisch einen Postfix aufgesetzt, eine Testmail losgelassen und Zaaack! – das Ding will nicht rausgehen. Jetzt dümpelt die Mail bis zum Timeout in der Queue herum. Abhilfe habe ich früher geschaffen in dem ich mir via mailq die Mail-ID herausgekramt habe und dann mühsam durch die spool Directories gegangen bin um ein File nach dem anderen zu löschen. Es geht eleganter:

mailq aufrufen um die Mail-ID zu bekommen

und anschliessend nur noch “postsuper -d <mail-id>” aufrufen um die Mail zu töten. Fertig….

Ja, die meisten werden es kennen. Nur so vergesse ICH das garantiert nicht mehr :-)

Sep 03

Ein Update des DBD::Oracle Treibers von 1.16 auf 1.21 klingt zunaechst unspektakulaer. Aber wie so oft steckt der Teufel im Detail. Benutzt man nämlich persistente Verbindungen unter mod_perl mit dem Modul Apache::DBI, ändert sich das Verhalten beim disconnecten von der DB. In der Regel cached das mod_perl die Verbindungen ja, daran hat sich auch nichts geaendert.

Bei der 1.16er Version jedoch impliziert das disconnect ein commit. Das hängt laut Modul-Doku von gutdünken des (Modul-)Entwicklers ab. Hat man seine Applikation jetzt darauf ausgerichtet, dann macht man nie ein Commit (sollte man nicht tun !). Dumm nur, dass dieses Verhalten bei der 1.21er geändert wurde. Nun impliziert das Modul beim disconnecten nämlich ein Rollback. Und das macht es selbst dann, wenn ein commit vorrausgeht.

Im ersten Ansatz ist das verschmerzbar. Wenn die DB allerdings, selbst bei Skripten die nur SELECTen, jedesmal mit einem Rollback belaestigt wird, kommt da schon einiges zusammen. Das Verhalten lässt sich mit folgendem “Workaround” aendern:

Aus einem $dbh->disconnect() wird ab sofort ein

$dbh->{AutoCommit}=1;
$dbh->disconnect();

Das AutoCommit wird also kurz vorm disconnecten gesetzt, und beeinflusst das sonstige Rollback/Commit-Verhalten im gesamten Skript ueberhaupt nicht. Sobald ein neues Connect (auch in einer persistenten mod_perl Umgebung) kommt, werden (auch bei gecachter DB-Verbindung) die Parameter AutoCommit, etc., eh neu gesetzt. Damit verhält sich alles wieder wie vorher.

Aug 15

Folgendes Problem:
Irgendein Daemon moechte einen Listener aufbauen und grabscht sich anstelle des IPv4 Sockets ein IPv6 Socket. Dummerweise kann man das dem Daemon nicht abgewoehnen, da dieser kein config-File oder Closed-Source ist. Abhilfe schafft das disablen des kompletten ipv6 Stacks. Wie das geht ?

Einfach in der /etc/modprobe.d/aliases folgende Zeile abaendern (die obere Zeile ist das original):

#alias net-pf-10 ipv6
alias net-pf-10 off

Danach rebooten (ohne geht leider beim 2.6er Kernel nicht) und gut ist.

Jul 31

Oft gesehen, nie benutzt. Zu der Kategorie gehoert wohl das kleine aber feine Tool “at”. Quasi ein “Wegwerf”-CRON. Dabei ist das Ding totsimpel zu bedienen, und dazu noch extremst nützlich. Wie es funktioniert ? Folgendermassen:

Angenommen ich muss dringend noch ein paar Files per scp kopieren, kann das aber erst machen, wenn kein Betrieb mehr auf dem Produktionssystem herrscht. Erschwerend kommt jetzt noch hinzu dass, sagen wir, der Betrieb erst gegen 23:00 beendet ist. Ein klassischer Fall für at:

at 23:00 [CR] (danach befinden wir uns im Commandmode)
scp Datei user@system:/directory [CR]
[CTRL+D]

Nun lediglich den Rechner auf dem das Kommando abgesetzt wurde anlassen (oder noch besser: Auf einem Remotesystem ausführen und anschliessend ausloggen) und ab gehts um 23:00 :-)

Eine Besonderheit für Mac-User gibt es noch. Der Dienst der die at-jobs (Eine Liste derer gibts übrigens via “atq”) startet, ist defaultmässig nicht gestartet. Das kann man via:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

nachholen.

Viel Spass beim “at”ten …

Jul 22

Wer sich mit folgender Fehlermeldung bei der Benutzung von CGI::Ajax unter Perl herumquaelen muss, dem sei ein Downgrade auf die Version CGI-Ajax-0.697 ans Herz gelegt. Damit ist die Fehlermeldung naemlich dann Geschichte:

Undefined subroutine CGI=HASH(0xBLABLABLA)::header_type at CGI::Ajax line xxxx

Jun 20

Mit bind geht das schon lange. Man hat 2 Netze, mit jeweils zwei unterschiedlichen Nameservern die die privaten Adressen im jeweiligen LAN auflösen. Will man jetzt, z.B. via VPN beide Nameserver aus den jeweiligen LANs nutzen, so konfiguriert man den bind für die jeweiligen Netze als forwarder (Jeweils für das Netz mit seinem Nameserver einen Eintrag). Ein Beispiel:

Gegeben seien ein LAN mit der Domäne Intranet1.de und dem Nameserver 192.168.0.222, und das LAN mit der Domain intranet2.de welches seinen DNS auf 10.0.0.222 liegen hat. Natürlich gibts noch einen öffentlichen Nameserver, der hat in unserem Beispiel die 212.121.212.111 als IP.

In der named.conf sieht das dann so aus:

options {
directory “/var/named”;
forwarders { 212.121.212.111;};
};

zone “intranet1.de” in {
type forward;
forwarders {192.168.0.222; };
forward only;
};

zone “intranet2.de” in {
type forward;
forwarders {10.0.0.222; };
forward only;
};

Beim Mac ist das viel simpler. Man lege ein Directory /etc/resolver an und lege dort einfach pro Zone ein File ab. In diesem Beispiel wäre das dann /etc/resolver/intranet1.de mit dem Inhalt “nameserver 192.168.0.222″ und eine zweite Datei mit /etc/resolver/intranet2.de mit Inhalt “nameserver 10.0.0.222″. Fertig. Dumm nur das das ganze nicht persistent ist. Nach dem Neustart ist alles weg. Nicht so wenn man sich die Dateien per Shellscript aus der /etc/rc.common erstellen lässt. Funktioniert prima und ist simpel.

Jun 02

Als merker (einer der klamotten, die man immer wieder nachschlagen muss).

Will man die Hardware Clock unter Linux setzen, nehme man hwclock. Syntax:

hwclock –set –date=”10/10/02 10:45:00″

Wobei das Datumsformat = “MM/DD/YY HH24:MI:SS” ist.

Mrz 08

Wem Nagios schon immer etwas zu komplex zum konfigurieren war, der versuche sich doch mal an Monit.
Das Teil muss zwar auf jedem einzelnen Rechner laufen, den es Monitoren soll, und es hat auch nicht ganz so viele Einstellungen wie Nagios, aber es kann Prozesse, TCP-Ports, ICMP-Pings uvm. monitoren und sogar bei bedarf von alleine restarten.
Zusätzlich informiert es einen per Mail was so gerade passiert. Als Extra-Bonbon gibt es ein (minimalistisches) Webinterface das einen schnell und zuverlässig über den Gesundheitszustand des zu monitorenden Rechners informiert.
Ist auf jeden Fall einen Blick wert, das Tool…

Feb 11

Wer schon immer mal überzeugende Argumente GEGEN php suchte, ist bei helmboldt.de richtig aufgehoben. Wusste garnicht das PHP soooo (!) gruselig ist…

gefunden bei roothausen.de

Update: Unter verplant.org gibt es einen objektiven Vergleich zwischen Perl und PHP – in jedem Falle Lesenswert

preload preload preload