Tag Archives: programming

Password generator dutch

Generates easy to remember passwords, using 3 words and a number

EXAMPLES:
TotaalHeuvelSorry25
ZorgenEnkeleDubbel42
TweedeMaalCadeau18
BlauwMamaZeep99
NetFoutFles88
KeusZijDaar18
AanbodVuurKaart98
ReddenGelijkHaan68
WakkerLatenHaten47

Words in list below are generated on lenght and SFW.
For getting a list of words a certain lenght use:

# Words between 4 and 7 characters
grep -o -w '\w\{4,7\}' /usr/share/dict/dutch
# Didn't use wordlist above due to many not easyly to remember words.
#!/bin/bash
me=`basename "$0"`
cat $me | sed '1,/^WOORDEN$/d' | shuf | head -3 | while read ; do echo -n $REPLY ;done ; echo $(shuf -i 10-99 -n 1)
exit 0
WOORDEN
Aan
Aanbod
Aanval
Aap
Aarde
Aardig
Acht
Achter
Actief
Ademen
Afname
Afval
Alleen
Alles
Als
Altijd
Ander
Andere
Anders
Angst
Appel
Arm
Auto
Avond
Baan
Baby
Bad
Bal
Bang
Bank
Basis
Bed
Been
Beer
Beest
Beetje
Begin
Begrip
Beide
Beker
Bel
Bellen
Berg
Beroep
Best
Beter
Bezoek
Bieden
Bij
Bijna
Bijten
Binnen
Blad
Blauw
Blazen
Blij
Bloed
Bloem
Bodem
Boek
Boete
Boom
Boon
Boord
Boos
Bord
Bos
Bot
Bouwen
Boven
Breed
Breken
Brief
Broer
Broek
Brood
Brug
Bruin
Bui
Buiten
Bureau
Buren
Bus
Cadeau
Cirkel
Cool
Daar
Daarom
Dag
Dak
Dan
Dansen
Dapper
Dat
Deel
Deken
Deksel
Delen
Derde
Deze
Dienen
Diep
Dier
Dik
Ding
Dit
Doen
Dom
Donker
Dood
Door
Doos
Dorp
Draad
Dragen
Drie
Drogen
Dromen
Droog
Druk
Dubbel
Dun
Dus
Duur
Duwen
Echt
Een
Één
Eend
Eerste
Eeuw
Effect
Eigen
Eiland
Einde
Eis
Elk
Enkele
Erg
Eten
Even
Examen
Falen
Feest
Feit
Fel
Fijn
Film
Fit
Fles
Foto
Fout
Fris
Fruit
Gaan
Gat
Gebied
Gedrag
Geel
Geen
Geit
Geld
Gelijk
Geloof
Geluid
Geluk
Gemak
Gemeen
Genoeg
Genot
Geur
Gevaar
Geven
Gevolg
Gewoon
Gezond
Gif
Glad
Glas
God
Goed
Goud
Graf
Grap
Gras
Grens
Grijs
Groen
Groep
Grof
Grond
Groot
Haan
Haar
Haast
Hal
Halen
Half
Hallo
Hamer
Hand
Hard
Hart
Haten
Hebben
Heel
Heet
Helder
Helft
Help
Hem
Hemel
Hen
Herfst
Hert
Het
Heuvel
Hier
Hij
Hobby
Hoe
Hoed
Hoek
Hoewel
Hond
Honger
Hoofd
Hoog
Hoogte
Hoop
Horen
Hotel
Houden
Huilen
Huis
Hun
Huren
Hut
Huur
Idee
Ieder
Iemand
Iets
Ijs
Ijzer
Jaar
Jagen
Jas
Jij
Jong
Jongen
Jouw
Jullie
Kaars
Kaart
Kaas
Kamer
Kans
Kant
Kap
Kast
Kat
Kennen
Kennis
Keuken
Keus
Kiezen
Kijken
Kind
Kip
Kist
Klaar
Klas
Klasse
Kleden
Klein
Kleren
Kleur
Klok
Klopt
Knie
Koers
Koffer
Koffie
Kok
Koken
Kom
Komen
Koning
Koorts
Kop
Kopen
Kort
Kost
Kosten
Koud
Kraam
Kracht
Krant
Kruis
Kuil
Kunnen
Kunst
Laag
Laat
Laatst
Lach
Lachen
Ladder
Laken
Lamp
Land
Lang
Langs
Laten
Leeg
Leeuw
Leger
Leiden
Lenen
Lengte
Lepel
Leren
Les
Leuk
Leven
Lezen
Licht
Liefde
Liegen
Liggen
Lijk
Lijken
Links
Lip
List
Lomp
Lood
Lopen
Los
Lot
Lucht
Lui
Lunch
Maag
Maal
Maan
Maand
Maar
Maat
Maken
Mama
Man
Mand
Manier
Map
Markt
Meel
Meer
Meest
Meisje
Melk
Meneer
Mensen
Mes
Met
Meubel
Middel
Midden
Mij
Mijn
Min
Minder
Minuut
Mis
Missen
Mits
Model
Modern
Moeder
Moeten
Mogen
Moment
Mond
Mooi
Moord
Morgen
Munt
Muziek
Naald
Naam
Naar
Naast
Nacht
Nat
Natuur
Nee
Neer
Negen
Nek
Nemen
Net
Netjes
Neus
Niet
Niets
Nieuw
Nieuws
Nobel
Noch
Nodig
Noemen
Nog
Nood
Nooit
Noord
Noot
Nul
Nummer
Object
Oceaan
Offer
Olie
Oma
Onder
Oneven
Ons
Onze
Oog
Ooit
Ook
Oom
Oor
Oorlog
Oost
Opa
Opeens
Open
Oranje
Orde
Oud
Ouder
Over
Overal
Paar
Paard
Pad
Pagina
Pan
Papa
Papier
Park
Pas
Pen
Peper
Per
Piano
Pijn
Plaat
Plaats
Plank
Plant
Plat
Plein
Plus
Poes
Poort
Praten
Prijs
Prins
Privé
Punt
Raak
Raam
Radio
Raken
Recht
Rechts
Redden
Reeds
Regen
Reiken
Reizen
Rennen
Rest
Rijk
Rijst
Rijzen
Ring
Rok
Rond
Rood
Rook
Rots
Roze
Rubber
Ruiken
Ruimte
Samen
Sap
Schaap
Schaar
Scherp
Schip
School
Schoon
Sex
Simpel
Sinds
Slapen
Slecht
Slim
Slot
Smaak
Smal
Sneeuw
Snel
Soep
Sok
Soms
Soort
Sorry
Spel
Spelen
Sport
Staal
Stad
Stap
Start
Steen
Stelen
Stem
Ster
Sterk
Steun
Stil
Stilte
Stoel
Stof
Stom
Stop
Storm
Straat
Studie
Stuk
Succes
Suiker
Taal
Taart
Tafel
Tak
Tand
Tante
Tas
Taxi
Team
Teen
Tegen
Teken
Tellen
Tennis
Terug
Test
Thee
Thuis
Tien
Tijd
Titel
Toen
Totaal
Traan
Tram
Trein
Trui
Tuin
Tussen
Tweede
Uit
Uur
Vaak
Vader
Vak
Vallen
Vals
Van
Vangen
Varken
Vast
Veel
Veer
Veilig
Ver
Verder
Verf
Vers
Vet
Vier
Vies
Vijand
Vijf
Vijver
Vinden
Vinger
Vis
Vlag
Vlees
Vlieg
Vloer
Voeden
Voelen
Voet
Vogel
Vol
Voor
Vork
Vorm
Vos
Vouwen
Vraag
Vragen
Vrede
Vreemd
Vriend
Vrij
Vroeg
Vrouw
Vullen
Vuur
Waar
Waarom
Wakker
Want
Wapen
Warm
Wassen
Wat
Water
Week
Weer
Weg
Welke
Welkom
Wens
Wereld
Werk
West
Wie
Wiel
Wij
Wijn
Wijs
Wild
Willen
Wind
Winkel
Winnen
Winter
Wissen
Wit
Wolf
Wolk
Wonder
Woord
Woud
Wreed
Zaak
Zacht
Zak
Zand
Zee
Zeep
Zeer
Zeggen
Zeil
Zeker
Zelfde
Zes
Zetten
Zeven
Ziek
Ziel
Zien
Zij
Zijn
Zilver
Zingen
Zinken
Zitten
Zoals
Zoeken
Zoet
Zomer
Zon
Zonder
Zonnig
Zoon
Zorg
Zorgen
Zou
Zout
Zuid
Zulke
Zullen
Zus
Zwaar
Zwak

