<< January 2022 >>
Sun Mon Tue Wed Thu Fri Sat
 01
02 03 04 05 06 07 08
09 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31



  • I mainly blog things related to NetBSD

  • my PGP Key is 0xB3FBAE33

  • my homepage


  • Profile

    Technorati Profile

  • If you want to be updated on this weblog Enter your email here:



    rss feed



    2006.09.04
    Usenet ist tot.

    Echt ekelhaft, was da für ein unsinniges Getrolle und Gejaule grenzdebiler Hirntoter abgeht.

    pkg_delete slrn wäre wohl die einzige Konsequenz.

    Posted at 07:38 pm by 0xb3fbae33
    Make a comment  

    2006.09.03
    Warum ist NetBSD so einzigartig?

    Vielleicht ist es ja schon aufgefallen, ich bastel zur Zeit mal wieder an den Flugblättern rum. Dazu brauche ich Vorschläge wie diese erweitert werden können.

    Mehr dazu in meiner Email auf deutsch: http://mail-index.netbsd.org/regional-de/2006/09/03/0009.html

    oder auf englisch: http://mail-index.netbsd.org/netbsd-users/2006/09/03/0007.html

    Außerdem gab es eine Diskussion auf BSDforen.de
    http://www.bsdforen.de/showthread.php?t=15986
    die schon einige Stichpunkte zu Tage förderte.

    Posted at 10:44 pm by 0xb3fbae33
    Make a comment  

    2006.08.01
    vim, RegExes und backreferencing

    Bisher habe ich elaboriertere RegExes nur in Perl eingesetzt, manchmal auch in sed. In vim hingegen eher nur kleinere Sachen.

    Jetzt hatte ich eine Liste der Art:

    Chapter_1.txt
    Chapter_10.txt
    Chapter_11.txt
    Chapter_2.txt
    Chapter_20.txt
    Chapter_3.txt



    Damit das ganze ordentlich sortiert wird, müssen natürlich führende Nullen her.

    Das geht nur mit backreferences, d.h. das was im Suchteil der RE getroffen wird, soll im Ersetzen-Teil wieder eingefügt bzw. verwand werden.

    Um die 1-9 zu treffen, genügt eine RE der Art:
    :s/_[0-9]\./

    Backreferences kann man mit & (für den gesamten Text) bzw. \1 \2 \3 usw. für das erste, zweite, dritte Muster.

    Dazu muss man nun den Suchteil der RE etwas umschreiben, indem man die Bestandteile (_ 0-9 und .) in runden Klammern zusammenfasst. Die Klammern wiederum müssen mit \ escaped werden.

    Die RE sieht dann so aus:


    :%s/\(_\)\([0-9]\)\(\.\)/\10\2\3/gi

    Das rote \(_\) trifft den Unterstrich, der mit der roten \1 wieder eingesetzt wird, das grüne \([0-9]\) trifft die einzelne Ziffer und wird mit der \2 wieder eingesetzt und das blaue \(\.\) bezieht sich auf den ., der ja als Sonderzeichen nocheinmal escaped werden muss. Zwischen der \1 und der \2 steht dann der Text der eingefügt werden soll, hier die 0.

    Posted at 09:35 pm by 0xb3fbae33
    Make a comment  

    2006.07.26
    Perl und UTF8

    Irgendwie leidet mein Hirn grade gewaltig. Kein Wunder bei 33,7°C in der Wohnung.

    Ich lasse grade mehrere Lemma-Strecken aus der Datenbank auslesen und portionsweise in Dateien schreiben.
    Dazu dienen zwei einfache Abfragen und eine Schleife.

    In der ersten Abfrage wird mit select count(lemma) from swliste where suchform >= '$anfang' and suchform <= '$ende' and loeschen is false; die Anzahl der betroffenen Lemmata abgefragt.

    Diese Anzahl wird dann durch die Portionsgröße geteilt um die Anzahl der Runden zu bekommen.
    Dann läuft eine Schleife durch und fragt die Lemmata ab, dazu wird mit LIMIT und OFFSET immer schön weitergetrippelt: SELECT lemma,oid,woerterbuecher from swliste where suchform >= '$anfang' and suchform <= '$ende' and loeschen is false order by suchform limit $lim offset $off;

    $lim ist die Portionsgröße und $off das Offset, also $lim mal Runde. Eigentlich ganz simpel und funktioniert soweit ganz gut.

    Die Dateinamen werden nach dem Muster Rundennummer-erstesLemma-letztesLemma.xml gebildet.
    Da es mit UTF8 in Dateinamen auf NetBSD und den Windows-Kisten Probleme gab, lasse ich den Dateinamen transliterieren.

    Und zwar mit einem stupiden Filter, der die kyrillischen Buchstaben in lateinische umwandelt.


    for ( $i=0; $i$result=~s/А/A/gi;
    $result=~s/Б/B/gi;
    $result=~s/В/V/gi;
    $result=~s/Г/G/gi;
    $result=~s/Д/D/gi;
    $result=~s/Е/E/gi;
    $result=~s/Ж/H/gi;
    $result=~s/З/Z/gi;
    $result=~s/И/I/gi;
    $result=~s/Й/J/gi;
    $result=~s/К/K/gi;
    $result=~s/Л/L/gi;
    $result=~s/М/M/gi;
    $result=~s/Н/N/gi;
    $result=~s/О/O/gi;
    $result=~s/П/P/gi;
    $result=~s/Р/R/gi;
    $result=~s/С/S/gi;
    $result=~s/Т/T/gi;
    $result=~s/У/U/gi;
    $result=~s/Ф/F/gi;
    $result=~s/Х/X/gi;
    $result=~s/Ц/C/gi;
    $result=~s/Ч/Q/gi;
    $result=~s/Ш/W/gi;
    $result=~s/Щ//gi;
    $result=~s/Ъ//gi;
    $result=~s/Ы/Y/gi;
    $result=~s/Ь//gi;
    $result=~s/Э/A/gi;
    $result=~s/Ю/U/gi;
    $result=~s/Я/O/gi;
    $result=~s/а/a/gi;
    $result=~s/б/b/gi;
    $result=~s/в/v/gi;
    $result=~s/г/g/gi;
    $result=~s/д/d/gi;
    $result=~s/е/e/gi;
    $result=~s/ж/h/gi;
    $result=~s/з/z/gi;
    $result=~s/и/i/gi;
    $result=~s/й/j/gi;
    $result=~s/к/k/gi;
    $result=~s/л/l/gi;
    $result=~s/м/m/gi;
    $result=~s/н/n/gi;
    $result=~s/о/o/gi;
    $result=~s/п/p/gi;
    $result=~s/р/r/gi;
    $result=~s/с/s/gi;
    $result=~s/т/t/gi;
    $result=~s/у/u/gi;
    $result=~s/ф/f/gi;
    $result=~s/х/x/gi;
    $result=~s/ц/c/gi;
    $result=~s/ч/q/gi;
    $result=~s/ш/w/gi;
    $result=~s/щ//gi;
    $result=~s/ъ/ss/gi;
    $result=~s/ы/y/gi;
    $result=~s/ь/+/gi;
    $result=~s/э/a/gi;
    $result=~s/ю/o/gi;
    $result=~s/я//gi;
    }



    Wenn ich das aber in ein Funktion oder eine Modul packe, funktioniert es nicht mehr, schon die Übergabe des Strings scheint zu scheitern. Ein print $_; gibt nichts aus. Rumgefummel mit use utf8; oder use encode; Encode::_utf8_on(); hat auch nicht geholfen. Nur wenn ich den Filter direkt in der Datei laufen lasse, funktioniert es.

    Komisch.

    Posted at 08:34 pm by 0xb3fbae33
    Make a comment  

    2006.07.18
    UTF8 und russisch

    Inzwischen muss ich Teile einer Datenbank zum Russisch-Wörterbuch in RTF-Dateien zerlegen. Neben der Sortiernummer soll auch das erste und letzte Lemma im Dateinamen stehen - natürlich in kyrillisch. Inzwischen kann sogar NetBSD die Dateinamen korrekt anzeigen, zumindest im uxterm mit UTF-8 Unterstützung:

    Das normale xterm mit ls scheitert kläglich:


    Ein uxterm mit gls und ls -w funktioniert aber :-)



    До свидания, товарищ!

    Posted at 01:30 am by 0xb3fbae33
    Make a comment  

    2006.07.16
    Bildergalerien aufbereiten

    Wenn ich mal wieder auf Fototour war, möchte ich natürlich auch die Bilder ins Netz stellen. Dazu müssen sie aufbereitet werden, da erledigen zwei Perl-Skripte und ein paar Shellskripte.



    ## Bilder rotieren lassen, benötigt pkgsrc/graphics/jhead, wertet automatisch EXIF-Header aus

    for i in *.JPG; do jhead -autorot $i; done


    ## Bilder signieren lassen, Unsignierten löschen

    picsig.pl sig.gif
    rm IMG*



    ## - Kommentar (EXIF) entfernen
    ## - Urheberrechtsvermerk einsetzen
    ## - Umbenennen mit sed, temporäre Bilder löschen

    for i in *.JPG
    do
    convert -strip $i 2$i
    convert -comment "(C) Stefan Schumacher, www.net-tex.de" 2$i 3$i
    mv 3$i `echo $i|sed s/sIMG/gommern-060331/`
    rm $i 2$i
    done


    ## Webalbum erstellen, es werden dazu Vorschaubilder erstellt, eine Index-Seite und eine HTML-Seite für jedes Bild. Die Vorschaubilder sind 150px breit und in der Tabelle werden 4 Stk nebeneinander gesetzt,

    ./album.pl 150 4


    Die beiden Perlskripte gibt es auf meiner Webseite:

    http://net-tex.dnsalias.org/~stefan/nt/code/#signpic
    http://net-tex.dnsalias.org/~stefan/nt/code/album.pl.txt


    Ein Beispiel-Album aus Magdeburg von heute gibt es unter http://net-tex.dnsalias.org/~stefan/gallery/md-060716/. Außerdem wird hier geklärt was BSD eigentlich heißt ;-)

    Posted at 10:31 pm by 0xb3fbae33
    Make a comment  

    DVDs per Cronjob brennen

    Ein alter Pentium 2 mit 200MHz wurde mit einer großen Festplatte und einem neuen DVD-Brenner ausgestattet. Der Rechner steht in einem Büro, so das von den Mitarbeitern werktäglich die DVDs gewechselt werden können.

    Ursprünglich wollte ich ja eigentlich Streamer einsetzen, aber die Kosten sind dort bei neuen Streamern und entsprechenden für 4 Wochenzyklen und 50 Montagsarchiven ungefähr zehnmal höher als für DVDs. Da wir z. Zt. unkomprimiert erst 2,5GB haben, reicht ein DVD-Brenner auch aus. Zumal der benötigte Archivzyklus nicht über zwei Wochen liegen wird.

    Wie dem auch sei, der Hauptserver synced seine Datenbestände per rsync regelmäßig auf den P2, so das die Daten dort live vorliegen. Außerdem wird nächtlich noch auf dem Hauptserver ein dump erzeugt, der mit mkisofs in eine ISO-Datei aufbereitet wird. Diese ISO-Datei wird per scp übertragen und per Cron in der Mittagspause auf dem P2 gebrannt. Dazu wird eine Logdatei erstellt, die ins www-Verzeichnis kopiert wird, um so einfach auf Fehler prüfen zu können.

    Leider hatte der der DVD-Brenner Schwierigkeiten zu brennen, da der Vorgang sofort abbrach. Komischerweise funktioniert es, wenn man einfach ein paar Sekunden Pause macht und den Brennvorgang nochmal anwirft. Ich vermute der Brenner ist etwas zu neu für den alten P2 mit ATA33 ;-)


    Hier das Skript:

    #!/bin/sh
    cd /home/backupbot/
    printf '\n\n#####################################################################\n#####################################################################\n\n' >>backuplog
    date >>backuplog
    /usr/pkg/bin/growisofs -dvd-compat -Z /dev/rcd1d -R -J iso 2>>backuplog
    /bin/sleep 15
    /usr/pkg/bin/growisofs -dvd-compat -Z /dev/rcd1d -R -J iso 2>>backuplog
    cp backuplog /home/www/
    /bin/mv /home/backupbot/iso/*.gz /home/backupbot/iso/letzte_sicherung.gz
    /bin/rm /home/backupbot/iso/*

    Posted at 06:48 pm by 0xb3fbae33
    Make a comment  

    2006.07.06
    PostgreSQL-Vortrag


    Posted at 11:04 am by 0xb3fbae33
    Make a comment  

    2006.06.11
    PostgreSQL: RULES rulez! - oder auch nicht ;-)

    Für eine Datenbank existiert eine Tabelle in der sich bereits ca. 300.000 Primärschlüssel befinden. Die Bearbeiter der Datenbank haben in einer GUI die Möglichkeit in bestimmten Grenzen Primärschlüssel anzeigen zu lassen und entsprechend den restlichen Datensatz auszufüllen oder einen komplett neuen Datensatz (inkl. neuem Primärschlüssel) anzulegen.

    Dabei kommt es manchmal vor das ein neuer Primärschlüssel angelegt werden soll, der schon existiert und dann entsprechend mit duplicate key violates unique constraint abgewiesen wird. Problematisch ist dabei, daß die angegebenen Werte zum Datensatz verfallen und neu eingetragen werden sollen.

    Damit dies nicht passiert, möchte ich nun die INSERT-Anfrage in ein UPDATE umbiegen.
    Und zwar so:

    test=# create table bar (id int, text text) with oids;
    CREATE TABLE
    test=# INSERT INTO bar VALUES (1,'a');
    INSERT 16473 1
    test=# INSERT INTO bar VALUES (2,'b');
    INSERT 16474 1
    test=# INSERT INTO bar VALUES (3,'c');
    INSERT 16475 1
    test=# SELECT * from bar ;
    id | text
    ----+------
    1 | a
    2 | b
    3 | c
    (3 rows)
    test=# INSERT INTO bar VALUES (1,'!');
    ERROR: duplicate key violates unique constraint "bar_pkey"


    Statt der letzten Fehlermeldung soll dann ein UPDATE ausgeführt werden, so das in 1.text = "a !" steht.


    Nichts leichter als das, dachte ich mir, es gibt ja RULES.
    Also, Handbuch gegriffen, RULES studiert und loskonstruiert, heraus kam:

    test=# CREATE RULE "insup"
    AS ON INSERT TO bar
    WHERE new.id IN (select id from bar)
    DO INSTEAD (update bar set text=text||' '||new.text where id=new.id);
    CREATE RULE
    test=# INSERT INTO bar VALUES (3,'X');
    INSERT 0 0
    test=# INSERT INTO bar VALUES (3,'Y');
    INSERT 0 0
    test=# SELECT * from bar ;
    id | text
    ----+-------
    1 | a
    2 | b
    3 | c X Y
    (3 rows)


    Funktioniert ja wunderbar mit dem UPDATE. Nur leider gibt es ein Problem:


    test=# INSERT INTO bar VALUES (99,'TEST');
    INSERT 16477 1
    test=# SELECT * from bar ;
    id | text
    ----+-----------
    1 | a
    2 | b
    3 | c X X
    99 | TEST TEST
    (4 rows)

    test=# INSERT INTO bar VALUES (99,'TEST2');
    INSERT 0 0
    test=# SELECT * from bar ;
    id | text
    ----+-----------------
    1 | a
    2 | b
    3 | c X X
    99 | TEST TEST TEST2
    (4 rows)


    So'n Mist, wenn der Schlüssel noch nicht existiert, wird "text" zweimal eingefügt. Das darf natürlich nicht sein.

    Nach ein paar Fragen im IRC bekam ich den Hinweis das RULES mit UPDATE teilweise unter RACE CONDITIONS leiden, so das man damit vorsichtig umgehen sollte. Stattdessen sollte ich lieber eine FUNCTION verwenden.
    Als Pointer bekam ich http://developer.postgresql.org/docs/postgres/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING gereicht.

    Nach ausgiebigem Studium des Werkes erschuf ich eine FUNCTION die tut was ich will :-)
    Und es war sogar schon das passende Bsp. im Handbuch angegeben *g

    CREATE FUNCTION ins_or_up (name int, data text) RETURNS VOID AS
    $$
      BEGIN LOOP
         update bar set text = text || data where id=name;
         if found then
            return; 
         end if;
    
    BEGIN
       INSERT INTO bar (id,text) VALUES (name,data); 
       return; 
    
       EXCEPTION WHEN unique_violation THEN
            -- do nothing 
       END; 
      END LOOP;
    END; 
    $$
    LANGUAGE plpgsql;
    


    Das tut was ich will:


    test=# INSERT INTO bar VALUES (1,'A');
    INSERT 16501 1
    test=# INSERT INTO bar VALUES (2,'B');
    INSERT 16502 1
    test=# INSERT INTO bar VALUES (3,'C');
    INSERT 16503 1
    test=# INSERT INTO bar VALUES (1,'X');
    ERROR: duplicate key violates unique constraint "bar_pkey"
    test=# SELECT * from bar ;
    id | text
    ----+------
    1 | A
    2 | B
    3 | C
    (3 rows)

    test=# SELECT ins_or_up(1,' X');
    ins_or_up
    -----------

    (1 row)

    test=# SELECT ins_or_up(2,' XX'); SELECT * from bar ;
    ins_or_up
    -----------

    (1 row)

    id | text
    ----+------
    3 | C
    1 | A X
    2 | B XX
    (3 rows)
    test=#


    Dann will ich mal die FUNCTION zerlegen:
    CREATE FUNCTION ins_or_up (name int, data text) RETURNS VOID AS
    Erzeuge die FUNCTION ins_or_up, übergebe name als Integer und data als Text, Rückgabewert gibt es nicht.


    $$
    BEGIN LOOP

    Ein kleines Schleifchen

    update bar set text = text || data where id=name;
    Aktualisiere die Tabelle bar, hänge den Text an den Datensatz mit der entsprechenden id an


    if found then return;
    end if;

    Wenn der Datensatz schon existiert, id also gefunden wird. Beende dann die FUNCTION und den IF-Zweig



    BEGIN INSERT INTO bar (id,text) VALUES (name,data);
    return;

    Anderenfalls soll der Satz normal eingefügt werden.


    EXCEPTION WHEN unique_violation THEN
    -- do nothing
    END;

    Sollte der Datensatz schon existieren, tue nichst und beende den Zweig


    END LOOP;
    END;
    $$

    beende die Schleife und die FUNCTION

    LANGUAGE plpgsql;
    Das ganze in PL/pgSQL.

    Posted at 09:30 pm by 0xb3fbae33
    Make a comment  

    2006.06.02
    Google Trends

    Eben flattert grade eine eMail über die PostgreSQL-Mailinglisten, die einen Link auf Google Trends enthält.

    Google Trends wertet die Suchanfragen statistisch aus, es wird ein Graph angezeigt, der die Häufigkeit illustriert und. ggf werden Nachrichten-Schlagzeilen gezeigt (bspw. wenn man nach "Michael Schumacher" googelt).

    Zusätzlich werden die Top10 der Städte, Regionen und Sprachen angezeigt.

    Dabei habe ich doch spaßeshalber mal ein paar lustige Suchbegriffe (naja, in der 7.Klasse waren sie lustig ;-) eingefüttert und erstaunliches (oder auch nicht, je nach dem ob man Realist ist oder den Medien treudoof hinterherdackelt ;-)


    Suchbegriff: "download porn" (http://www.google.de/trends?q=download+porn&ctab=0&geo=all&date=all)



    1. Delhi India
    2. Jakarta Indonesia
    3. Zagreb Hrvatska
    4. Chennai India
    5. Mumbai India
    6. Perth Australia
    7. Birmingham United Kingdom
    8. Melbourne Australia
    9. Manchester United Kingdom
    10. Sydney Australia

    Da wundert man sich schon über Jakarta, aber es wird noch besser:

    1. Indonesia
    2. Hrvatska
    3. India
    4. South Africa
    5. Romania
    6. Malaysia
    7. Norway
    8. New Zealand
    9. Australia
    10. Turkey

    Indonesien, das nach Bevölkerung größte muslimische Land der Welt steht in dieser pikanten Suche auf Platz 1. Malaysia und Turkey sind ja auch nicht grade als Verfechter bürgerlicher Freiheiten bekannt.

    Auch interessant ist die Suche nach dem Stichwort schelchthin:
    Sex (http://www.google.com/trends?q=sex&ctab=0&geo=all&date=all)



    Regionen:

    1. Pakistan
    2. Egypt
    3. Viet Nam
    4. Iran
    5. India
    6. Morocco
    7. Saudi Arabia
    8. Turkey
    9. Philippines
    10. Poland

    Bruhaha, bis auf Vietnam und Polen haben alle Länder Moslems, teilweise sogar nur Moslems (Saudi Arabien), in ihrer Bevölkerung. Und Vietnam ist immer noch ein kommunistisches Regime mit den alten verknöcherten Moralvorstellungen die wir nur zu gut kennen. In Polen ist die katholische Kirche und religiöse Rechte mit ihrem Unfug stark vertreten.
    In Vietnam gibt es auch viele Katholiken, die Religion wurde von den Franzosen eingeschleppt und durchgeprügelt.

    Was sagen uns die Statistiken nun?

    Naja, nicht wirklich viel, aber man kann darüber spekulieren warum gerade die Länder, in denen etwas tabuisiert ist, danach suchen. Sicherlich ist das Verbotene am interessantesten und da Sex nunmal das natürlichste der Welt ist, kann man es nicht tabuisieren, da helfen auch keine Verbote.

    Bleibt abzuwarten was das für die Gesellschaft bedeutet. Ich glaube wir werden in mittlerer bis ferner Zukunft den Zusammenbruch weiterer Regime erleben, zumindest solange diese ihre Untertanen kulturell und sozial unterdrücken werden. Die Menschen wollen nun mal frei sein und werden alles daransetzen es zu sein.

    Wenn die Regime es nichtmal gebacken kriegen mit der Macht des Koran oder der Bibel Sex und Pornographie aus den Köpfen der Menschen (oder Männer?) zu verbannen, dann können sie sich auf Dauer auch einfach nicht halten.


    Vielleicht sollten wir einfach ein paar schöne Interracial Videos über den islamischen Staaten abwerfen ;-)

    Posted at 11:42 pm by 0xb3fbae33
    Make a comment  

    Next Page