<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ulrich-Block.de</title>
	<atom:link href="http://www.ulrich-block.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ulrich-block.de</link>
	<description></description>
	<lastBuildDate>Fri, 20 Apr 2012 21:32:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>wp-cron.php?doing_wp_cron=1334444885</title>
		<link>http://www.ulrich-block.de/wp-cron-phpdoing_wp_cron1334444885/</link>
		<comments>http://www.ulrich-block.de/wp-cron-phpdoing_wp_cron1334444885/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 21:26:23 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Apache2]]></category>
		<category><![CDATA[cronjob]]></category>
		<category><![CDATA[doing_wp_cron]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-cron.php]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1804</guid>
		<description><![CDATA[WordPress hat eine Standardeigenschaft, die man erst im Log des Webservers sieht. Alle X Seitenaufrufe wir die Datei wp-cron.php aufgerufen. Im Log des Webservers sieht es dann so aus: 1.1.1.1 - - [15/Apr/2012:01:08:05 +0200] "POST /wp-cron.php?doing_wp_cron=1334444885 HTTP/1.0" 200 - "-" "WordPress/3.3.1; http://www.ulrich-block.de" Da das Intervall zwischen den einzelnen Zugriffen recht kurz ist, sind die Einträge im Log sehr zahlreich. Die Datei ist meines Wissens für Dinge wie das versenden von E-Mails bei neuen Kommentaren zuständig. Bei einem Blog der nur ein paar hundert Aufrufe in der Stunde hat und bei dem nur ab und zu Kommentare gepostet werden ist diese]]></description>
			<content:encoded><![CDATA[<p>WordPress hat eine Standardeigenschaft, die man erst im Log des Webservers sieht. Alle X Seitenaufrufe wir die Datei <em>wp-cron.php</em> aufgerufen. Im Log des Webservers sieht es dann so aus:<br />
<code><br />
1.1.1.1 - - [15/Apr/2012:01:08:05 +0200] "POST /wp-cron.php?doing_wp_cron=1334444885 HTTP/1.0" 200 - "-" "WordPress/3.3.1; http://www.ulrich-block.de"<br />
</code></p>
<p>Da das Intervall zwischen den einzelnen Zugriffen recht kurz ist, sind die Einträge im Log sehr zahlreich.</p>
<p>Die Datei ist meines Wissens für Dinge wie das versenden von E-Mails bei neuen Kommentaren zuständig.</p>
<p>Bei einem Blog der nur ein paar hundert Aufrufe in der Stunde hat und bei dem nur ab und zu Kommentare gepostet werden ist diese Funktion demnach eine Recourcenverschwendung.</p>
<p>Eine Alternative musste demnach her.</p>
<p>Als erstes habe ich die Funktion ganz deaktiviert, indem ich folgendes in die wp-config.php eingetragen habe:</p>
<pre class="brush:php">
define('DISABLE_WP_CRON', true);
</pre>
<p>Im nächsten Schritt habe ich einen Cronjob angelegt, der die Datei auf der Console ausführt:</p>
<pre class="brush:bash">
0 */1 * * * cd /homepages/domain.tld/httpd &#038;&#038; timeout=120 php ./wp-cron.php
</pre>
<p>Der Cronjob ruft die Datei stündlich auf und ich kann weiterhin alle Funktionen wahrnehmen. Der wesentliche Unterschied liegt da drin, das der Webserver nicht alle X Aufrufe die Datei aufruft.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/wp-cron-phpdoing_wp_cron1334444885/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sourcemod Update 1.4.2</title>
		<link>http://www.ulrich-block.de/sourcemod-update-1-4-2/</link>
		<comments>http://www.ulrich-block.de/sourcemod-update-1-4-2/#comments</comments>
		<pubDate>Sat, 14 Apr 2012 13:42:50 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[Sourcemod]]></category>
		<category><![CDATA[1.4.2]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DODS]]></category>
		<category><![CDATA[server crash]]></category>
		<category><![CDATA[sicherheitsupdate]]></category>
		<category><![CDATA[TF2]]></category>
		<category><![CDATA[Update]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1798</guid>
		<description><![CDATA[Sourcemod wurde in der neuen Version 1.4.2 veröffentlicht. Jeder sollte so schnell wie möglich seine Installationen aktualisieren. Diese Eile ist notwendig, weil es sich um Sicherheitsupdate handelt. Es behebt ein Problem, bei dem ein Angreifer den Server zum Absturz bringen kann. Zusätzlich wurde folgendes geändert: Änderungen aus 1.4.0 behoben, die zu einem erhöhten Leistungsverbrauch bei &#8220;The Ship&#8221; führen. Gamedata Unterstützung für Spiele aktualisiert. Diverse Fehler behoben Sourcemod kann von der Downloadseite heruntergeladen werden. Einige Support Links: Hifle beim Updaten Komplette beschreibung des Updates Der originale englische Text: SourceMod 1.4.2 Released Apr 13, 2012 22:03 I&#8217;m pleased to announce that SourceMod]]></description>
			<content:encoded><![CDATA[<p>Sourcemod wurde in der neuen Version 1.4.2 veröffentlicht.</p>
<p>Jeder sollte so schnell wie möglich seine Installationen aktualisieren. Diese Eile ist notwendig, weil es sich um Sicherheitsupdate handelt. Es behebt ein Problem, bei dem ein Angreifer den Server zum Absturz bringen kann.</p>
<p>Zusätzlich wurde folgendes geändert:</p>
<ul>
<li>Änderungen aus 1.4.0 behoben, die zu einem erhöhten Leistungsverbrauch bei &#8220;The Ship&#8221; führen.</li>
<li>Gamedata Unterstützung für Spiele aktualisiert.</li>
<li>Diverse Fehler behoben</li>
</ul>
<p>Sourcemod kann von der <a href="referrer.php?r=http://www.sourcemod.net/downloads.php" target="_blank">Downloadseite</a> heruntergeladen werden. Einige Support Links:</p>
<ul>
<li><a href="referrer.php?r=http://wiki.alliedmods.net/Upgrading_SourceMod" target="_blank">Hifle beim Updaten</a></li>
<li><a href="referrer.php?r=http://wiki.alliedmods.net/SourceMod_1.4.2_Release_Notes" target="_blank">Komplette beschreibung des Updates</a></li>
</ul>
<p>Der originale englische Text:</p>
<blockquote><p>
SourceMod 1.4.2 Released 	Apr 13, 2012 22:03<br />
I&#8217;m pleased to announce that SourceMod 1.4.2 has been released.</p>
<p>It is strongly recommended that users of older versions update as soon as possible. We resolved an important security issue wherein an attacker could intentionally cause the game server to crash.</p>
<p>Other than that, this is a minor update, whose highlights include:</p>
<ul>
<li>Fixed regression in SM 1.4.0 causing load issue on The Ship</li>
<li> Updated gamedata for supported games</li>
<li>Bug fixes</li>
</ul>
<p>You can get SourceMod from the downloads page. Some support links:</p>
<ul>
<li>Need help upgrading?</li>
<li>Release notes.</li>
</ul>
<p>Thanks to BAILOPAN and Asherkin for fixes and helping to ready the release, as well as other members of the SM community for various other fixes, including FlaminSarge, Dr!fter, VoiDeD, and ProdigySim.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/sourcemod-update-1-4-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neues aus dem Maschinenraum Nr. 2</title>
		<link>http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/</link>
		<comments>http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 19:15:40 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[easy-wi.com]]></category>
		<category><![CDATA[Webinterface]]></category>
		<category><![CDATA[Easy-Wi]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[gamepanel]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[Screenshot]]></category>
		<category><![CDATA[umsonst]]></category>
		<category><![CDATA[Vorschau]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1779</guid>
		<description><![CDATA[Auch bei meinem Webinterface Easy-Wi geht es voran. Hier sind ein paar aktuelle Bilder aus dem Backend des Interfaces]]></description>
			<content:encoded><![CDATA[<p>Auch bei meinem Webinterface <a href="http://easy-wi.com" target="_blank">Easy-Wi</a> geht es voran.</p>
<p>Hier sind ein paar aktuelle Bilder aus dem Backend des Interfaces</p>

<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/versionoverview-2/' title='versionoverview'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/versionoverview1-150x150.png" class="attachment-thumbnail" alt="versionoverview" title="versionoverview" /></a>
<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/useroverview-2/' title='useroverview'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/useroverview1-150x150.png" class="attachment-thumbnail" alt="useroverview" title="useroverview" /></a>
<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/ipbans-2/' title='ipbans'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/ipbans1-150x150.png" class="attachment-thumbnail" alt="ipbans" title="ipbans" /></a>
<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/pageoverview-2/' title='pageoverview'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/pageoverview1-150x150.png" class="attachment-thumbnail" alt="pageoverview" title="pageoverview" /></a>
<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/gserveroverview-2/' title='gserveroverview'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/gserveroverview1-150x150.png" class="attachment-thumbnail" alt="gserveroverview" title="gserveroverview" /></a>
<a href='http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/groupsoverview-2/' title='groupsoverview'><img width="150" height="150" src="http://www.ulrich-block.de/wp-content/uploads/2012/04/groupsoverview1-150x150.png" class="attachment-thumbnail" alt="groupsoverview" title="groupsoverview" /></a>

]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/neues-aus-dem-maschinenraum-nr-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Userinput Klasse Nr. 2</title>
		<link>http://www.ulrich-block.de/userinput-klasse-nr-2/</link>
		<comments>http://www.ulrich-block.de/userinput-klasse-nr-2/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 11:03:08 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[Klasse]]></category>
		<category><![CDATA[Userinput]]></category>
		<category><![CDATA[Validieren]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1772</guid>
		<description><![CDATA[Ich hatte in einem vorigen Beitrag ein Konzept einer PHP Klasse veröffentlich, mit dem man Userinput validieren kann. In dem Code waren noch einige Dinge unausgereift und führten zu Problemen. Diese lagen insbesondere im Zusammenhang mit Userinput der in Form eines Arrays gesendet wurde. Die Schwachstellen sind nun ausgebessert und mehr Methoden zum Validieren zusammengekommen. Demnach sollte die Klasse für den produktiven Einsatz geeignet sein. Die Downloadseite befindet sich hier. Zusätzliche Methoden und reguläre Ausdrücke kann man immer gebrauchen. Wer also Ergänzungen hat, kann sie mir gerne per Mail und oder Kommentar schreiben. Ich werde sie dann nachtragen.]]></description>
			<content:encoded><![CDATA[<p>Ich hatte in einem <a href="http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/" target="_blank">vorigen Beitrag</a> ein Konzept einer PHP Klasse veröffentlich, mit dem man Userinput validieren kann.</p>
<p>In dem Code waren noch einige Dinge unausgereift und führten zu Problemen. Diese lagen insbesondere im Zusammenhang mit Userinput der in Form eines Arrays gesendet wurde.</p>
<p>Die Schwachstellen sind nun ausgebessert und mehr Methoden zum Validieren zusammengekommen. Demnach sollte die Klasse für den produktiven Einsatz geeignet sein.</p>
<p>Die Downloadseite befindet sich <a href="http://www.ulrich-block.de/skripte/userinput-klasse/" target="_blank">hier</a>.</p>
<p>Zusätzliche Methoden und reguläre Ausdrücke kann man immer gebrauchen. Wer also Ergänzungen hat, kann sie mir gerne per Mail und oder Kommentar schreiben. Ich werde sie dann nachtragen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/userinput-klasse-nr-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screenshots erstellen einfach gemacht mit Greenshot</title>
		<link>http://www.ulrich-block.de/screenshots-erstellen-einfach-gemacht-mit-greenshot/</link>
		<comments>http://www.ulrich-block.de/screenshots-erstellen-einfach-gemacht-mit-greenshot/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 11:15:21 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[einfach]]></category>
		<category><![CDATA[greenshot]]></category>
		<category><![CDATA[Screenshot]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1754</guid>
		<description><![CDATA[Jeder, der öfter mal Screenshots erstellen muss, kennt das Problem. Man muss auf die Drucken Taste drücken und dann die Zwischenablage in eine Grafikbearbeitungssoftware kopieren. Je nach deren Qualität dauert es dann einige Arbeitsschritte, bis man das gewünschte Ergebnis hat. Ich wurde vor kurzem auf das kostenlose Programm Greenshot hingewiesen, dass das Erstellen von Screenshots stark vereinfacht. Drückt man die Drucken Taste kann man nun den Bereich auswählen, von den man einen Screenshot erstellen möchte. Die Tastenkombination ALT + Drucken kopiert das gerade geöffnete Fenster. Mit dem Tastenkürzel STRG + Drucken wird, wie gewohnt, der ganze Bildschirm erfasst. Nachdem man]]></description>
			<content:encoded><![CDATA[<p>Jeder, der öfter mal Screenshots erstellen muss, kennt das Problem. Man muss auf die Drucken Taste drücken und dann die Zwischenablage in eine Grafikbearbeitungssoftware kopieren.</p>
<p>Je nach deren Qualität dauert es dann einige Arbeitsschritte, bis man das gewünschte Ergebnis hat.</p>
<p>Ich wurde vor kurzem auf das kostenlose Programm <a href="referrer.php?r=http://getgreenshot.org" target="_blank">Greenshot</a> hingewiesen, dass das Erstellen von Screenshots stark vereinfacht.</p>
<p>Drückt man die <em>Drucken</em> Taste kann man nun den Bereich auswählen, von den man einen Screenshot erstellen möchte.</p>
<p>Die Tastenkombination <em>ALT + Drucken</em> kopiert das gerade geöffnete Fenster.</p>
<p>Mit dem Tastenkürzel <em>STRG + Drucken</em> wird, wie gewohnt, der ganze Bildschirm erfasst. </p>
<p>Nachdem man einen Bereich, oder gleich den ganzen Bildschirminhalt aufgenommen hat, startet sich <a href="referrer.php?r=http://getgreenshot.org" target="_blank">Greenshot</a> von selber und man hat eine Palette von Werkzeugen, mit denen man die Aufnahme bearbeiten kann.</p>
<p>Die Benutzeroberfläche sieht folgendermaßen aus:<br />
<a href="http://www.ulrich-block.de/download/greenshot.jpg" target="_blank"><img src="http://www.ulrich-block.de/download/greenshot.jpg" alt="Greenshot" width="600"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/screenshots-erstellen-einfach-gemacht-mit-greenshot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shortcuts, die das Leben erleichtern</title>
		<link>http://www.ulrich-block.de/shortcuts-die-das-leben-erleichtern/</link>
		<comments>http://www.ulrich-block.de/shortcuts-die-das-leben-erleichtern/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 19:33:22 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[linux shell]]></category>
		<category><![CDATA[shortcuts]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1749</guid>
		<description><![CDATA[Wer viel auf der Linux Shell arbeitet, wird möchte bestimmte Eingaben beschleunigen. Besonders das Eingeben langer Pfade gehört zu den eher weniger spaßigen Angelegenheiten. Vielen unbekannt gibt es auf der Bash zahlreiche kleine Shortcuts, die einem das Leben einfacher machen. Bei Pfaden hat die Tabulator Taste eine Verfollständigungsfunktion. Hat man bereits z.B. /etc/pass eingetippt und drückt die Tabulator Taste, hat man automatisch /etc/passwd. Drückt man nacheinander &#8220;Escape&#8221; und &#8220;.&#8221; wird das letzte zusammenhängende Element eingefügt. Hat man z.B. vorher &#8220;touch /neuer/pfad/und/datei.txt&#8221; eingegeben kann man nun &#8220;/neuer/pfad/und/datei.txt&#8221; mit der Kombi aufrufen. Mit den Pfeiltasten &#8220;oben&#8221; und &#8220;unten&#8221; kann man die bisher]]></description>
			<content:encoded><![CDATA[<p>Wer viel auf der Linux Shell arbeitet, wird möchte bestimmte Eingaben beschleunigen. Besonders das Eingeben langer Pfade gehört zu den eher weniger spaßigen Angelegenheiten.</p>
<p>Vielen unbekannt gibt es auf der Bash zahlreiche kleine Shortcuts, die einem das Leben einfacher machen.</p>
<ul>
<li>Bei Pfaden hat die Tabulator Taste eine Verfollständigungsfunktion. Hat man bereits z.B. /etc/pass eingetippt und drückt die Tabulator Taste, hat man automatisch /etc/passwd.</li>
<li>Drückt man nacheinander &#8220;Escape&#8221; und &#8220;.&#8221; wird das letzte zusammenhängende Element eingefügt. Hat man z.B. vorher &#8220;touch /neuer/pfad/und/datei.txt&#8221; eingegeben kann man nun &#8220;/neuer/pfad/und/datei.txt&#8221; mit der Kombi aufrufen.</li>
<li>Mit den Pfeiltasten &#8220;oben&#8221; und &#8220;unten&#8221; kann man die bisher eingegebenen Befehle anzeigen lassen</li>
<li>An Stelle von &#8220;cd /home/MenUser&#8221; kann man nur &#8220;cd&#8221;, oder &#8220;cd ~&#8221; verwenden.</li>
</ul>
<p>Es gibt sicher noch viel mehr. Die oben genannten vereinfachen das alltägliche Arbeiten auf jeden Fall enorm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/shortcuts-die-das-leben-erleichtern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Das wars dann mit Adsense und Analytics</title>
		<link>http://www.ulrich-block.de/das-wars-dann-mit-adsense-und-analytics/</link>
		<comments>http://www.ulrich-block.de/das-wars-dann-mit-adsense-und-analytics/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 19:18:22 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1746</guid>
		<description><![CDATA[Wie einige von euch sicher mitbekommen haben, hat Google seine Datenschutzbestimmungen geändert. Ich habe es zum Anlass genommen, auf die Google Dienste Adsense und Analytics für diesen Blog zu verzichten. Zu diesem Schritt hatte ich mich schon früher entschlossen. Nur hatte ich bisher leider keine Zeit den Entschluss auch in die Tat umzusetzen.]]></description>
			<content:encoded><![CDATA[<p>Wie einige von euch sicher mitbekommen haben, hat <a href="referrer.php?r=http://google-produkte.blogspot.de/2012/01/aktualisierung-unserer.html" target="_blank">Google seine Datenschutzbestimmungen geändert</a>.</p>
<p>Ich habe es zum Anlass genommen, auf die Google Dienste Adsense und Analytics für diesen Blog zu verzichten.</p>
<p>Zu diesem Schritt hatte ich mich schon früher entschlossen. Nur hatte ich bisher leider keine Zeit den Entschluss auch in die Tat umzusetzen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/das-wars-dann-mit-adsense-und-analytics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Low Rater ein Problem?</title>
		<link>http://www.ulrich-block.de/low-rater-ein-problem/</link>
		<comments>http://www.ulrich-block.de/low-rater-ein-problem/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 11:28:56 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Counter-Strike]]></category>
		<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Counter-Strike: Source]]></category>
		<category><![CDATA[CS]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Day of Defeat]]></category>
		<category><![CDATA[Day of Defeat: Source]]></category>
		<category><![CDATA[Half-life 1]]></category>
		<category><![CDATA[Half-Life 2]]></category>
		<category><![CDATA[HL1]]></category>
		<category><![CDATA[HL2]]></category>
		<category><![CDATA[low rater]]></category>
		<category><![CDATA[orangebox]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1739</guid>
		<description><![CDATA[Es kommt immer mal wieder vor, dass sich Spieler über so genannte &#8220;Low Rater&#8221; beschweren. Der Gelegenheitsspieler versteht dann in aller Regel nicht einmal, was man von ihm will. Unter Low Ratern versteht man Spieler, die Netsettings verwenden, welche wenig Daten zum Server senden und empfangen. Bei HL1 und HL2 Spielen wie Counter-Strike 1.6 und Counter-Strike: Source werden die &#8220;Rates&#8221; mit folgenden Configeinträgen bestimmt: // Maximal benutzbare Bandbreite. Je Mehr Spieler auf dem Server und desto größer die cl_cmd- und cl_udpaterate Werte sind, desto mehr wird gebraucht. rate &#8220;25000&#8243; // Anzahl in der Sekunde, in der Daten von dir zum]]></description>
			<content:encoded><![CDATA[<p>Es kommt immer mal wieder vor, dass sich Spieler über so genannte &#8220;Low Rater&#8221; beschweren. Der Gelegenheitsspieler versteht dann in aller Regel nicht einmal, was man von ihm will.</p>
<p>Unter Low Ratern versteht man Spieler, die Netsettings verwenden, welche wenig Daten zum Server senden und empfangen. Bei HL1 und HL2 Spielen wie Counter-Strike 1.6 und Counter-Strike: Source werden die &#8220;Rates&#8221; mit folgenden Configeinträgen bestimmt:</p>
<blockquote><p>
// Maximal benutzbare Bandbreite. Je Mehr Spieler auf dem Server und desto größer die cl_cmd- und cl_udpaterate Werte sind, desto mehr wird gebraucht.<br />
rate &#8220;25000&#8243;</p>
<p>// Anzahl in der Sekunde, in der Daten von dir zum Server gesendet werden. Kann nicht größer als die erreichten FPS sein.<br />
cl_cmdrate &#8220;66&#8243;</p>
<p>// Anzahl in der Sekunde, in der Daten vom Server zu dir gesendet werden. Man sollte aufpassen, dass hier keine zu große Abweichung zu cl_cmdrate entsteht.<br />
cl_updaterate &#8220;66&#8243;</p>
<p>// So viele (0.01=10ms) werden die Hitboxes nach hinten versetzt, um den Ping auszugleichen. Bei einem hohen Ping sollte man einen höheren Wert nehmen.<br />
// Als Startwert kann man den durchschnittlichen Scoreboard Ping nehmen. Danach so weit herabsetzen, bis man merkt, das dieHitboxen nicht mehr passen.<br />
cl_interp &#8220;0.01&#8243;
</p></blockquote>
<p>Die Standardwerte von Valve sind deutlich geringer, als die im Beispiel verwendeten. </p>
<p>Es hält sich nun hartnäckig das Gerücht, dass man Spieler mit diesen Einstellungen schlechter treffen kann. Für HL1 Spiele, wie Counter-Strike 1.6 trifft dies bedingt zu. Bei HL2 Spielen wie Counter-Strike: Source ist der Netzwerkcode deutlich robuster, so dass bei mir der Eindruck entstanden ist, dass die Netsettings anderer eine unbedeutenderer Rolle spielen.</p>
<p>Man kann sich nun entweder über Spieler mit wenig technischen Kenntnissen aufregen, oder als Admin aktiv werden.<br />
Sowohl HL1, als auch HL2 basierenden Servern bieten die Möglichkeit, die zulässigen Grenzwerte für die Netsettings einzuschränken. Verbindet ein Spieler mit Netsettings außerhalb dieser Grenzen auf den Server, wird sein Spiel den zulässigen Grenzwert verwenden.</p>
<p>Die Grenzen werden folgendermaßen in der server.cfg bestimmt:</p>
<blockquote><p>
// Minimale Bandbreite 0=unlimited<br />
sv_minrate &#8220;15000&#8243;</p>
<p>// Maximale Bandbreite 0=unlimited<br />
sv_maxrate &#8220;100000&#8243;</p>
<p>// Minimum Updates pro Sekunde zum Client<br />
sv_minupdaterate &#8220;40&#8243;</p>
<p>// Maximum Updates pro Sekunde zum Client<br />
sv_maxupdaterate &#8220;66&#8243;</p>
<p>// Minimum Updates vom Client pro Sekunde<br />
sv_mincmdrate &#8220;40&#8243;</p>
<p>// Maximum Updates vom Client pro Sekunde<br />
sv_maxcmdrate &#8220;66&#8243;
</p></blockquote>
<p>Beim Erzwingen werden die Grenzen nur angewendet. Die Config des Spielers wird <strong>nicht</strong> überschrieben. Aus diesem Grund sind Plugins, die die Netsettings der Spieler überprüfen überflüssig und schaden eventuell sogar der Community auf dem Server. Schaden können sie , weil schlechte Verlierer nun die Configwerte der Spieler anschauen können. Die Schuld für das Verlieren wird auf die angeblichen &#8220;Low Rates&#8221; geschoben und entsprechend geschimpft. Dies natürlich auch dann, wenn der beschimpfte Spieler vom Server gezwungen wird, andere Werte zu verwenden, die alles andere als &#8220;Low&#8221; sind.</p>
<p>Manch ein Admin wird nun auf die Idee kommen, den maximal zulässigen Wert auch als minimalen Wert zu verwenden, damit jeder mit den Werten 100/100, oder 66/66 spielt.<br />
Dies ist keine gute Idee. Es gibt viele Spieler, die mit alter Hardware und oder Laptops spielen. Diese erreichen nur niedrige Frameraten (FPS). Ein Spieler kann nur so viele Updates in der Sekunde senden, wie er FPS hat. Weicht die effektiv gesendete <em>cmdrate</em> nun zu stark von der eingestellten <em>updaterate</em> ab, trifft man den Spieler in der Regel sogar schlechter, als einen, der etwas niedrigere Rates verwendet.<br />
Der bessere und benutzerfreundlichere Weg ist somit ein minimaler Wert von 40-50.</p>
<p>Zwingt man die Spieler Netsettings innerhalb dieser Grenzen zu benutzen, ist schlechtes Treffen nicht mehr den Configeinstellungen geschuldet. Die Aussage, man treffe einen anderen wegen seinen &#8220;Low Rates&#8221; nicht ist demnach nur noch eine Ausrede für eigenes Unvermögen.</p>
<p>Mit wenigen Handgriffen sind &#8220;Low Rater&#8221; kein Problem für den Spielablauf.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/low-rater-ein-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Die Steam Web API und Updates</title>
		<link>http://www.ulrich-block.de/die-steam-web-api-und-updates/</link>
		<comments>http://www.ulrich-block.de/die-steam-web-api-und-updates/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:57:46 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[steam]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Autoupdate]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1733</guid>
		<description><![CDATA[Von vielen unbemerkt hat Valve schon seit einiger Zeit eine umfangreiche Steam Web API bereitgestellt. Die Dokumentation ist leider nicht sehr vollständig und in der Valve Developer WIKI zu finden. Die Anfrage an die API wird mittels GET Parametern gemacht. Die Antwort kann in den Formaten XML, JSON und VDF ausgegeben werden. Ein für Serveroperatoren sehr interessanter Teil ist leider nicht dokumentiert. Mittels der Valve Developer WIKI kann man zu SteamApps Versionsnummern mit der aktuellen abgleichen lassen. Im Fall von Counter-Strike: Source würde eine Abfrage mit XML folgendermaßen aussehen: https://api.steampowered.com/ISteamApps/UpToDateCheck/v0001/?appid=240&#38;version=1.0.0.69&#38;format=xml Die aktuelle Version ist 1.0.0.70. Deswegen ist die XML Antwort:]]></description>
			<content:encoded><![CDATA[<p>Von vielen unbemerkt hat Valve schon seit einiger Zeit eine umfangreiche Steam Web API bereitgestellt. Die Dokumentation ist leider nicht sehr vollständig und in der <a href="referrer.php?r=https://developer.valvesoftware.com/wiki/Steam_Web_API" target="_blank">Valve Developer WIKI</a> zu finden.</p>
<p>Die Anfrage an die API wird mittels GET Parametern gemacht. Die Antwort kann in den Formaten XML, JSON und VDF ausgegeben werden.</p>
<p>Ein für Serveroperatoren sehr interessanter Teil ist leider nicht dokumentiert. Mittels der Valve Developer WIKI kann man zu SteamApps Versionsnummern mit der aktuellen abgleichen lassen. Im Fall von Counter-Strike: Source würde eine Abfrage mit XML folgendermaßen aussehen:</p>
<blockquote><p>https://api.steampowered.com/ISteamApps/UpToDateCheck/v0001/?appid=240&amp;version=1.0.0.69&amp;format=xml</p></blockquote>
<p>Die aktuelle Version ist 1.0.0.70. Deswegen ist die XML Antwort:</p>
<pre class="brush:xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE response&gt;
&lt;response&gt;
	&lt;success&gt;true&lt;/success&gt;
	&lt;up_to_date&gt;false&lt;/up_to_date&gt;
	&lt;version_is_listable&gt;false&lt;/version_is_listable&gt;
	&lt;required_version&gt;10070&lt;/required_version&gt;
	&lt;message&gt;Your server is out of date, please upgrade&lt;/message&gt;
&lt;/response&gt;
</pre>
<p>Fragt man mit einer aktuellen Version nach:</p>
<pre class="brush:xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE response&gt;
&lt;response&gt;
	&lt;success&gt;true&lt;/success&gt;
	&lt;up_to_date&gt;true&lt;/up_to_date&gt;
	&lt;version_is_listable&gt;true&lt;/version_is_listable&gt;
&lt;/response&gt;
</pre>
<p>Mittels der API kann man  sich also relativ einfach ein Script schreiben, dass die lokale Serverversion mit der aktuellen abgleicht. Im Folgenden wird dann je nach Output reagiert. Wenn &#8220;up_to_date&#8221; &#8220;False&#8221; ist, kann z.B. ein Update gestartet werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/die-steam-web-api-und-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vserver, Rootserver und dedizierte Server Nr.2</title>
		<link>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/</link>
		<comments>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 12:51:45 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[dedizierte Server]]></category>
		<category><![CDATA[Rootserver]]></category>
		<category><![CDATA[Vserver]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1728</guid>
		<description><![CDATA[In einem früheren Beitrag hatte ich den Unterschiede zwischen Vserver, Rootserver und dediziertem Server beschrieben. Dort bin ich auch auf Möglichkeiten eingegangen, wie man ein System auf der Konsole als Vserver identifizieren kann. Eine sehr einfach Möglichkeit hatte ich vergessen. Mit dem Programm dmidecode kann man die Hardwareinformationen seines Servers auslesen. Manchen Images enthalten es bereits. Bei anderen muss es noch installiert werden. Die interessanteste Ausgabe ist die des Systemherstellers. Der Befehl dazu lautet: dmidecode -s system-manufacturer Auf einem mit VMWare virtualisiertem System ist die Ausgabe: dmidecode -s system-manufacturer VMware, Inc. Bei Virtuozzo hingegen ist ein Zugriff auf diese Informationen]]></description>
			<content:encoded><![CDATA[<p>In einem <a href="http://www.ulrich-block.de/vserver-rootserver-dedizierte-server-und-schwarze-schafe/" target="_blank">früheren Beitrag</a> hatte ich den Unterschiede zwischen Vserver, Rootserver und dediziertem Server beschrieben. Dort bin ich auch auf Möglichkeiten eingegangen, wie man ein System auf der Konsole als Vserver identifizieren kann.</p>
<p>Eine sehr einfach Möglichkeit hatte ich vergessen. Mit dem Programm <strong>dmidecode</strong> kann man die Hardwareinformationen seines Servers auslesen. Manchen Images enthalten es bereits. Bei anderen muss es noch installiert werden.</p>
<p>Die interessanteste Ausgabe ist die des Systemherstellers. Der Befehl dazu lautet:</p>
<blockquote><p>dmidecode -s system-manufacturer</p></blockquote>
<p>Auf einem mit VMWare virtualisiertem System ist die Ausgabe:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
VMware, Inc.
</p></blockquote>
<p>Bei Virtuozzo hingegen ist ein Zugriff auf diese Informationen gar nicht erst möglich:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
/dev/mem: Permission denied
</p></blockquote>
<p>Auf einem dedizierten Server von Fujitsu ist die Ausgabe:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
FUJITSU
</p></blockquote>
<p>Auch MSI Mainboads melden sich entsprechend:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
MSI
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Steam-Service wird installiert</title>
		<link>http://www.ulrich-block.de/steam-service-wird-installiert/</link>
		<comments>http://www.ulrich-block.de/steam-service-wird-installiert/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 11:12:54 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Steam]]></category>
		<category><![CDATA[Installieren]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[steam]]></category>
		<category><![CDATA[Steam-Service]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1720</guid>
		<description><![CDATA[Beim Straten von Steam begrüßte mich heute folgende Meldung: Steam-Service wird installiert Zum korrekten Ausführen von Steam mit dieser Version von Windows muss die Steam-Service-Komponente innstaliert sein. Für die Installation der Service-Komponente sind Administratoren-Zugriffsrechte erforderlich. SERVICE INSTALLIEREN ABBRECHEN Ich war erstmal reichlich verwundert, zumal Steam dies bisher nicht getan hatte. Bevor ich auf den Button &#8220;SERVICE INSTALLIEREN&#8221; klicke, wollte ich erst einmal wissen, ob dieses Fenster überhaupt zu Steam gehört, oder mir etwas untergeschoben worden ist. Mein Nutzerverhalten kann man zwar als vorsichtig bezeichnen, dennoch kann man nie wissen, was man sich trotzdem eingefangen haben könnte. Eine Google Suche brachte]]></description>
			<content:encoded><![CDATA[<p>Beim Straten von Steam begrüßte mich heute folgende Meldung:</p>
<blockquote><p>Steam-Service wird installiert</p>
<p>Zum korrekten Ausführen von Steam mit dieser Version von Windows muss die Steam-Service-Komponente innstaliert sein.<br />
Für die Installation der Service-Komponente sind Administratoren-Zugriffsrechte erforderlich.</p>
<p>SERVICE INSTALLIEREN		ABBRECHEN</p></blockquote>
<p>Ich war erstmal reichlich verwundert, zumal Steam dies bisher nicht getan hatte. Bevor ich auf den Button <em>&#8220;SERVICE INSTALLIEREN&#8221;</em> klicke, wollte ich erst einmal wissen, ob dieses Fenster überhaupt zu Steam gehört, oder mir etwas untergeschoben worden ist. Mein Nutzerverhalten kann man zwar als vorsichtig bezeichnen, dennoch kann man nie wissen, was man sich trotzdem eingefangen haben könnte.</p>
<p>Eine Google Suche brachte nichts 100% konkretes zu Tage. Man konnte aber sehen, dass die Nachricht von Valve bzw. Steam kommt. Damit war meine erste Befürchtung, dass mein System kompromittiert ist, zum Glück falsch.</p>
<p>Tendentiell ist es wohl ein Problem mit der Rechteverwaltung des Windowsusers. Steam benötigt für die Installation eines Updates wohl Adminsitratorrechte. Bei der Autoerkennung dieser Rechte muss ein Problem bestehen, so dass der Updater nicht direkt gestartet werden kann.</p>
<p>Ich entschied mich dafür, den <em>&#8220;SERVICE INSTALLIEREN&#8221;</em> Button zu betätigen. Die Windows Administrator Warnung erschien. Sie bestätigte mir, dass die Anwendung von Valve kommt und als solche verifiziert ist.<br />
Nachdem ich Windows erlaubt hatte, das Programm auszuführen, wurde der Updater gestartet. Im Anschluss startete Steam ohne weitere Probleme.</p>
<p>Mein Fazit:<br />
Lieber einmal zu vorsichtig sein, als irgendwann das Nachsehen zu haben.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/steam-service-wird-installiert/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Neues aus dem Maschinenraum</title>
		<link>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/</link>
		<comments>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 10:05:07 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[easy-wi.com]]></category>
		<category><![CDATA[Webinterface]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[Gameserver]]></category>
		<category><![CDATA[MYSQL]]></category>
		<category><![CDATA[Neuerungen]]></category>
		<category><![CDATA[panel]]></category>
		<category><![CDATA[Update]]></category>
		<category><![CDATA[voiceserver]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1712</guid>
		<description><![CDATA[Ich möchte einen kleinen Einblick auf die kommende Version meines Webinterfaces Easy-Wi geben. Es wird zwei wesentliche Neuerungen geben. Zum einen arbeite ich gerade mit Hochdruck an einem CMS. Heutzutage selbstverständliche Funktionen, wie Rewrite Urls und Mehrsprachigkeit, werden selbstverständlich unterstützt. Setzt man Rewrite Urls ein, kann man Links wie domain.tld/de/Leihserver/, oder domain.tld/uk/Lendserver/Gameserver/ benutzen. Keywords können je Artikel oder Seite gesetzt werden. Seiten, wie die Verleih- und Protectionmodeseite, die bereits losgelöst vom CMS bestanden haben, sind ebenfalls mit von der Partie. Die zweite Neuerung ist das Layout der Adminoberfläche. Die Menüführung wurde komplett überarbeitet und sollte die Arbeitsabläufe beschleunigen. Beim Hover]]></description>
			<content:encoded><![CDATA[<p>Ich möchte einen kleinen Einblick auf die kommende Version meines Webinterfaces <a href="http://easy-wi.com" target="_blank">Easy-Wi</a> geben. Es wird zwei wesentliche Neuerungen geben.</p>
<p>Zum einen arbeite ich gerade mit Hochdruck an einem CMS. Heutzutage selbstverständliche Funktionen, wie Rewrite Urls und Mehrsprachigkeit, werden selbstverständlich unterstützt. Setzt man Rewrite Urls ein, kann man Links wie <em>domain.tld/de/Leihserver</em>/, oder <em>domain.tld/uk/Lendserver/Gameserver/</em> benutzen.<br />
Keywords können je Artikel oder Seite gesetzt werden.<br />
Seiten, wie die Verleih- und Protectionmodeseite, die bereits losgelöst vom CMS bestanden haben, sind ebenfalls mit von der Partie.</p>
<p>Die zweite Neuerung ist das Layout der Adminoberfläche. Die Menüführung wurde komplett überarbeitet und sollte die Arbeitsabläufe beschleunigen.</p>
<p>Beim Hover über das Menü wird das jeweilige Untermenü eingeblendet. Sobald man in einem Unterbereich arbeitet, wird die Subnavi zu diesem Bereich, die vorher nur über Hover erreichbar war, unterhalb der Überschrift des Bereiches aufgeklappt und permanent angezeigt. Sobald man den Bereich wieder verlässt, wird das zugehörige Untermenü wieder ausgeblendet.<br />
Durch die neue Struktur kann ich wesentlich mehr Menüelemente einbauen, ohne dass es unübersichtlich wird.</p>
<p>Des Weiteren gibt es nun Rechts eine Übersicht, die bei Events, also Anzahl der Einträge größer als 0, farblich hervorgehoben wird. Es wird demnach beim Arbeiten sofort farblich ins Auge stechen, wenn man sich um etwas kümmern sollte.</p>
<p>Insgesamt habe ich versucht, durch Schattenwürfe, Trennlinien und Farbverläufe das Layout etwas aufzulockern.</p>
<p>Der derzeitige WIP Status sieht folgendermaßen aus:<br />
<a href="http://www.ulrich-block.de/wp-content/uploads/2012/01/easy-wi-preview.jpg" target="_blank"><img src="http://www.ulrich-block.de/wp-content/uploads/2012/01/easy-wi-preview-300x262.jpg" alt="" title="easy-wi-preview" width="300" height="262" class="alignleft size-medium wp-image-1715" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spammer, Webspell und Stopforumspam.com</title>
		<link>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/</link>
		<comments>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 14:01:35 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Spam]]></category>
		<category><![CDATA[stopforumspam.com]]></category>
		<category><![CDATA[Webspell]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1698</guid>
		<description><![CDATA[Das CMS Webspell hat, wie so ziemlich jedes andere CMS auch, mit Spammern zu kämpfen. Der Clan myRevenge e.V. setzt Webspell ein und hat mich um Hilfe mit ihrem Spam Problem gebeten. Trotz Captcha und Bestätigungslink schaffen es Spammer immer wieder sich anzumelden oder als Gast zu spammen. Nach einer erfolgreichen Anmeldung wird im zweiten Schritt auch in Bereichen gespmamt, in denen Gäste keine Schreibrechte haben. Um den Spam einzudämmen, bietet sich eine Überprüfung an, wer so schreibt. Dabei macht man sich zu Nutze, dass Spammer wiederkehrende E-Mail Adressen und Usernamen verwenden. Im ersten Schritt werden unerwünschte Top Level Domains]]></description>
			<content:encoded><![CDATA[<p>Das CMS <a href="referrer.php?r=http://www.webspell.org" target="_blank">Webspell</a> hat, wie so ziemlich jedes andere CMS auch, mit Spammern zu kämpfen. Der Clan <a href="referrer.php?r=http://www.myrevenge.net" target="_blank">myRevenge e.V.</a> setzt Webspell ein und hat mich um Hilfe mit ihrem Spam Problem gebeten. Trotz Captcha und Bestätigungslink schaffen es Spammer immer wieder sich anzumelden oder als Gast zu spammen. Nach einer erfolgreichen Anmeldung wird im zweiten Schritt auch in Bereichen gespmamt, in denen Gäste keine Schreibrechte haben.</p>
<p>Um den Spam einzudämmen, bietet sich eine Überprüfung an, wer so schreibt. Dabei macht man sich zu Nutze, dass Spammer wiederkehrende E-Mail Adressen und Usernamen verwenden.</p>
<p>Im ersten Schritt werden unerwünschte Top Level Domains und Domainendungen in 2 Arrays übergeben und überprüft, ob die verwendete E-Mail einen dieser Kriterien entspricht. Weil Spammer sehr flexibel sind, stellt diese Maßnahme lediglich einen Tropfen auf den heißen Stein dar.</p>
<p>Wesentlich effizienter ist der zweite Schritt. Hier wird die API von <a href="referrer.php?r=http://stopforumspam.com" target="_blank">stopforumspam.com</a> kontaktiert und gefragt, ob Name, oder E-Mail bereits als Spammer bekannt sind. Stopforumspam.com ist eine Seite, die bekannte Spammer sammelt und nicht kommerziellen Nutzern eine API zu der Datenbank anbietet.<br />
Nur wenn die API antwortet, dass der Datensatz unbekannt ist, darf der User sich anmelden, bzw. einen Kommentar schreiben.</p>
<p>Die beschriebenen Ergänzungen werden in den Dateien register.php und comments.php vorgenommen.<br />
<span id="more-1698"></span><br />
Die Erweiterung der register.php:</p>
<pre class="brush:php">
// check e-mail
if(!validate_email($mail)) {
	$error[]=$_language-&gt;module['invalid_mail'];
} else {
	// Liste mit unzulaessigen Maildomains
	$badmaildomains=array('willich.nicht','auchnicht.de');
	// Liste mit unzulaessigen TLs array('cn','xxx')
	$badtld=array();
	// Useraccount von Domain trennen
	list($user,$domain)=explode('@',$mail);
	// Top Level herausfinden
	$domain_explode=explode('.',$domain);
	$last_array_entry=count($domain_explode)-1;
	// Überpruefen, ob die Domain geblacklisted ist
	if (in_array($domain,$badmaildomains) or in_array($domain_explode[$last_array_entry],$badtld)) {
		$error[]=$_language-&gt;module['invalid_mail'];
	} else {
		// Stopforumspam kontaktieren:
		$opts=stream_context_create(array('http'=&gt;array('method'=&gt;'GET','header'=&gt;"Accept-language: en\r\nUser-Agent: ".$_SERVER['HTTP_HOST']."\r\n")));
		$contact_stopforumspam=@file_get_contents('http://www.stopforumspam.com/api?email[]='.urlencode($mail).'&amp;username[]='.urlencode($username).'&amp;username[]='.urlencode($nickname),false,$opts);
		if($contact_stopforumspam!=false) {
			$xmlreply = simplexml_load_string($contact_stopforumspam);
			foreach ($xmlreply as $xml_key =&gt; $xmlcheck) {
				// Wenn der Spammer in der Datenbank erfasst ist, feststellen, ob die Mail und oder der Username bekannt war und einen entsprechenden Fehler ausgeben
				if ($xmlcheck-&gt;appears==1) {
					if ($xml_key=='email') {
						$error[]=$_language-&gt;module['invalid_mail'];
					} else if ($xml_key=='username') {
						$error[]=$_language-&gt;module['nickname_inuse'];
					}
				}
			}
		}
	}
}
</pre>
<p>Und die Änderung in der comments.php:</p>
<pre class="brush:php">
function IsNoSpammer ($mail,$username,$useragent) {
	$nospammer=true;
	// Liste mit unzulaessigen Maildomains
	$badmaildomains=array('willich.nicht','auchnicht.de');
	// Liste mit unzulaessigen TLs array('cn','xxx')
	$badtld=array();
	// Useraccount von Domain trennen
	list($user,$domain)=explode('@',$mail);
	// Top Level herausfinden
	$domain_explode=explode('.',$domain);
	$last_array_entry=count($domain_explode)-1;
	// Überpruefen, ob die Domain geblacklisted ist
	if (in_array($domain,$badmaildomains) or in_array($domain_explode[$last_array_entry],$badtld)) {
		$nospammer=false;
	}
	$opts=stream_context_create(array('http'=&gt;array('method'=&gt;'GET','header'=&gt;"Accept-language: en\r\nUser-Agent: ".$useragent."\r\n")));
	$contact_stopforumspam=@file_get_contents('http://www.stopforumspam.com/api?email[]='.urlencode($mail).'&amp;username[]='.urlencode($username),false,$opts);
	if($contact_stopforumspam!=false) {
		$xmlreply = simplexml_load_string($contact_stopforumspam);
		foreach ($xmlreply as $xml_key =&gt; $xmlcheck) {
			// Wenn der Spammer in der Datenbank erfasst ist, $nospammer auf false setzen
			if ($xmlcheck-&gt;appears==1) {
				$nospammer=false;
			}
		}
	}
	return $nospammer;
}
if (IsNoSpammer($mail,$name,$_SERVER['HTTP_HOST'])==true) {
	// hier den DB Eintrag vornehmen.
} else {
	die();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>2-Klick-Empfehlungsbutton</title>
		<link>http://www.ulrich-block.de/2-klick-empfehlungsbutton/</link>
		<comments>http://www.ulrich-block.de/2-klick-empfehlungsbutton/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 01:57:00 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[2 klick]]></category>
		<category><![CDATA[Empfehlungsbutton]]></category>
		<category><![CDATA[social media]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1687</guid>
		<description><![CDATA[In den Nachrichten und Kommentaren wird das Thema Datenschutz im Zusammenhang mit Social Media schon länger diskutiert. Trotz mancher Bedenken möchte man aus verschiedenen Gründen Social Media Buttons einfügen. Als die Diskussion aufflammte hat heise.de eine 2-Klick Lösung entwickelt, um Social Media Buttons mit dem Datenschutz unter einen Hut zu bringen. Bei dieser Methode wird erst nach ausdrücklicher Aufforderung durch den Benutzer der externe Code von Facebook und Co. angefordert und eingebunden. Wegen der großen Nachfrage wurde der Code zu der 2-Klick Lösung unter der MIT Lizenz veröffentlicht. Diese 2-Klick Lösung habe ich in meinem Blog eingebaut. Sie kann von]]></description>
			<content:encoded><![CDATA[<p>In den Nachrichten und Kommentaren wird das Thema Datenschutz im Zusammenhang mit Social Media schon länger diskutiert.<br />
Trotz mancher Bedenken möchte man aus verschiedenen Gründen Social Media Buttons einfügen.</p>
<p>Als die Diskussion aufflammte hat <a href="referrer.php?r=http://www.heise.de/newsticker/meldung/Code-fuer-2-Klick-Empfehlungsbutton-von-Heise-ist-erhaeltlich-1337833.html" target="_blank">heise.de eine 2-Klick Lösung</a> entwickelt, um Social Media Buttons mit dem Datenschutz unter einen Hut zu bringen. Bei dieser Methode wird erst nach ausdrücklicher Aufforderung durch den Benutzer der externe Code von Facebook und Co. angefordert und eingebunden.</p>
<p>Wegen der großen Nachfrage wurde der Code zu der 2-Klick Lösung unter der <a href="refferrer.php?r=http://www.opensource.org/licenses/mit-license.php" target="_blank">MIT Lizenz</a> veröffentlicht.</p>
<p>Diese 2-Klick Lösung habe ich in meinem Blog eingebaut. Sie kann von nun an beim Aufruf der einzelnen Beiträge am Ende genutzt werden.</p>
<p>Nachtrag:<br />
Ich habe die Einbindung erweitert. Nun kann man die Buttons auch in der Übersicht benutzen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/2-klick-empfehlungsbutton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Umstellung der Textausrichtung</title>
		<link>http://www.ulrich-block.de/umstellung-der-textausrichtung/</link>
		<comments>http://www.ulrich-block.de/umstellung-der-textausrichtung/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 11:06:22 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1684</guid>
		<description><![CDATA[Ich habe gerade die Textausrichtung des Blogs von Linksbündig auf Blocksatz umgeändert. Dazu musste ich im Stylesheet lediglich die Einstellungen zu den einzelnen Posts um die Angabe &#8220;text-align:justify;&#8221; erweitern. Ich hoffe, dass diese Änderung die Texte etwas lesbarer machen wird.]]></description>
			<content:encoded><![CDATA[<p>Ich habe gerade die Textausrichtung des Blogs von Linksbündig auf Blocksatz umgeändert. Dazu musste ich im Stylesheet lediglich die Einstellungen zu den einzelnen Posts um die Angabe <em>&#8220;text-align:justify;&#8221;</em> erweitern.</p>
<p>Ich hoffe, dass diese Änderung die Texte etwas lesbarer machen wird.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/umstellung-der-textausrichtung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS Layout: Header, 3 Reihen (Fixed-Fluid-Fixed), Footer</title>
		<link>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/</link>
		<comments>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 11:00:52 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[3 columns]]></category>
		<category><![CDATA[dynamisch]]></category>
		<category><![CDATA[fest]]></category>
		<category><![CDATA[fixed]]></category>
		<category><![CDATA[fluid]]></category>
		<category><![CDATA[footer]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[reihen]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1673</guid>
		<description><![CDATA[Ein 3 Spalten Layout, dass einen Header und Footer hat, kann man mit HTML und CSS auf unterschiedliche Weise gestalten. Die beiden meist genutzten Varianten sollten Divs und Tabellen sein. Mit Tabellen ist die gleichmäßige Höhen- und Breitengestaltung sehr einfach. Die Höhe und Breite aller Spalten richtet sich an den Maximalwerten der anderen Elemente aus. Eine einfache Tabelle sieht so aus: &#60;table&#62;     &#60;tr&#62;         &#60;td colspan="3"&#62;Header&#60;/td&#62;     &#60;/tr&#62;     &#60;tr&#62;         &#60;td&#62;Linkes Menu&#60;/td&#62;         &#60;td&#62;Inhalt&#60;/td&#62;         &#60;td&#62;Rechtes Menu&#60;/td&#62;     &#60;/tr&#62;     &#60;tr&#62;        &#60;td colspan="3"&#62;Footer&#60;/td&#62;     &#60;/tr&#62; &#60;/table&#62; Der Einsatz von Tabellen zu diesem]]></description>
			<content:encoded><![CDATA[<p>Ein 3 Spalten Layout, dass einen Header und Footer hat, kann man mit HTML und CSS auf unterschiedliche Weise gestalten. Die beiden meist genutzten Varianten sollten Divs und Tabellen sein.</p>
<p>Mit Tabellen ist die gleichmäßige Höhen- und Breitengestaltung sehr einfach. Die Höhe und Breite aller Spalten richtet sich an den Maximalwerten der anderen Elemente aus. Eine einfache Tabelle sieht so aus:</p>
<pre class="brush:html">
&lt;table&gt;
    &lt;tr&gt;
        &lt;td colspan="3"&gt;Header&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Linkes Menu&lt;/td&gt;
        &lt;td&gt;Inhalt&lt;/td&gt;
        &lt;td&gt;Rechtes Menu&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
       &lt;td colspan="3"&gt;Footer&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>Der Einsatz von Tabellen zu diesem Zweck gilt aber als veraltet und damit nicht mehr zeitgemäß.</p>
<p>Zur Zeit verwendet man für die Layout Gestaltung überwiegend Divs. Dabei schreibt man die Positionsangaben zum DIV nicht in selbiges hinein, sondern weist diesem eine ID und oder Klasse zu. Die Eigenschaften der IDs und Klassen definiert man dann in einer extra <em>*.css</em> Datei.</p>
<p>Wenn man feste mit flexiblen Breiten- und Höhenangaben vermischt, wird man bei Divs auf Hürden und Hindernisse treffen.</p>
<p>Wenn man z.B. möchte, dass die Höhe des Layouts immer minimal 100% der Höhe des Browserfensters beträgt, umfasst man das eigentliche Layout mit einem Div. Dieses Div macht man dann zu einem Wrapper. In den Eigenschaften wird dann bestimmt, dass der Wrapper immer mindestens 100% der Seitenhöhe belegen soll. Die Divs, die das eigentliche Aussehen bestimmen sollen, werden in diesem Wrapper positioniert.</p>
<p>Bei einem Layout mit drei Spalten kann man diese mittels Float ausrichten. Bei dem Linken und Mittleren setzt man <em><strong>&#8220;float:left;&#8221;</strong></em>. Beim Rechten <em><strong>&#8220;float:right;&#8221;</strong></em>.<br />
Ist die Höhe der Divs ein fester Wert, bekommt man keine Probleme. Soll aber zumindest eine Höhe flexibel sein, werden alle drei eine, an ihrem Inhalt bestimmte, unterschiedliche Höhe erhalten. Möchte man unterschiedliche Hintergründe verwenden, kann das Endergebnis sehr unsymmetrisch aussehen.</p>
<p>Eine Alternative ist es, die Position der 3 Spalten absolut (<em>&#8220;position:absolute;&#8221;</em>) zu bestimmen. Im Folgenden definiert man dann den Abstand der rechten und linken Spalte zum Rand mit 0. Die mittleren Spalte wird mit Margin nach Links und Rechts ausgerichtet. Als Werte für die Margin Angabe nimmt man die Spaltenbreite der äußeren beiden Spalten.<br />
Im Ergebnis hat man 3 Spalten, bei denen für die beiden äußeren feste Pixelwerte verwendet werden können. Die Mittlere Spalte wird immer die restliche Breite für sich in Anspruch nehmen, egal wie Breit das Browserfenster des Users gerade ist.</p>
<p>Definiert man nun die minimale Höhe aller drei Spalten mit 100%, werden durch diese Höhenangabe alle Spalten gleichmäßig bis zum Ende des Wrappers getreckt.</p>
<p>Die farbliche Gestaltung der einzelnen Divs erfolgt ebenfalls mittels CSS. Im Beispiel habe ich die Farben Grün <strong>#0F0</strong>, Rot <strong>#0F0</strong> und Blau <strong>#00F</strong> verwendet. Die Farben passen so sicher nicht zusammen und beißen sicher etwas in den Augen. Ich habe sie dennoch gewählt, um mittels des Kontrastes die gleichmäßige Höhe der Spalten besser darstellen zu können.</p>
<p>Eine Beispielseite, die den nachfolgenden Code verwendet, kann man hier ansehen: <a href="http://www.ulrich-block.de/download/3cols.html" target="_blank">3cols.html</a></p>
<p>Die CSS Angaben:<br />
<span id="more-1673"></span></p>
<pre class="brush:css">
html,body {
	margin:0;
	height:100%;
	font-size:12px;
	font-family:"HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
}
#header{
	position:relative;
	z-index:100;
	width:100%;
	height:30px;
	line-height:30px;
	text-align:center;
	font-size:14px;
	background-color:#3D3D3D;
	color:#CCCCCC;
}
#wrapper {
	position:relative;
	min-height:97%;
	height:auto !important;
	height:97%;
	overflow:hidden;
}
#menuleft {
	position:absolute;
	z-index:50;
	top:0px;
	left:0px;
	width:140px;
	height:100%;
	background-color:#0F0;
}
#datapage {
	position:absolute;
	z-index:1;
	height:100%;
	margin:0 140px 0 140px;
	background-color:#F00;
}
#menuright {
	position:absolute;
	z-index:50;
	top:0px;
	right:0px;
	width:140px;
	height:100%;
	background-color:#00F;
}
#footer{
	position:absolute;
	z-index:100;
	bottom:0px;
	width:100%;
	height:30px;
	line-height:30px;
	background-color:#3D3D3D;
	text-align:center;
	font-size:14px;
	color:#CCCCCC;
}
</pre>
<p>Der HTML Code, der diese CSS Angaben verwendet:</p>
<pre class="brush:html">
&lt;body&gt;
	&lt;div id="header"&gt;
		Header
	&lt;/div&gt;
	&lt;div id="wrapper"&gt;
		&lt;div id="menuleft"&gt;
			Linkes Menu
		&lt;/div&gt;
		&lt;div id="datapage"&gt;
			Inhalt
		&lt;/div&gt;
		&lt;div id="menuright"&gt;
			Rechtes Menu
		&lt;/div&gt;
		&lt;div id="footer"&gt;
			Footer
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mit PHP nach Inhalten in bestimmten Dateitypen suchen</title>
		<link>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/</link>
		<comments>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 15:39:38 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dateien]]></category>
		<category><![CDATA[Inhalt durchsuchen]]></category>
		<category><![CDATA[rekursiv]]></category>
		<category><![CDATA[Webspace]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1654</guid>
		<description><![CDATA[Ich wurde heute von jemanden angeschrieben, bei dem über einen Exploit eine umfangreiche PHP Shell eingeschleust wurde. Das Einfallstor war ein Uploadskript, welches eigentlich für Zip Archive gedacht war. Dieses Skript hat leider nicht geschaut, was wirklich hochgeladen wird. Dank strenger Chmods war der PHP User sehr eingeschränkt. Durch den Einsatz von disable_functions in der php.ini war es dem PHP User weder möglich, Systembefehle auszuführen, noch Sockets zu öffnen. Aus diesem Grund konnte nur Schaden bei der betroffenen Webseite selber angerichtet werden. Es war zum Beispiel möglich sämtliche Dateien auszulesen und zu manipuliert. Des Weiteren ist es sehr wahrscheinlich, dass]]></description>
			<content:encoded><![CDATA[<p>Ich wurde heute von jemanden angeschrieben, bei dem über einen Exploit eine umfangreiche PHP Shell eingeschleust wurde. Das Einfallstor war ein Uploadskript, welches eigentlich für Zip Archive gedacht war. Dieses Skript hat leider nicht geschaut, was wirklich hochgeladen wird.</p>
<p>Dank strenger Chmods war der PHP User sehr eingeschränkt. Durch den Einsatz von disable_functions in der php.ini war es dem PHP User weder möglich, Systembefehle auszuführen, noch Sockets zu öffnen. Aus diesem Grund konnte nur Schaden bei der betroffenen Webseite selber angerichtet werden. Es war zum Beispiel möglich sämtliche Dateien auszulesen und zu manipuliert. Des Weiteren ist es sehr wahrscheinlich, dass der Inhalt der Datenbank sich in den Händen des Angreifers befindet.</p>
<p>Da es sich um einen angemieteten Webspace handelt, wäre es nun extrem aufwendig gewesen, alle Dateien per Hand nach Manipulationen zu durchsuchen. Ich wurde deswegen gebeten, ein PHP Skript zu schreiben, das diese Aufgabe für den Betroffenen erledigt.</p>
<p>Das Ergebnis sind diese beiden Functions:</p>
<pre class="brush:php">&lt;?php
// Function, die die einzelnen Dateien überprüft.
function checkfile($file) {
	// Der Inhalt dieser Dateitypen wird überprüft.
	$types=array('php', 'php4', 'php5', 'txt', 'html', 'htm');
	// Nach diesem Inhalt wird in den Dateien gesucht.
	$contents=array('Suchbegriff', 'Suchausdruck');
	$found=array();
	// Namen der ausführenden Datei und der zu durchsuchenden bestimmen.
	$thisfile=preg_split('/\//', $_SERVER['SCRIPT_FILENAME'], -1, PREG_SPLIT_NO_EMPTY);
	$filename=preg_split('/\//', $file, -1, PREG_SPLIT_NO_EMPTY);
	// Den Dateityp bestimmen.
	$filetype=preg_split('/\./', $file, -1, PREG_SPLIT_NO_EMPTY);
	// Wenn es sich nicht um die ausführende Datei handelt und der Typ in der Dateiliste ist, einen Filehandler für die Datei öffnen.
	if ($thisfile[count($thisfile)-1]!=$filename[count($filename)-1] and in_array($filetype[count($filetype)-1], $types)) {
		// Die Datei so lange auslesen, bis das Ende erreicht wurde.
		$fp= @fopen($file, 'r');
		// Wenn der Filehandler erfolgreich geöffnet werden konnte, die Datei durchsuchen.
		if ($fp) {
			while (!feof($fp)){
				// Alle Suchbegriffe durchgehen und wenn einer gefunden wurde, diesen Treffer dem Trefferarray hinzufügen.
				foreach ($contents as $content) {
					if(strpos(strtolower(fgets($fp)), strtolower($content)) !== false) $found[]=$content;
				}
			}
			// Dateihandler schließen
			fclose($fp);
		}
	}
	unset($fp);
	// Wenn Suchbegrife gefunden wurden, diese als String ausgeben. Anderenfalls mit false antworten.
	if (count($found) == 0) return false;
	else return implode(', ',$found);
}
// Das angegeben Verzeichnis und alle Unterverzeichnisse durchsuchen.
// Wenn kein Verzeichnis angegeben wird, dann im aktuellen beginnen.
function listcontent($dir='.') {
	// Wenn es sich um ein Verzeichnis handelt, den Inhalt listen.
	if (is_dir($dir)) {
		$dircontent=scandir($dir);
		// Den gesamten Inhalt des Verzeichnisses durchgehen.
		foreach ($dircontent as $c) {
			// Wenn es sich um ein Verzeichnis handelt, die Function listcontent() aufrufen;
			if ($c!='.' and $c!='..' and is_dir($dir.'/'.$c)) {
				listcontent($dir.'/'.$c);
			// Wenn es sich um eine Datei handelt und die checkfile() Function einen String zurückgibt, einen Suchtreffer ausgeben.
			} else if ($c!='.' and $c!='..' and checkfile($dir.'/'.$c)) {
				echo 'Found file: '.$dir.'/'.$c.' with content: '.checkfile($dir.'/'.$c).'&lt;br /&gt;';
			}
		}
	// Wenn es sich um eine Datei handelt und die checkfile() Function einen String zurückgibt, einen Suchtreffer ausgeben.
	} else if (checkfile($dir.'/'.$c)) {
		echo 'Found potential bad file: '.$dir.'/'.$c.' with content: '.checkfile($dir.'/'.$c).'&lt;br /&gt;';
	}
}
// Die Suche starten.
echo "Starting search&lt;br /&gt;";
listcontent();
echo "Search finished&lt;br /&gt;";
?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Userinput validieren mittels PHP Klasse</title>
		<link>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/</link>
		<comments>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 19:56:08 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Klasse]]></category>
		<category><![CDATA[Userinput]]></category>
		<category><![CDATA[Validieren]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1642</guid>
		<description><![CDATA[Die Grundregel, dass man keinem Userinput vertrauen soll, wird jedem ein Begriff sein. Zum Validieren habe ich mir nun folgendes Konzept überlegt: Im ersten Schritt werden die Superglobals in ein Object übergeben und dabei escaped. Nach der Übergabe werden die Superglobals gelöscht, da ihr Inhalt nicht mehr benötigt wird. Im folgenden kann der vorherige Inhalt der Superglobals zusammen mit einer Funktion aufgerufen werden, die den Inhalt überprüft. Nur wenn die Überprüfung erfolgreich war, wird der Wert zurückgegeben. Bei dem Aufruf der Funktion gibt man an, welchen Key aus welcher Superglobal erwünscht ist. Wenn die Funktion auch auf Länge überprüfen kann,]]></description>
			<content:encoded><![CDATA[<p>Die Grundregel, dass man keinem Userinput vertrauen soll, wird jedem ein Begriff sein.</p>
<p>Zum Validieren habe ich mir nun folgendes Konzept überlegt:<br />
Im ersten Schritt werden die Superglobals in ein Object übergeben und dabei escaped. Nach der Übergabe werden die Superglobals gelöscht, da ihr Inhalt nicht mehr benötigt wird.</p>
<p>Im folgenden kann der vorherige Inhalt der Superglobals zusammen mit einer Funktion aufgerufen werden, die den Inhalt überprüft. Nur wenn die Überprüfung erfolgreich war, wird der Wert zurückgegeben.</p>
<p>Bei dem Aufruf der Funktion gibt man an, welchen Key aus welcher Superglobal erwünscht ist. Wenn die Funktion auch auf Länge überprüfen kann, dann muss man auch noch die Länge angegeben werden.<br />
Mit dem ersten Wert sagt man, welcher Key gewünscht ist, mit dem zweiten Wert sagt man, von welcher der vorherigen Superglobals der Wert genommen werden soll.</p>
<p>Für den produktiven Einsatz braucht man sicher noch mehr Funktionen. Als Ausgangscode ist die Klasse sicher gut zu gebrauchen:</p>
<pre class="brush:php">
< ?php
class ValidateUserinput {
	private $get=array();
	private $post=array();
	private $server=array();
	private $cookie=array();
	private $request=array();
	private $env=array();
	// Wenn die Magic Quotes nicht zum escapen eingesetzt werden, dann mit addcslashes escapen
	private function magic_quotes ($value) {
		if (!function_exists('get_magic_quotes_gpc') or get_magic_quotes_gpc()==0) {
			$value=addcslashes($value);
		}
		return $value;
	}
	private function inputsecurity ($value,$what) {
		foreach ($value as $key => $val) {
			if (is_string($val)) {
				$this->$what[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->$what[$key] = $this->inputsecurity($val,$what);
			}
		}
	}
	// Constructor
	function __construct($get,$post,$server,$cookie,$request,$env) {
		foreach ($get as $key => $val) {
			if (is_string($val)) {
				$this->get[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->get[$key] = $this->inputsecurity($val,'get');
			}
		}
		foreach ($post as $key => $val) {
			if (is_string($val)) {
				$this->post[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->post[$key] = $this->inputsecurity($val,'post');
			}
		}
		foreach ($server as $key => $val) {
			if (is_string($val)) {
				$this->server[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->server[$key] = $this->inputsecurity($val,'server');
			}
		}
		foreach ($cookie as $key => $val) {
			if (is_string($val)) {
				$this->cookie[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->cookie[$key] = $this->inputsecurity($val,'cookie');
			}
		}
		foreach ($request as $key => $val) {
			if (is_string($val)) {
				$this->request[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->request[$key] = $this->inputsecurity($val,'request');
			}
		}
		foreach ($env as $key => $val) {
			if (is_string($val)) {
				$this->env[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->env[$key] = $this->inputsecurity($val,'env');
			}
		}
	}
	// Destructor
	function __destruct() {
		unset($this->get);
		unset($this->post);
		unset($this->server);
		unset($this->cookie);
		unset($this->reques);
		unset($this->env);
	}
	// Url Filter
	function url ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value],FILTER_VALIDATE_URL)) {
			return $check[$value];
		}
	}
	// Mail Filter
	function ismail($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value],FILTER_VALIDATE_EMAIL)) {
			return $check[$value];
		}
	}
	// IP4 Adressen
	function ip4 ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){
			return $check[$value];
		}
	}
	// IP 6 Adressen
	function ip6 ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){
		return $check[$value];
		}
	}
	// IP4 und IP6 Adressen
	function ip ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP)){
			return $value;
		}
	}
	// Serverport
	function port($value,$type) {
		$check=$this->$type;
		if (preg_match("/^(0|([1-9]\d{0,3}|[1-5]\d{4}|[6][0-5][0-5]([0-2]\d|[3][0-5])))$/",$check[$value])) {
			return $check[$value];
		}
	}
	// A-Z, a-z und 0-9 sind in beliebiger Anordnung mit einer maximalen Stringlänge erlaubt.
	function pregw($value,$length,$type) {
		$check=$this->$type;
		if (preg_match("/^[\w]{1,$length}$/",$check[$value])) {
			return $check[$value];
		}
	}
	// Gibt den Wert ohne Inputüberprüfung zurück.
	function escaped ($value,$type) {
		$check=$this->$type;
		return $check[$value];
	}
}
// Die Superglobals leeren, nachdem sie in das Object übergeben worden sind.
$ui=new ValidateUserinput($_GET,$_POST,$_SERVER,$_COOKIE,$_REQUEST,$_ENV);
unset($_GET);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($_REQUEST);
unset($_ENV);
// Ab hier würde dann der restliche PHP Code beginnen.
// Die einzelnen Werte werden dadurch aufgerufen, dass man mit der Funktion bestimmt, auf was der Wert überprüft werden soll.
// Mit dem ersten Wert sagt man, welcher Key gewünscht ist, mit dem zweiten Wert sagt man, von welcher der vorherigen Superglobals der Wert genommen werden soll.
// Bei dem Beispielaufruf datei.php?w=test würde test ausgegeben werden
if ($ui->escaped('w','get')) echo $ui->escaped('w','get');
else echo 'Nicht validiert';
?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vorschlag einer genaueren Protection Mode Richtlinie der ESL</title>
		<link>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/</link>
		<comments>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 14:42:28 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[ESL]]></category>
		<category><![CDATA[Counter-Strike]]></category>
		<category><![CDATA[Counter-Strike: Source]]></category>
		<category><![CDATA[esl]]></category>
		<category><![CDATA[esl.eu]]></category>
		<category><![CDATA[Gameserver]]></category>
		<category><![CDATA[protection mode]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1630</guid>
		<description><![CDATA[Möchte man als Hoster bei der ESL als zertifizierter Hoster geführt werden, muss er seinen Kunden ein Webinterface bereitstellen, dass den genannten Protection Mode unterstützt. beim Zulassungsverfahren wurde bisher eine PDF versandt, die nur recht Wage aufgelistet hat, welche Maßnahmen man ergreifen kann, damit der Server als sicher eingestuft wird. Das man hier keine genauen Vorschriften machen kann, was genau, auf welche Art umzusetzen ist, liegt in der Natur der Sache. Jedes Interface arbeitet anders. Das die Vorgabe sehr wage sind, kann man der ESL deswegen nicht vorwerfen. Es ist somit die Verantwortung der Webinterface Entwickler eine Lösung für ihren]]></description>
			<content:encoded><![CDATA[<p>Möchte man als Hoster bei der <a href="referrer.php?r=http://esl.eu" target="_blank">ESL</a> als zertifizierter Hoster geführt werden, muss er seinen Kunden ein Webinterface bereitstellen, dass den genannten <em>Protection Mode</em> unterstützt. beim Zulassungsverfahren wurde bisher eine PDF versandt, die nur recht Wage aufgelistet hat, welche Maßnahmen man ergreifen kann, damit der Server als sicher eingestuft wird. Das man hier keine genauen Vorschriften machen kann, was genau, auf welche Art umzusetzen ist, liegt in der Natur der Sache. Jedes Interface arbeitet anders. Das die Vorgabe sehr wage sind, kann man der ESL deswegen nicht vorwerfen. Es ist somit die Verantwortung der Webinterface Entwickler eine Lösung für ihren Spezialfall zu schaffen.</p>
<p>Was hingegen teilweise auf die Kappe der ESL geht, ist der Umstand, dass sich über mögliche Angriffswege ausgeschwiegen wurde. Nicht jeder Coder kennt sich in den Eigenarten einzelner Gameserver aus, oder verfolgt die Diskussionen zu diesen. Wenn er sich nur auf die ESL verlässt und auf den Rat von Dritten verzichtet, wird er wichtige Dinge übersehen. Wenn er jedoch Hinweise Dritter bewusst übergeht, ist eine fehlerhafte Umsetzung alleinig ihm anzulasten.</p>
<p>Da es bis heute keine zusammenfassende Auflistung über mögliche Angriffswege und Abwehrmaßnahmen gibt, habe ich nun im Rahmen meiner ehrenamtlichen Tätigkeit bei der ESL einen Vorschlag für eine Richtlinie erarbeitet und diese an die ESL weitergeleitet. Ob und in welcher Form mein Vorschlag übernommen wird, ist Sache der ESL.</p>
<p>Auch unabhängig vom Protection Mode ist es sicherlich interessant, über welche Wege Kunden ihre Server anderes betreiben können, als vom Anbieter vorgesehen.</p>
<p>Viele der Punkte gibt es schon seitdem es Gameserver gibt und sind versierten Anwendern ebenso lange bekannt. Dennoch werden sie leider immer wieder übersehen.</p>
<p>Im folgenden nun mein Vorschlag einer Richtlinie für den Protection Mode</p>
<p><em><span style="text-decoration: underline;">Ziel:</span></em><br />
Der Server, der unter der angegeben Adresse (IP:Port) erreicht wird, darf außer den Servertools eslplugin und zblock keine weiteren Servertools geladen haben.</p>
<p><em><span style="text-decoration: underline;">Angriffswege , die nicht funktionieren dürfen:</span></em><br />
<em>1. Upload in das geschütze Verzeichnis:</em><br />
Der User darf nicht in der Lage sein, Servertools in die Verzeichnisse des geschützen Server zu laden und von dort auszuführen.</p>
<p><em>2. plugin_load:</em><br />
Das Ausführen des Servercommands &#8220;plugin_load&#8221; muss verhindert werden. Dabei ist auch zu beachten, das die *.so Dateien des Servers manipuliert werden können, so dass der Befehl unter dem Beispielnamen &#8220;plg1n_load&#8221; läuft. Über das deaktivieren des Befehls hinaus, muss deswegen sicher gestellt sein, dass der Benutzer die *.so des Servers nicht verändern kann.</p>
<p><em>3. Änderung der ausführbaren Dateien:</em><br />
Mittels eines FTP Client und Editor können Änderungen an den Startskripten , ausgeführten Binaries und den *.so in den bin/ Ordern der Server gemacht werden. Des Weiteren kann man diese Änderungen auch mit Servertools wie Sourcemod und Eventscript herbeiführen.<br />
Diese Veränderungen müssen sowohl beim geschützten, als auch ungeschützen Server entweder rückgängig, oder von vornherein verhindert werden.</p>
<p><em>4. (Reverse) Shells:</em><br />
Manche Servertools können Shells bereitstellen, mit denen man Prozesse vom Gameserverprozess losgelöst starten kann. Diese Prozesse müssen beim Start des Protected Modes beim normalen User beendet werden.</p>
<p><em>5. Folgen von Punkt 3 und 4:</em><br />
Ein nach den Punkt 3 oder 4 kompromitierter ungeschützter Server kann auch durch eine Firewall hindurch eine Reverse Shell aufbauen. Wenn diese beim Start des Protected Modes nicht erkannt wird, kann man die Adresse des geschützten Servers mit einem ungeschützten belegen.<br />
Eine Belegung der Adresse kann ebenso mit Endlosschleifen und Cronjobs erreicht werden.<br />
Es müssen deswegen alle ungewollten Cronjobs und Prozesse beim Benutzer des ungeschützten Servers beendet werden, bevor der protected Server gestartet wird. Es darf nicht möglich sein, dass die Adresse voin einem anderen Prozess, als dem geschützten benutzt wird.</p>
<p><em><span style="text-decoration: underline;">Mögliche Maßnahmen:</span></em><br />
Folgende Maßnahmen müssen nicht alle umgesetzt werden. Sie sind lediglich eine Liste von Dingen, mit denen man das Ziel erreichen kann.</p>
<ol>
<li>Strenge Chmods</li>
<li>Zugriffseinschränkungen und Dateifilter am FTP Server</li>
<li>Prozess und Port Kontrolle</li>
<li>Verbieten des Befehls plugin_load</li>
<li>Überprüfung kritischer Serverdateien vor jedem Serverstart sowohl im Protected Mode als auch im Unprotected Mode</li>
<li>Ohne Differenzierung alle Prozesse des ungeschützten Users beim Start des Protection Modes killen</li>
<li>Die Server mit unterschiedlichen Usern starten. Dabei sollte unter keinen Umständen ein User mit Root, oder Sudo Rechten den Prozesse ausführen.</li>
<li>Für jeden Gameserverprozess ein eigenes Chroot</li>
</ol>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><em>Zusätzlicher Hinweis:</em></span><br />
Es gibt keine wirksamen Maßnahmen gegen Shellplugins. Im Extremfall könnte dies ausgenutzt werden, um über veralterte Pakete oder Kernel Rootrechte erlangt werden. Es ist deswegen darauf zu achten, dass der Server nicht über bekannte Exploits von innen angreifbar ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Bestimmen der includieren Datei anhand von $_SERVER</title>
		<link>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/</link>
		<comments>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 12:02:28 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[$_SERVER]]></category>
		<category><![CDATA[Dateiname]]></category>
		<category><![CDATA[Superglobal]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1621</guid>
		<description><![CDATA[$_SERVER ist eine so genannte Superglobal und enthält Informationen, wie die Sprache des Users und Daten zu der aufgerufenen Datei. Mit folgendem Code kann man sich den gesamten Inhalt samt Keys auflisten lassen: < ?php foreach ($_SERVER as $key => $info) { echo $key.': '.$info.''; } ?> Die Ausgabe kann dann wie folgt aussehen: TMPDIR: /var/www/html/project.tld/temp/ PATH: /usr/local/bin:/usr/bin:/bin PHPRC: /var/www/html/project.tld/conf/ PWD: /var/www/html/project.tld/php-fcgi FCGI_ROLE: RESPONDER UNIQUE_ID: Twgt2T5asdUAAHbGuiIAAACS HTTP_HOST: project.tld HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1 HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 HTTP_ACCEPT_LANGUAGE: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 HTTP_ACCEPT_ENCODING: gzip, deflate HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_COOKIE: PHPSESSID=2a03a4eec3as2b9a4afd692474c64c1e HTTP_DNT: 1 HTTP_CONNECTION: close SERVER_SIGNATURE: SERVER_SOFTWARE: Apache/2.2.17 SERVER_NAME: project.tld SERVER_ADDR: 1.1.1.1 SERVER_PORT:]]></description>
			<content:encoded><![CDATA[<p>$_SERVER ist eine so genannte <a href="referrer.php?r=http://www.php.net/manual/de/language.variables.superglobals.php" target="_blank">Superglobal</a> und enthält Informationen, wie die Sprache des Users und Daten zu der aufgerufenen Datei.</p>
<p>Mit folgendem Code kann man sich den gesamten Inhalt samt Keys auflisten lassen:</p>
<pre class="brush:php">
< ?php
foreach ($_SERVER as $key => $info) {
	echo $key.': '.$info.'';
}
?>
</pre>
<p>Die Ausgabe kann dann wie folgt aussehen:</p>
<blockquote><p>
TMPDIR: /var/www/html/project.tld/temp/<br />
PATH: /usr/local/bin:/usr/bin:/bin<br />
PHPRC: /var/www/html/project.tld/conf/<br />
PWD: /var/www/html/project.tld/php-fcgi<br />
FCGI_ROLE: RESPONDER<br />
UNIQUE_ID: Twgt2T5asdUAAHbGuiIAAACS<br />
HTTP_HOST: project.tld<br />
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1<br />
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8<br />
HTTP_ACCEPT_LANGUAGE: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3<br />
HTTP_ACCEPT_ENCODING: gzip, deflate<br />
HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7<br />
HTTP_COOKIE: PHPSESSID=2a03a4eec3as2b9a4afd692474c64c1e<br />
HTTP_DNT: 1<br />
HTTP_CONNECTION: close<br />
SERVER_SIGNATURE:<br />
SERVER_SOFTWARE: Apache/2.2.17<br />
SERVER_NAME: project.tld<br />
SERVER_ADDR: 1.1.1.1<br />
SERVER_PORT: 80<br />
REMOTE_ADDR: 2.2.2.2<br />
DOCUMENT_ROOT: /var/www/html/project.tld/httpd<br />
SERVER_ADMIN: admin@project.tld<br />
SCRIPT_FILENAME: /var/www/html/project.tld/httpd/test.php<br />
REMOTE_PORT: 50156<br />
GATEWAY_INTERFACE: CGI/1.1<br />
SERVER_PROTOCOL: HTTP/1.1<br />
REQUEST_METHOD: GET<br />
QUERY_STRING: test=test<br />
REQUEST_URI: /test.php?test=test<br />
SCRIPT_NAME: /test.php<br />
PHP_SELF: /test.php<br />
REQUEST_TIME: 1325936089
</p></blockquote>
<p>$_SERVER enthält keinen Key für den Namen der aufgerufenen Datei selber. Wenn man darauf reagieren möchte, welche Datei einen bestimmten Code includiert hat, wird man mit dem Aufruf eines Keys von $_SERVER alleine erfolglos sein. Man kann die notwendige Information aber aus dem Key &#8216;SCRIPT_NAME&#8217; gewinnen:</p>
<pre class="brush:php">
< ?php
// den Key 'SCRIPT_NAME' an den "/" trennen.
$split=preg_split("/\//",$_SERVER['SCRIPT_NAME'],-1,PREG_SPLIT_NO_EMPTY);
// Die Einträge des Arrays bestimmen und 1 abziehen, da bei den Array Keys bei 0 zu zählen begonnen wird
$count=count($split)-1;
// Der Letzte Eintrag ist unsere Datei
$file=$split[$count];
// Wenn es die Datei x ist, 'Hello World' ausgeben, ansonsten den Dateinamen
if ($file=='x.php') {
	echo 'Hello World';
} else {
	echo $file;
}
?>
</pre>
<p>Ohne Kommentare und zusammegefasst sieht der Code dann so aus:</p>
<pre class="brush:php">
< ?php
$split=preg_split("/\//",$_SERVER['SCRIPT_NAME'],-1,PREG_SPLIT_NO_EMPTY);
$file=$split[count($split)-1];
if ($file=='x.php') {
	echo 'Hello World';
} else {
	echo $file;
}
?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

