tialotta.de – Die neue Heimat meiner Frau

Seit neuestem hat meine Frau auch ein Blog. Unter www.tialotta.de veröffentlicht Sie in Zukunft Ihr Handarbeitsgedöns und was Sie so bastelt. <vorurteilsmodus>Es handelt sich also um eine reine Frauenseite. </vorurteilsmodus> Bis lang ist erst ein kleiner Artikel veröffentlicht, aber ich denke da wird bald mehr folgen.

Das Ganze hat mich in den letzten Tagen einige Stunden an Arbeit gekostet, hat aber Spaß gemacht. Das Einrichten und Konfigurieren von WordPress ist ja kein Problem. Aber ein Theme zusammenbasteln, dass Swantje gefällt, war gar nicht so einfach. Naja, ich denke es ist nun aber recht nett geworden. Sie ist jedenfalls zufrieden.

TomTom Update Fail – Ein Drama in 6 Stunden

Nee, nee, nee! Was TomTom sich damit gedacht hat, ist mir ein Rätsel. Ich habe zu Weihnachten ein TomTom XL IQ Routes Europe verschenkt. Und mit dem Geschenk habe ich dummerweise das Versprechen abgegeben, ein Software- und Kartenupdate durchzuführen, da der Empfänger nicht so wahnsinnig in solchen Sachen bewandert ist. Hätte ich es bloß nicht getan.

Zunächst sah noch alles prima aus. TomTom an mein Notebook angeschlossen und Windows 7 meldete, dass es die notwendige Software aus dem Netz ziehen und installieren werden. Klasse. Nur leider wurde daraus nichts. Na gut, die Software lässt sich ja auch manuell installieren. Das klappte auch gleich auf anhieb.

Nach dem Start von TomTom HOME und dem Einrichten eines Benutzers wurde gleich ein Update auf die neueste Softwareversion angeboten. Das habe ich aber erstmal gelassen, denn wichtig war mir zunächst das Kartenmaterial. Also erstmal dieses Update starten. 1.6GB aus dem Netz saugen und dann gleich mal installiern. Dauert zwar alles elend lange, da die USB-Übertragungsgeschwindigkeit grottenschlecht ist, aber man hat ja nach Weihnachten genug Zeit. Aber irgendwie klappte das alles nicht. Zuwenig freier Speicher auf dem TomTom war die Meldung. Hä? Ein nagelneues Gerät, dass ein aktuelles Update für genau dieses Gerät nicht frisst, weil zu wenig Speicher frei ist? Ominös. Oder einfach ein völliger Fail von TomTom. Was tun?

Naja, ich habe dann einfach mal mit dem Explorer ein paar Sprachdateien aus dem System gelöscht. Und nun ließ es sich die Installation auch starten. Also warten… Nach ca. einer Stunde dann: Fehlermeldung – nicht genug Speicher. Das Update ist abgekackt. Wie jetzt? Wozu untersucht die Updatefunktion vorher ob genug Speicher vorhanden ist, wenn es dann doch nicht reicht. Schwachsinnige Programmierer! Was nun?

Na, vielleicht sollte ich erstmal die Systemsoftware erneuern. Also Update angeschoben und … Zu wenig Speicher vorhanden. Es ist zum Mäuse melken.

Ich habe dann noch ein paar Stunden (Datensicherung bei der elend lahmen Geschwindigkeit macht einfach keinen Spaß) rumprobiert und habe dann den Entschluss gefasst, das TomTom-Laufwerk zu formatieren und die Updates auf ein nacktes System einzuspielen. Das war auch die Lösung! Nun passt alles drauf und es funktioniert einwandfrei.

Es bleibt die Frage, wie ein Normalsterblicher das schaffen soll. Unmöglich!

Umstellung

Weihnachtszeit! Zeit um endlich mal ein paar Dinge zu tun, die ich schon lange vor mir her geschoben habe. Eines dieser Dinge ist, endlich steindorff.de vom ewiki zu befreien und ein WordPress aufzuspielen. Und das habe ich nun auch geschafft. Das ewiki ist mittlerweile nur noch ein Spam-Grab gewesen. Und Minuten nachdem ich WordPress installiert hatte, erhielt ich auch schon den ersten Kommentarspam. Doch Akismet sei Dank, kümmert mich das jetzt nicht mehr. Vom alten ewiki habe ich ein paar Artikel gerettet, die sich um PHP drehen.

WMI mit PHP