Kanban effectiveness graph generator

While attending a Kanban workshop, i needed to keep myself awake.
I’d hardly slept that night.

So i wrote something useful using PHP JPgraph and Sqlite, while attending the workshop.
It shows the effectiveness of the team using kanban.

index.php

<html>
<head>
</head>
<body>
<?PHP
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
include ("insert.php");
}
include ("getlast.php");
?>
<img src="graph.php"><P>
<form action="" method="POST">
Tickets from board: <input size="4" name="klaar" value="<?PHP print $klaar; ?>"/> <input type="checkbox" name="useklaar" value="useklaar" checked> Use fromboard <P>
    <table>
        <tr>
            <td>inlane:</td><td><input size="4" name="inlane" value="<?PHP print $inlanelast; ?>"/></td>
            <td>analyse:</td><td><input size="4" name="analyze" value="<?PHP print $analyzelast; ?>" /></td>
            <td>implement:</td><td><input size="4" name="implement" value="<?PHP print $implementlast; ?>" /></td>
            <td>documentation:</td><td><input size="4" name="documentation" value="<?PHP print $documentationlast; ?>"/></td>
            <td>peer:</td><td><input size="4" name="peer" value="<?PHP print $peerlast; ?>"/></td>
            <td>test:</td><td><input size="4" name="test" value="<?PHP print $testlast; ?>"/></td>
            <td>done:</td><td><input size="4"  name="done" value="<?PHP print $donelast; ?>"/></td>
        </tr>
    </table>
            <input type="submit" value="Submit"/>
</form>

</body>
</html>

graph.php

<?php
include ("jpgraph/jpgraph.php");
include ("jpgraph/jpgraph_line.php");
$db = new SQLite3('mysqlitedb.db');
$index=0;
$results = $db->query('SELECT inlane FROM ENTRIES');
while ($row = $results->fetchArray()) {
$inlane[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT analyze FROM ENTRIES');
while ($row = $results->fetchArray()) {
$analyze[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT implement FROM ENTRIES');
while ($row = $results->fetchArray()) {
$implement[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT documentation FROM ENTRIES');
while ($row = $results->fetchArray()) {
$documentation[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT peer FROM ENTRIES');
while ($row = $results->fetchArray()) {
$peer[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT test FROM ENTRIES');
while ($row = $results->fetchArray()) {
$test[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT done FROM ENTRIES');
while ($row = $results->fetchArray()) {
$done[$index] = $row[0];
     $index++;
}
//$datay = array(1,2,4);
$datay1 = array(2,4,4,6,7,4);
$datay2 = array(2,3,4);
$graph = new Graph(600,600,"auto");
$graph->img->SetMargin(40,40,40,40);	
$graph->img->SetAntiAliasing();
$graph->SetScale("textlin");
$graph->SetShadow();
$graph->title->Set("Kanban grapher - A pruts by FASH");
$graph->title->SetFont(FF_FONT1,FS_BOLD);

// Add 10% grace to top and bottom of plot
$graph->yscale->SetGrace(10,10);

//ID|inlane|implement|documentation|peer|test|done

$p1 = new LinePlot($inlane);
$p1->mark->SetType(MARK_FILLEDCIRCLE);
$p1->mark->SetFillColor("red");
$p1->mark->SetWidth(4);
$p1->SetColor("red");
$p1->SetCenter();
$graph->Add($p1);

$p2 = new LinePlot($analyze);
$p2->mark->SetType(MARK_FILLEDCIRCLE);
$p2->mark->SetFillColor("orange");
$p2->mark->SetWidth(4);
$p2->SetColor("orange");
$p2->SetCenter();
$graph->Add($p2);

$p3 = new LinePlot($implement);
$p3->mark->SetType(MARK_FILLEDCIRCLE);
$p3->mark->SetFillColor("yellow");
$p3->mark->SetWidth(4);
$p3->SetColor("yellow");
$p3->SetCenter();
$graph->Add($p3);

$p4 = new LinePlot($documentation);
$p4->mark->SetType(MARK_FILLEDCIRCLE);
$p4->mark->SetFillColor("green");
$p4->mark->SetWidth(4);
$p4->SetColor("green");
$p4->SetCenter();
$graph->Add($p4);

$p5 = new LinePlot($peer);
$p5->mark->SetType(MARK_FILLEDCIRCLE);
$p5->mark->SetFillColor("blue");
$p5->mark->SetWidth(4);
$p5->SetColor("blue");
$p5->SetCenter();
$graph->Add($p5);

$p6 = new LinePlot($test);
$p6->mark->SetType(MARK_FILLEDCIRCLE);
$p6->mark->SetFillColor("purple");
$p6->mark->SetWidth(4);
$p6->SetColor("purple");
$p6->SetCenter();
$graph->Add($p6);

$p7 = new LinePlot($done);
$p7->mark->SetType(MARK_FILLEDCIRCLE);
$p7->mark->SetFillColor("black");
$p7->mark->SetWidth(4);
$p7->SetColor("black");
$p7->SetCenter();
$graph->Add($p7);

$graph->legend->SetLineSpacing(5);

$p1->SetLegend ("inlane"); 
$p2->SetLegend ("analyse"); 
$p3->SetLegend ("implementation"); 
$p4->SetLegend ("documentation"); 
$p5->SetLegend ("peer"); 
$p6->SetLegend ("test"); 
$p7->SetLegend ("done"); 
$graph ->legend->Pos( 0.09,0.09,"left" ,"top");

$graph->Stroke();
?>

insert.php

<?php
$db = new SQLite3('mysqlitedb.db');
//ID|inlane|implement|documentation|peer|test|done
$klaar=$_POST["klaar"];
$inlane=$_POST["inlane"];
$analyze=$_POST["analyze"];
$implement=$_POST["implement"];
$documentation=$_POST["documentation"];
$peer=$_POST["peer"];
$test=$_POST["test"];
$done=$_POST["done"];

$db->exec("DELETE FROM BOARD");
$db->exec("INSERT INTO BOARD  VALUES ($klaar,$inlane,$analyze,$implement,$documentation,$peer,$test,$done)");

$done=$_POST["done"]+$klaar;
$test=$_POST["test"]+$done;
$peer=$_POST["peer"]+$test;
$documentation=$_POST["documentation"]+$peer;
$implement=$_POST["implement"]+$documentation;
$analyze=$_POST["analyze"]+$implement;
$inlane=$_POST["inlane"]+$analyze;

$db->exec("INSERT INTO ENTRIES  VALUES (NULL,$inlane,$analyze,$implement,$documentation,$peer,$test,$done)");
?>
getlast.php
<?php
$db = new SQLite3('mysqlitedb.db');

$results = $db->query('SELECT inlane FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$inlanelast = $row[0];

$results = $db->query('SELECT implement FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$implementlast = $row[0];

$results = $db->query('SELECT documentation FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$documentationlast = $row[0];

$results = $db->query('SELECT peer FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$peerlast = $row[0];

$results = $db->query('SELECT test FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$testlast = $row[0];

$results = $db->query('SELECT done FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$donelast = $row[0];

$results = $db->query('SELECT vanbord FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$klaar = $row[0];

$results = $db->query('SELECT analyze FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$analyzelast = $row[0];
?>

Web controller for Acdsee

UPDATE: 2023 It’s still working

I made a webcontroller for viewing images on a big TV.

Using a Acdsee instance with MCE Controller installed and a webserver.

https://tig.github.io/mcec/example_commands.html

Rate the picture 1-5, clear rating, slideshow start, escape, open/close image, zoom-in out and zoom-reset. Previous and next image fullscreen and delete/yes

Some used defined keys (see php file)

 if ($cmd=="I"){ $put="chars:+"; };
 if ($cmd=="O"){ $put="chars:-"; };
 if ($cmd=="R"){ $put="chars:*"; };
 if ($cmd=="Y"){ $put="chars:y"; };
 if ($cmd=="F"){ $put="chars:f"; };
 if ($cmd=="D"){ $put="delete"; };
 if ($cmd=="N"){ $put="right"; };
 if ($cmd=="P"){ $put="left"; };
 if ($cmd=="ENTER"){ $put="enter"; };
 if ($cmd=="ESC"){ $put="escape"; };

PHP Script for the buttons and creating the TCP packets for MCE.

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<?php
  $ip           = "remoteserver";
  $port         = "5150";

if (empty($put)) $put = "";
if (empty($line)) $line = "";
$cmd=$_POST['cmd'];
 if ($cmd=="I"){ $put="chars:+"; };
 if ($cmd=="O"){ $put="chars:-"; };
 if ($cmd=="R"){ $put="chars:*"; };
 if ($cmd=="Y"){ $put="chars:y"; };
 if ($cmd=="F"){ $put="chars:f"; };
 if ($cmd=="D"){ $put="delete"; };
 if ($cmd=="N"){ $put="right"; };
 if ($cmd=="P"){ $put="left"; };
 if ($cmd=="ENTER"){ $put="enter"; };
 if ($cmd=="ESC"){ $put="escape"; };
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
    $task = send_cmd("$put", $fp);

 if ($cmd=="1" || $cmd=="2" || $cmd=="3" || $cmd=="4" || $cmd=="5" || $cmd=="0"){
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftdown:ctrl", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("$cmd", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftup:ctrl", $fp);
  fclose($fp);
        };
if ($cmd=="S") {
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftdown:alt", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("$cmd", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftup:alt", $fp);
  fclose($fp);
        };

 if ($cmd=="fnietF"){
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftdown:shift", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftdown:ctrl", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("$cmd", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftup:ctrl", $fp);
  fclose($fp);
  $fp = stream_socket_client("tcp://".$ip.":".$port, $errno, $errstr, 30);
        send_cmd("shiftup:shift", $fp);
  fclose($fp);
        };



//}
  echo "<html><head><title></title></head>";
  echo "<body><center><H1>";
$callself=$_SERVER['PHP_SELF'];
echo "<div data-role=\"controlgroup\" data-type=\"horizontal\">";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"1\"><input type=\"submit\" value=\"1\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"2\"><input type=\"submit\" value=\"2\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"3\"><input type=\"submit\" value=\"3\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"4\"><input type=\"submit\" value=\"4\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"5\"><input type=\"submit\" value=\"5\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"0\"><input type=\"submit\" value=\"Rate Clear\" /></form>\n";
echo "</div>";

echo "<div data-role=\"controlgroup\" data-type=\"horizontal\">";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"S\"><input type=\"submit\" value=\"SLIDESHOW\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"ESC\"><input type=\"submit\" value=\"ESC\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"ENTER\"><input type=\"submit\" value=\"OPEN/CLOSE\" /></form>\n";
  fclose($fp);
echo "</div>";

echo "<div data-role=\"controlgroup\" data-type=\"horizontal\">";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"I\"><input type=\"submit\" value=\"ZOOMIN\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"R\"><input type=\"submit\" value=\"ZOOMRESET\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"O\"><input type=\"submit\" value=\"ZOOMOUT\" /></form>\n";
echo "</div>";

echo "<div data-role=\"controlgroup\" data-type=\"horizontal\">";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"P\"><input type=\"submit\" value=\"PREV\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"D\"><input type=\"submit\" value=\"DEL\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"Y\"><input type=\"submit\" value=\"Y\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"F\"><input type=\"submit\" value=\"FULL\" /></form>\n";
    echo "<form data-transition=\"none\" style=\"display:inline;\" name=\"input\" action=\"$callself\" method=\"post\"><input type=\"hidden\" name=\"cmd\" value=\"N\"><input type=\"submit\" value=\"NEXT\" /></form>\n";
echo "</div>";
  echo "</body></html>";
  function send_cmd($cmd, $fp){
    fwrite($fp, $cmd);
    fwrite($fp, "\n");
        return;
  }
?>

Using Graphviz and dot language to plot friends and family

I’ve been using the dotty language for many things, this is a who is who displayer.
iptables rules displayer, open ports, gluster brinks/nodes. netstat ports.,
Wil post more about this later


installing
apt-get install graphviz

View it on a website using mojozoom javascipt

demo : https://media.henriaanstoot.nl/websites/dotviewer/index.html

dot file example (changed names to protect the innocent)

           digraph G {
                size="960,960"
                graph [fontsize=16];
                node  [fontsize=16];
                ericewc [shape=diamond]
                notoasat [shape=diamond]
                rwke [shape=diamond]
                prtsu [shape=diamond]
                wkmre [shape=diamond]
                hsocol [shape=diamond]
                stm [shape=diamond]
                scoisenr [shape=diamond]
                lpetg [shape=diamond]
                ptoi [shape=diamond]
                nrnag -> rean;
                rean -> grrdea;
                rean -> kmoina;
                nrnag -> aabrrba;
                aabrrba -> edide;
                aabrrba -> taamra;
                wkmre -> renei;
                renei -> ilem;
                cpb -> mttne;
                cpb -> mhyme;
                ghnhlaid -> hsanvk;
                hsanvk -> mray;
                ghnhlaid -> erbnete -> kene;
                erbnete -> ebnno;
                erbnete -> hsan;
                erbnete -> anek;
                nehri -> hetctur;
                nlicoe -> hetctur;
                ueoqnim -> hetctur;
                hetctur -> aisovwkrs;
                aisovwkrs -> amnroa;
                aisovwkrs -> gioud;
                aisovwkrs -> aulra;
                rwke -> lemtcu;
                lemtcu -> rhary;
                lemtcu -> gmc;
                prtsu -> ico;
                prtsu -> hloaa;
                nehri -> prtsu;
           }

Making the graphics

dot -Tsvg -obig.svg goed.dot
#gs -q -dNOPAUSE -dBATCH -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=png16m -sOutputFile=big.png big.ps
convert big.svg big.png
convert -resize 800x800 big.png bigsmall.png

Onkyo web control hack

Back in 2009 i’ve posted my web controller for Onkyo in a forum.

Several people build on that source and made android/iphones app using this as example.

It uses pfsockopen with raw packets in php.
Spend a lot of work reverse engineering the tcp headers to be send.
Another fun trick was re-using a trick i’ve used for my ipcam controller and dartabase. (Dart game application)

Below a PDF with first page of forum

I’ve made a alteration in my logitechmediaserver (squeezebox server) which embedded a onkyo volume control part in the gui.

Volume Onkyo in LMS

Part of code

<?php
// :colorscheme elflord
// Henri Aanstoot
// Onkyo Reciever Web Interface 2009
// Version 0.6b - 23 Oct 2009
// EDIT THIS
$receiveripnumber="your.onkyo.ip.here";
$receiverlistenport="60128";
// maximum to set volume (0-100) 
// !! some have 64 max????
$volumemax=60;
// (i had to enable this port by going onto the menu's on my Onkyo
// ---- NO EDITING BELOW THIS LINE

// trick browser into staying on same page
$ibrowser = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
if ($ibrowser == false) {
header("HTTP/1.0 204 No Response");
}
// test write to file
//$fp=fopen("test.txt", "wb");
// write to Receiver 
$fp = pfsockopen($receiveripnumber, $receiverlistenport, $errno, $errstr, 30);
//get command from post form
$command=$_POST['cmd'];
//get volume if cmd is numeric
if(is_numeric($command)) 
 {
if ($command > $volumemax) { $command=$volumemax; }
echo $command;
  $vol=str_pad(dechex($command), 2, '0', STR_PAD_LEFT);
  $command="!1MVL$vol";
 }
// Calculate header and datapacket lengths
$length=strlen($command); 
$length=$length+1;
$total=$length+16;
$code=chr($length);
// total eiscp packet to send 
$line="ISCP\x00\x00\x00\x10\x00\x00\x00$code\x01\x00\x00\x00".$command."\x0D";
#fputs($fp,$line,$total);
// write
fwrite($fp, $line);
// rest status part
//    while (!feof($fp)) {
//        echo fgets($fp, 128);
//    } 

fclose($fp);

if ($ibrowser == true) {
print "<html>
<head>
<title>Sending Command...</title>`
<meta http-equiv=\"refresh\" content=\"0;url=index.php\">
</head>
<body></body>
</html>";
}

?>

List of command’s

header,Power
!1PWR00,Poweroff
!1PWR01,Poweron
header,Muting
!1AMT00,Audio muting off
!1AMT01,Audio muting on
!1AMTQSTN,Audio muting stat
header, Speaker A/B (Main/Front?)
!1SPA00,Speaker A Off
!1SPA01,Speaker A On
!1SPB00,Speaker B Off
!1SPB01,Speaker B On
header,Sound modus
!1LMD00,STEREO
!1LMD01,DIRECT 
!1LMD02,SURROUND
!1LMD03,FILM
!1LMD04,THX
!1LMD05,ACTION
!1LMD06,MUSICAL
!1LMD07,MONO MOVIE
!1LMD08,ORCHESTRA
!1LMD09,UNPLUGGED
!1LMD0A,STUDIO-MIX
!1LMD0B,TV LOGIC
!1LMD0C,ALL CH STEREO
!1LMD0D,THEATER-DIMENSIONAL 
!1LMD0E,ENHANCED 7/ENHANCE
!1LMD0F,MONO 
!1LMD11,PURE AUDIO 
!1LMD12,MULTIPLEX
!1LMD13,FULL MONO
!1LMD14,DOLBY VIRTUAL
!1LMD40,5.1ch Surround
!1LMD40,Straight Decode*1
!1LMD41,Dolby EX/DTS ES
!1LMD41,Dolby EX*2
!1LMD42,THX Cinema
!1LMD43,THX Surround EX
!1LMD50,U2/S2 Cinema/Cinema2
!1LMD51,MusicMode
!1LMD52,Games Mode
!1LMD80,PLII/PLIIx Movie
!1LMD81,PLII/PLIIx Music
!1LMD82,Neo:6 Cinema
!1LMD83,Neo:6 Music
!1LMD84,PLII/PLIIx THX Cinema
!1LMD85,Neo:6 THX Cinema
!1LMD86,PLII/PLIIx Game
!1LMD87,Neural Surr*3
!1LMD88,Neural THX
!1LMD89,PLII THX Games
!1LMD8A,Neo:6 THX Games
!1LMDUP,Listening Mode Wrap-Around Up
!1LMDDOWN,Listening Mode Wrap-Around Down
header,Input Selector
!1SLI00,VIDEO1    VCR/DVR
!1SLI01,VIDEO2    CBL/SAT
!1SLI02,VIDEO3    GAME/TV
!1SLI03,VIDEO4    AUX1(AUX)
!1SLI04,VIDEO5    AUX2
!1SLI05,VIDEO6
!1SLI06,VIDEO7
!1SLI10,DVD
!1SLI20,TAPE(1)
!1SLI21,TAPE2
!1SLI22,PHONO
!1SLI23,CD
!1SLI24,FM
!1SLI25,AM
!1SLI26,TUNER
!1SLI27,MUSIC SERVER 
!1SLI28,INTERNET RADIO
!1SLI29,USB
!1SLI30,MULTI CH
!1SLI31,XM*1
!1SLI32,SIRIUS*1
!1SLIUP,Selector Position Wrap-Around Up
!1SLIDOWN,Selector Position Wrap-Around Down

Beer crate bottle counter

Post in 2002 due to screenshot .. dont know when i build it, some years before.

Using 24 pushbuttons and a IO expander, i could count the bottles in a crate. Probably used something like a hef4067 ??

Now i probably use a weight sensor or a beer cap counter using a webcam image.

Notification to email and shopping list printer.

Web Interface

Every bottle had to be placed back upside down so the opening of the bottle would not press down on the button. Later i used springs which could hold a empty bottle elevated above the button. The weight of a full bottle would press on the button.

Web part Dopcounter (screenshot at top of page)

<HTML><HEAD><TITLE>dopDB.counter running @ fash's place</TITLE></HEAD><BODY bgcolor=white text=black>
<?
if ($show){
print "<a href='index.php'>Show Last</a>";
}
else {
print "<a href='?show=1'>Show All</a>";
}
?>
<CENTER>
<?
$db = mysql_connect("localhost", "user", "pass");
mysql_select_db("dopDB",$db);
// store voor bargraph
$store=0;
$result2 = mysql_query("SELECT max(timestamp) FROM counter",$db);
$maxtimestamp = mysql_fetch_array($result2);
$result = mysql_query("SELECT * FROM counter",$db);
while ($myrow = mysql_fetch_array($result)) {
$lenght=strlen($myrow[1]);
if ( $lenght = 24)
{
if ($maxtimestamp[0] == $myrow[0] || $show)
 {
 $row1= substr("$myrow[1]", 0, 6);
 $row2= substr("$myrow[1]", 6, 6);
 $row3= substr("$myrow[1]", 12, 6);
 $row4= substr("$myrow[1]", 18, 6);
 $row1 = str_replace("1","<td><img src='dop.jpg'></td>",$row1);
 $row1 = str_replace("0","<td><img src='dopl.jpg'></td>",$row1);
 $row2 = str_replace("1","<td><img src='dop.jpg'></td>",$row2);
 $row2 = str_replace("0","<td><img src='dopl.jpg'></td>",$row2);
 $row3 = str_replace("1","<td><img src='dop.jpg'></td>",$row3);
 $row3 = str_replace("0","<td><img src='dopl.jpg'></td>",$row3);
 $row4 = str_replace("1","<td><img src='dop.jpg'></td>",$row4);
 $row4 = str_replace("0","<td><img src='dopl.jpg'></td>",$row4);
 print "<TABLE border=15 bgcolor='#aaaaaa'><TR>";
 print $row1;
 print "</tr><tr>";
 print $row2;
 print "</tr><tr>";
 print $row3;
 print "</tr><tr>";
 print $row4;
 print "</tr><table>";
 }
$dopcounter=str_replace("0","",$myrow[1]);
$totaldop=strlen($dopcounter);
if ($maxtimestamp[0] == $myrow[0] || $show)
 {
print "<P>";
print date('l dS of F Y H:i:s',$myrow[0]); 
print "<BR><H1>$totaldop bottles left</H1>";
 }
$store = $store + 1;
$storetotals[$store]=$totaldop;
if ($totaldop < 6 && $maxtimestamp[0] == $myrow[0])
 {
 print "<BR>Time to buy some beer again!<BR>";
 }
}
else
{
print "numba bottles error! check code!";
}
}
?>

<table border=0>
<tr>
<?
$storebck=$store;
if ($storebck > 50){ $store=$storebck-50; } else { $store=0; }
while ($store <= $storebck){
print "<td bgcolor=#efefff width=10 valign='bottom'>";
$double=$storetotals[$store]*2;
print "<img src='bar1.gif' width=15 height=$double></td>";
$store = $store +1;
}
?>
</tr>
<tr>
<?
if ($storebck > 50){ $store=$storebck-50; } else { $store=0; }
while ($store <= $storebck){
print "<td bgcolor=#efefff width=10 valign='bottom'>";
print "$storetotals[$store]</td>";
$store = $store +1;
}
?>
</tr>
</table>
</BODY></HTML>

Reverse engineering a alpha ticker led scoller

Cobra from the Icecrew got his hands on some Led scrollers.

But they only had a windows program to controll these, so we started some reverseengineering.

First we had to make a serial cable.
(Now we could easily use a logic analyser with protocol decoding)

Next i made a sniffer .. because we only had a windows program to control the display.
So we used a windows machine to control the display by serial, and using a read line to a linux machine to stiff the serial traffic

After some tinkering .. we got this

So we wrote some software to control it using Linux

Some code

#!/usr/bin/perl
# Get the attention of the sign
print "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
# Tell the sign to print the message
$message = "���������������������    ";
print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " b" . $message . "\004";
#print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " a" . $message . 
#"\004";

::::::::::::::
PERLTESTLED
::::::::::::::
#!/usr/bin/perl
print "\0\0\0\0\0\001" . "Z" . "00" . "\002" . "AA" . "\x1B" . " b" . "Test Message" . "\004";

::::::::::::::
PERLTESTLED2
::::::::::::::
#!/usr/bin/perl
# Get the attention of the sign
print "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
# Tell the sign to print the message
$message = "<<<<<<<<<<<<<<<<";
#print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " b" . $message . "\004";
print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " a" . $message . "\004";

A few days later i wrote a controller using glade. (Could not find more code)

Some time later we found some datasheets which could have helped!

Dartabase

Somewhere start 2002, i made a tool for playing darts.
Well … keeping score and history

I was multiuser, multigame with statistics and undo.
You could click on the little dartboard what your have thrown on a real board. It just kept score and told you best finish options.

Screenshot below was a digitized picture, no way accurate. Versions later the board was realtime drawn with GDlib and pixelperfect.
It even showed you previous throws.

At the end of the game it should give you the hotspots you have thrown.

Later version

Sound Firewall

See also 2nd Firewall 2013 and Led Firewall
https://www.henriaanstoot.nl/2013/08/03/ohm-2013-hackerevent/

While partying @ HAL2001, a hackers event, Venom and I made a Soundfirewall.

We had a little DMZ, with our servers.
This was protected by a iptables firewall.

Our idea was to get a sound notification on every (interesting) network packet the firewall dropped.

So we made this: (At the bottom are the sound definitions.)
Example of the sound we heared whole day.

#use strict;
#       @(#)    First Edit: Bas
#       @(#)    Last Edit: Fash

use POSIX ":sys_wait_h";
use vars qw(%Msg_Rec);

$SIG{'TERM'} = $SIG{'HUP'} = 'goodbye';
$SIG{'CHLD'} = 'IGNORE';

## Constants
my $BELL   = "";
my $MAILER = "/usr/sbin/sendmail";
my $WRITE  = "/usr/bin/write";
$/ = "
";

autoflush STDOUT;

sub goodbye {
  $| = 0;

  close_pipe_if_open();
  exit(0);
}

#
# in_range($range, $number) 
# returns 1 if $number is inside $range, 0 if not
#
sub in_range {
  my $range = shift;
  my $num = shift;

  foreach my $f (split(/,/, $range)) {
    if ($f =~ /-/) {
      my ($low,$high) = split(/-/, $f);
      return 1 if ($low <= $num and $num <= $high);
    } elsif ($f == $num) {
      return 1;
    }
  }
  return 0;
}

# 
# inside_time_window($days,$hours)
# returns 1 if inside window, 0 if outside window
#
sub inside_time_window {
  my $range = shift;
  my($days, $hours) = split(/:/, $range);

  my ($hr, $wday) = (localtime(time))[2,6];

  if (($days eq '*' or in_range($days, $wday))
      and ($hours eq '*' or in_range($hours, $hr))) {
    return 1;
  } else {
    return 0;
  }
}

  
print "\n*** swatch-3.0.1 (pid:6826) started at " . `/bin/date` . "\n";

  
use Date::Calc qw(:all);

sub parse_dot {
  my $message = shift;
  my $dot_loc = shift;
  my @dot = ();
  my @ranges = split(/:/, $dot_loc);

  foreach my $range (0..$#ranges) {
    if ($ranges[$range] != -1) {
      my ($begin, $end) = split(/-/, $ranges[$range]);
      $dot[$range] = substr($message, $begin, ($end - $begin + 1));
    }
  }

  return @dot;
}

my ($date_loc, $time_loc) = ("-1:0-2:4-5", "7-8:10-11:13-14");
my %months = (
              Jan => 1,
              Feb => 2,
              Mar => 3,
              Apr => 4,
              May => 5,
              Jun => 6,
              Jul => 7,
              Aug => 8,
              Sep => 9,
              Oct => 10,
              Nov => 11,
              Dec => 12
             );

# Returns an array of year, month, day, hours, minutes, and seconds.
#
sub YMDHMS {
  my $string = shift;
  my $year_today = (Today())[0];

  my ($y, $m, $d) = parse_dot($string, $date_loc);
  my ($hrs, $mins, $secs) = parse_dot($string, $time_loc);
  if (length($y) eq 0) { $y = (Today())[0] };

  return ($y, $months{$m}, $d, $hrs, $mins, $secs);
}

sub new_msg {
  my $use = shift;
  my $msg = shift;
  my $count = shift;
  my @delta = @_;
  my $delta;
  if ($delta[0] == 0) {
    $delta = sprintf("%d:%.2d:%.2d", $delta[1], $delta[2], $delta[3]);
  } else {
    $delta = sprintf("$delta[0] day%s %d:%.2d:%.2d", $delta[0] > 1 ? 's' : '',
                    $delta[1], $delta[2], $delta[3]);
  }
  if ($use eq 'regex') {
    return "$count $msg regular expressions in $delta";
  } else {
    return "$count in $delta: $msg";
  }
}

#
# Stores message information in 
#    $Msg_Rec = (
#      {<truncated message>|<pattern>} => {
#        dhms => [ array ], # days,hours,minutes,seconds
#        count => integer,

sub throttle {
  my %opts = (
              KEY       => $_,
              CUT_MARKS => [ "0:16" ], # not used yet
              USE       => 'message',
              @_
             );

  my $msg = $opts{'KEY'};
  my $use = $opts{'USE'};
  my @ymdhms = YMDHMS($msg);
  my $key;
  my @min_dhms_delta = split(/(\s+|:)/, $opts{'MIN_DELTA'});

  foreach my $i (0..$#min_dhms_delta) {
    # strip out unwanted element
    splice (@min_dhms_delta, $i, 1) if ($min_dhms_delta[$i] eq ":");
  }

  if ($use eq 'regex') {
    $key = $opts{'REGEX'};
  } else {
    $key = substr($msg, 16);
    $key =~ s/\[\d+\]/[PID]/;
  }

  while ($#min_dhms_delta < 3) {
    unshift(@min_dhms_delta, 0); # make sure that the dhms array is full
  }

  if (exists $Msg_Rec{$key} and defined $Msg_Rec{$key}->{ymdhms}) {
    my $passed = 1;
    $Msg_Rec{$key}->{count}++;
    if ($ymdhms[1] > $Msg_Rec{$key}->{ymdhms}[1]) { $ymdhms[0]--; }

    my @delta_dhms = Delta_DHMS(@{$Msg_Rec{$key}->{ymdhms}}, @ymdhms);
    foreach my $i (0..$#min_dhms_delta) {
      $passed = 0 if ($delta_dhms[$i] < $min_dhms_delta[$i]);
      last unless ($delta_dhms[$i] == $min_dhms_delta[$i]);
    }    
    if ($passed) {
      my $new = '';
      $new = new_msg($use, $key, $Msg_Rec{$key}->{count}, @delta_dhms);
      $Msg_Rec{$key}->{ymdhms} = [ @ymdhms ];
      $Msg_Rec{$key}->{count} = 1;
      return $new;
    } else {
      return '';
    }
  } else {
    my $rec;
    $rec->{ymdhms} = [ @ymdhms ];
    $Msg_Rec{$key} = $rec;
    return $msg;
  }
}


##
## ACTION SUBROUTINES
##

my %text_modes = (
  "black"       => "\033[30;1m",
  "red"         => "\033[31;1m",
  "green"       => "\033[32;1m",
  "yellow"      => "\033[33;1m",
  "blue"        => "\033[34;1m",
  "magenta"     => "\033[35;1m",
  "cyan"        => "\033[36;1m",
  "white"       => "\033[37;1m",
  "black_h"     => "\033[40;1m",
  "red_h"       => "\033[41;1m",
  "green_h"     => "\033[42;1m",
  "yellow_h"    => "\033[43;1m",
  "blue_h"      => "\033[44;1m",
  "magenta_h"   => "\033[45;1m",
  "cyan_h"      => "\033[46;1m",
  "white_h"     => "\033[47;1m",
  "bold"        => "\033[1m",
  "blink"       => "\033[5m",
  "inverse"     => "\033[7m",
  "normal"      => "\033[0m",
  "underscore"  => "\033[4m",
);
  
sub echo {
  my %args = (
              'MODES' => [ 'normal' ],
              @_
             );

  return if (exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}));
  
  if ($args{'MODES'}[0] eq 'random') {
    my @mode_names = keys %text_modes;
    print $text_modes{$mode_names[rand $#mode_names]};
  } else {
    foreach my $mode (@{$args{'MODES'}}) {
      print $text_modes{$mode};
    }
  }
  print $args{'MESSAGE'};
  print $text_modes{'normal'};
  print "\n";
}

#
# ring_bell(args) -- send x number of control-G characters to the output.
#
sub ring_bell {
  my %args = (
              'RINGS' => 1,
              @_
             );
  my $sun_terminal = (`uname -s` eq 'SunOS\n');
  
  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});
  
  my $bells = $args{'RINGS'};
  for ( ; $bells > 0 ; $bells-- ) {
    print $BELL;
    sleep 1 if $sun_terminal; # SunOS needed this. Not sure about Solaris though
  }
}

#
# exec_command(args) -- fork and execute a command
#
sub exec_command {
  my %args = (@_);
  my $exec_pid;
  my $command;

  if (exists $args{'COMMAND'}) {
    $command = $args{'COMMAND'};
  } else {
    warn "$0: No command was specified in exec action.\n";
    return;
  }

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

 EXECFORK: {
    if ($exec_pid = fork) {
      waitpid(-1, WNOHANG);
      return;
    } elsif (defined $exec_pid) {
      exec($command);
      } elsif ($! =~ /No more processes/) {
        # EAGAIN, supposedly recoverable fork error
        sleep 5;
        redo EXECFORK;
      } else {
        warn "$0: Can't fork to exec $command: $!\n";
      }
  }
  return;
}


{
  my $pipe_is_open;
  my $current_command_name;
  #
  # send_message_to_pipe -- send text to a pipe.
  #
  # usage: &send_message_to_pipe($program_to_pipe_to_including_the_vertical_bar_symbol,
  #               $message_to_send_to_the_pipe);
  # 
  
  sub send_message_to_pipe {
    my %args = (@_);
    my $command;

    if (exists $args{'COMMAND'}) {
      $command = $args{'COMMAND'};
    } else {
      warn "$0: No command was specified in pipe action.\n";
      return;
    }

    return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

    # open a new pipe if necessary
    if ( !$pipe_is_open or $current_command_name ne $command ) {
      # first close an open pipe
      close(PIPE) if $pipe_is_open;
      $pipe_is_open = 0;
      open(PIPE, "| $command") 
        or warn "$0: cannot open pipe to $command: $!\n" && return;
      PIPE->autoflush(1);
      $pipe_is_open = 1;
      $current_command_name = $command;
    }
    # send the text
    print PIPE "$args{'MESSAGE'}";

    if (not exists $args{'KEEP_OPEN'}) {
      close(PIPE) if $pipe_is_open;
      $pipe_is_open = 0;
    }
  }

  #
  # close_pipe_if_open -- used at the end of a script to close a pipe
  #     opened by &pipe_it().
  #
  # usage: &close_pipe_if_open();
  #
  sub close_pipe_if_open {
    if ($pipe_is_open) {
      close(PIPE);
    }
  }
}


#
# send_email -- send some mail using $MAILER.
#
# usage: &send_email($addresses_to_mail_to);
#
sub send_email {
  my $login = (getpwuid($<))[0];
  my %args = (
              'ADDRESSES' => $login,
              'SUBJECT' => 'Message from Swatch',
              @_
             );

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

  my $addresses = $args{'ADDRESSES'};
  $addresses =~ s/:/,/g;

  if ($MAILER eq '') {
    warn "ERROR: $0 cannot find a mail delivery program\n";
    return;
  }

  open(MAIL, "| $MAILER $addresses")
    or warn "$0: cannot open pipe to $MAILER: $!\n" && return;

  print MAIL "To: $addresses\n";
  print MAIL "Subject: $args{SUBJECT}\n\n";
  print MAIL "$args{'MESSAGE'}\n";
  close(MAIL);
}


#
# write_message -- use $WRITE to send a message logged on users.
#
sub write_message {
  my %args = (@_);

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

  if ($WRITE eq '') {
    warn "ERROR: $0 cannot find the write(1) program\n";
    return;
  }

  if (exists($args{'USERS'})) {
    foreach my $user (split(/:/, $args{'USERS'})) {
      send_message_to_pipe(COMMAND => "$WRITE $user 2>/dev/null", 
                           MESSAGE => "$args{'MESSAGE'}\n");
    }
  }
}

use File::Tail;
my $Filename = '/var/log/ulog/syslogemu.log';
my $File = File::Tail->new(name=>$Filename, maxinterval => 1, interval => 1);
if (not defined $File) {
    die "/usr/local/bin/swatch: cannot read input \"$Filename\": $!\n";
}

LOOP: while (defined($_=$File->read)) {

    chomp;
    my $sanitized_ = $_;
    @_ = split;
    
    # quote all special shell chars
    $sanitized_ =~ s/([;&\(\)\|\^><\$`'\\])/\\$1/g;
    my @sanitized_ = split(/\s+/, $sanitized_);
    if (/INVALID|REPEATED|INCOMPLETE:LOGIN/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        ring_bell('RINGS' => "3", );
        next;
    }

    if (/(panic|halt)/) {
        echo('MESSAGE' => "$_", );
        ring_bell();
        next;
    }

    if (/Regents/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        ring_bell();
        next;
    }

    if (/ipfw:.*Deny ICMP:8.0/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/drip.wav &", );
        next;
    }

    if (/ipfw:.*Deny TCP .*:6000/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/camera.wav &", );
        next;
    }

    if (/ipfw:.*Deny UDP .*:513/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/flush.wav &", );
        next;
    }

    if (/ipfw:.*Deny TCP .*:21/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/vault.wav &", );
        next;
    }

    if (/PROTO=TCP .*DPT=80/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/tcp80.mp3 &", );
        next;
    }
    if (/PROTO=TCP .*DPT=23/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/tcp23.mp3 &", );
        next;
    }

    if (/UDP .*=1300007/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/udp137.mp3 &", );
        next;
    }

    if (/PROTO=ICMP/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/ping.mp3 &", );
        next;
    }

    if (/.*/) {
        echo('MESSAGE' => "$_", );
        next;
    }

}