Folgender PHP-Code ermittelt die auf einem Windows-System installierte Software. Dabei kann man auch einen Remote-Computer abfragen. Mit der Funktion getWMI() kann man aber auch alle anderen WMI-Abfragen durchführen. Das Funktioniert natürlich nur unter Windows.

<?php
function getWMI($strClass,$strHostname ='', $strUser ='', $strPassword = '') {

    $objLocator = new COM("WbemScripting.SWbemLocator");
    if($strHostname == "") {
        $objService = $objLocator->ConnectServer();
    } else{
        $objService = $objLocator->ConnectServer($strHostname, "rootcimv2", "$strHostname\$strUser", $strPassword);
    }
    
    $objWEBM = $objService->Get($strClass);
    $objProp = $objWEBM->Properties_;
    
    $arrProp = $objProp->Next($objProp->Count);

    $objWEBMCol = $objWEBM->Instances_();
    $arrWEBMCol = $objWEBMCol->Next($objWEBMCol->Count);
    foreach($arrWEBMCol as $objItem)
    {
        reset($arrProp);
        $arrInstance = array();
        foreach($arrProp as $propItem)
        {
            eval("\$value = \$objItem->" .$propItem->Name .";");
            $arrInstance[$propItem->Name] = trim($value);
        }
        $arrData[] = $arrInstance;
    }
    return $arrData;
}


echo "<pre>";

print_r(getWMI("Win32_Product", "192.168.0.56", "administrator", "password"));

echo "</pre>";
?>

AJAX ganz einfach

Dynamische Seite ganz einfach bauen, ohne dass wir einen Reload brauchen? Das geht! Schaut Euch mal das folgende an.

<html>
<head>
  <title>Dynamic Test</title>
  <script language="javascript" type="text/javascript" src="./request.js"></script>
</head>
<body>
  Auswahl:
  <form name="form_category">
    <select name="select_category">
	  <option value="date">Datum</option>
	  <option value="time">Uhrzeit</option>
	  <option value="datetime">Datum + Uhrzeit</option>
    </select>
    <input type="button" name="requestbtn" value="Anzeigen"
              onClick="httpRequest('http://admin/dynamic/request.php', 'id', document.form_category.select_category.value, 'answer')">
  </form>
  Ergebnis:
  <div id="answer" style="background-color: #D0D0D0;">
    <!--This is where we'll be displaying the products once they're loaded-->
	Bitte wählen Sie ein Zeitformat.
  </div>
</body>
</html>

Die Seite besteht nun aus einem Drop-Down Feld aus dem wir die Einträge „Datum“, „Uhrzeit“ und „Datum + Uhrzeit“ wählen können. Wenn wir nun auf den Button „Anzeigen“ klicken, wird uns im unteren Teil der Seite in einem DIV-Block entsprechend unserer Auswahl das Datum, die Uhrzeit oder halt beides angezeigt. Tooooll….. Nix neues? Doch! Denn das Ergebnis wird uns dort angezeigt, ohne dass die Seite neu geladen wird. Ok, das Beispiel mit Datum und Uhrzeit geht natürlich auch direkt mit JS, aber man damit noch ganz andere Sachen, z.B. Datenbankabfragen machen. Wie? Nun ja, in unserem Beispiel wird die Berechnung von Datum und Uhrzeit nicht in JS vorgenommen, sondern erfolgt in einem PHP-Skript, dass irgendwo auf einem Erreichbaren Rechner liegen kann.

Das entscheidende sind die Zeilen 4 und 15. In Zeile 4 binden wir das folgenden JavaScript „request.js“ ein:

// Hier wird die Antwort Ausgegeben (ID des Ausgabeelements, z.B. ein DIV-Block)
var ResponseTargetID = '';


// Funktion zum Erzeugen eines XMLHttpRequest-Objekts
function createRequestObject(){
	var request_o; 
	var browser = navigator.appName;
	 
	if (browser == "Microsoft Internet Explorer") {
		request_o = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		request_o = new XMLHttpRequest();
	}
	return request_o;
}
  
// Erzeuge XMLHttpRequest-Objekt
var http = createRequestObject();

	
/**
*  Funktion zum Abrufen der Informationen
*
* @param uri - URI der abzurufenden Seite 
* @param parameter - Abfrage Parameter, z.B. 'id'
* @param value - Wert des Parameters
* @param targetID - ID des Elements, dass die Ausgabe anzeigen soll
*/
function httpRequest(uri,parameter,value,targetID){
	
	ResponseTargetID = targetID;
	
	http.open('GET', uri + '?' + parameter + '=' + value);
	
	// Handler definieren
	http.onreadystatechange = handleResponse;

	// Daten senden. In unserem Fall nix!	
	http.send(null);
}


/**
* handleResponse()
*
* verarbeitet die Antworten des Requests
*/
function handleResponse(){
			
		
	/* Das XMLHttpRequest-Objekt hat eine Eigenschaft readyState. Diese kann
	   folgende Werte annehmen:
		0: Uninitialized
		1: Loading
		2: Loaded
		3: Interactive
		4: Finished */
	if(http.readyState == 4) { // Finished?
		if (http.status == 200) { // Status OK?
			var response = http.responseText;
			
			// Ergebnis in das Element einfügen.
			document.getElementById(ResponseTargetID).innerHTML = response;
		}
	}
}

Dies stellt uns die Möglichkeit zur Verfügung per JS Anfragen an einen Server zu stellen. Dazu wird die Funktion XMLHttpRequest() benutzt. Es wird einfach per XMLHttpRequest-Objekt.open() eine Seite abgerufen und das Ergebnis an unsere Seite zurückgeliefert. handleResponse() zeigt das Ergebnis wird dann im Response-Target an. In unserem Fall ist das der DIV-Block mit der ID „answer“.

Die Anfrage selber geschieht in Zeile 15 unserer HTML-Seite. Dort wird die JS-Funktion httpRequest aus unserem JS-Script benutzt, um eine Anfrage an einen anderen Rechner zu stellen. Das Ergebnis wird dann in DIV-Block mit der id=“answer“ angezeigt.

Schauen wir uns mal den Server-Code in request.php an:

<?php

if ($_GET['id'] == 'date') {
	echo date('Y-m-d');
}

if ($_GET['id'] == 'time') {
	echo '<b>'.date('H:i:s').'</b>';
}

if ($_GET['id'] == 'datetime') {
	echo date('Y-m-d / H:i:s');
}

?>

Das ist ja nun ganz simpel. Je nach per GET übergebener ID, wird einfach eine andere Ausgabe erzeugt.

Wie benutze ich das nun?

Was ich brauche ist eine HTML-Seite mit einem Formular. Auf der Seite binde ich per

<script language="javascript" type="text/javascript" src="./request.js">

im Header das JavaScript ein.

Wenn nun ein bestimmtes Ereignis ausgelöst wird, z.B. onClick eines Buttons, müssen wir nun nur noch das Ergebnis aus dem Netz abfragen:

<input type="button" name="requestbtn" value="Anzeigen"
          onClick="httpRequest('http://admin/dynamic/request.php', 'id', document.form_category.select_category.value, 'answer')"> 

Die Syntax von httpRequest

httpRequest(url,parameter,value,targetid)

  • url abzufragende Seite
  • parameter GET-Parameter, in unserem Beispiel ‚id‘
  • value Wert des Parameters, in unserem Beispiel also ‚date‘, ‚time‘ oder ‚datetime‘
  • targetid ID eines HTML-Elements, dass das Ergebnis anzeigen soll, im Beispiel ‚answer‘ (ein DIV-Block)
  • httpRequest fragt nun die Ausgabe der Seite url?parameter=value (z.B. http://admin/dynamic/request.php?id=date) ab und zeigt die Ausgabe der URL im DIV-Block an.

    Was kann man damit machen?

    Es gibt vielfältige Anwendungsmöglichkeiten. Zum Beispiel kann Datenbankeinträge abfragen und darstellen ohne dass ein Page-Reload notwendig ist. Ich denke da fällt jedem etwas Tolles ein. Eine andere Möglichkeit wäre eine Textvervollständigung in einem Text-Input-Feld, die durch das Ereignis keyKeyup ausgelöst wird.

Wake On LAN mit PHP

Mit der folgenden Funktion können WakeOnLAN-fähige Computer im lokalen Netzwerk gestartet werden.

<?php

   Trallala
   
/**
 * WakeUpComputer()
 *
 * Sends a MagicPaket to wake up a computer
 *
 * MagicPaket (116 bytes)
 *
 *     byte   content
 * ---------------------------
 *     1..6   MAC-Address
 *        7   0x00
 *        8   0x74
 *        9   0xFF   
 *       10   0xFF   
 *       11   0xFF   
 *       12   0xFF   
 *       13   0xFF   
 *       14   0xFF   
 *  15..110   6 x MAC-Adress
 *      111   0x40
 *      112   0x00
 *      113   0x90
 *      114   0x90
 *      115   0x40
 *      116   0x00 
 *   
 *   
 * @author Christoph Steindorff, ECW GmbH <cst@ecw.de>
 * @param string $strMacAddress, e.g. '001111d35df8'
 * @param integer $iPort, e.g. 80
 * @return boolean TRUE: packet send, FALSE: error 
 */
function WakeUpComputer($strMacAddress,$iPort=2050) {
	
	$strMAC='';
	$strMagicPaket='';
	
	
	if (strlen($strMacAddress) == 12) {
		for ($x=0; $x<6; $x++) {
			$strMAC .= chr(hexdec(substr($strMacAddress,($x*2),2)));
		}
		
		// Part 1: MAC-Address - Bytes 1..6
		$strMagicPaket =  $strMAC;
		
		// Part 2: Bytes 7..8
		$strMagicPaket .= chr(0x00);  
		$strMagicPaket .= chr(0x74);
		
		// Part 3: 6 x 0xFF - Bytes 9..14		
		for ($x=0; $x<6; $x++) {
			$strMagicPaket .= chr(0xFF);
		}
		
		// Part 4: 16 x MAC-Address - Bytes 15..110
		for ($x=0; $x<16; $x++) {
			$strMagicPaket .= $strMAC;
		}
		
		// Part 5: Bytes 111..116
		$strMagicPaket .= chr(0x40);  // 111
		$strMagicPaket .= chr(0x00);  // 112
		$strMagicPaket .= chr(0x90);  // 113
		$strMagicPaket .= chr(0x90);  // 114
		$strMagicPaket .= chr(0x40);  // 115
		$strMagicPaket .= chr(0x00);  // 116
		

		// Send Paket
		$fudp = fsockopen('udp://255.255.255.255',$iPort,$errno,$errstr);
		
		if ($fudp) {
			fwrite($fudp, $strMagicPaket);
			fclose($fudp);
		} else {
			return FALSE;
		}
	} else {
		return FALSE;
	}
	return TRUE;
}

if WakeUpComputer('001111d35df8') {
	echo 'MagicPaket gesendet.';
} else {
	echo 'MagicPaket nicht gesendet';
} 
?>

Um unter Windows die MAC-Adressen der lokalen Computer herauszufinden, kann man sie einfach von der Konsole aus anpingen und anschließend ein ‚arp -a‘ ausführen.

In folgenden Beispiel, wollen wir die MAC-Adresse vom Rechner mit der lokalen IP-Adresse 192.168.0.47 herausfinden. Zunächst pingen wir den Rechner an: ‚ping 192.168.0.47‘. Anschließend rufen wir ‚arp -a‘ auf. Nun wird uns die MAC-Adresse angezeigt, die zu der IP-Adresse gehört.

Diesen Wert, in unserem Beispiel ’00-04-75-d7-e0-92′, verwenden wir nun mit unserer Funktion WakeUpComputer(). Allerdings müssen alle Bindestriche entfernt werden. Der Aufruf wäre also: WakeUpComuter(‚000475d7e092‘);

Syntax Highlighting mit PHP

Ein kleines Beispiel zu PEAR:Text_Highlighter.

<?php
/**
* Beispiel zur Verwendung von PEAR::Text/Highlighter
*/
?>
<html>
<head>
  <STYLE type="text/css">
	.hl-main {font-family: monospace; font-size:13px;}
	
	.hl-default { color: #000000; }
	.hl-code { color: #7f7f33; }
	.hl-brackets { color: #0000FF; }
	.hl-comment { color: #008000; font-style: italic; }
	.hl-quotes { color: #00007F; }
	.hl-string { color: #008080; }
	.hl-identifier { color: #000000; }
	.hl-reserved { color: #000080; }
	.hl-inlinedoc { color: #0000FF; }
	.hl-var { color: #FF0000; }
	.hl-url { color: #0066FF; }
	.hl-special { color: #0000FF; }
	.hl-number { color: #800080; }
	.hl-inlinetags { color: #000080; font-weight: bold; }
  </style>
</head>
<body>
<?php

// PEAR-Klasse Text/Highlighter einbinden
require_once('Text/Highlighter.php');

// Objekt erzeugen
// Sprache: SQL, Zeilennummer anzeigen
$hl =& Text_Highlighter::factory('SQL',array('numbers'=>true));

// Ausgeben von des Quelltextes von query.sql
echo $hl->highlight(file_get_contents('query.sql'));

?>
</body>
</html>

Ist ja einfach. PEAR:Text/Highlighter unterstützt verschiedene Sprachen, u.a: PHP, SQL, Java, C++, XML, DTD …