<?php error_reporting(E_ERROR); //var_dump($argv); //exit; /** * Funktion um eine URL zu prüfen. * * Dazu wird eine Socketverbindung zum Server aufgebaut und ein HEAD Request nach der Ressource * durchgeführt. Die Funktion folgt auch Header-Weiterleitungen und ermittelt ggf geänderte URLs * * @param string $url komplette URL inkl Schema z.B. http://www.google.ch/ oder http://www.google.ch/path/to/document.html * @return mixed Status der Prüfung * @return booloean false Es konnte keine Verbindung zum Server aufgebaut werden oder der Server anwortete mit einer 404-er Fehler * @return booloan true Die URL ist okay und kann verwendet werden * @return string URL Es wurde bei der Abfrage eine neue URL gefunden (301-er oder 302-er Weiterleitung) */ function checkURL($url){ $url = parse_url($url); $fp = fsockopen($url['host'],80); if($fp === false){ return false; } $ret = array(); $out = "HEAD {$url['path']} HTTP/1.1\r\n"; $out .= "Host: {$url['host']}\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { $ret[] = fgets($fp, 128); } fclose($fp); if(strpos($ret[0],"200 OK") !== false){ return true; }else{ if(strpos($ret[0],"301") !== false || strpos($ret[0],"302") !== false){ foreach($ret as $wert){ if(strpos($wert,"Location: http://") !== false){ $wert = trim(str_replace("Location:",'',$wert)); return $wert; } } return false; } } return false; } /** * Funktion um eine URL abzufragen und den Inhalt der Ressource zu laden * * @param string $url komplette URL inkl Schema z.B. http://www.google.ch/ oder http://www.google.ch/path/to/document.html * @param boolean $file Wenn FALSE gesetzt ist (default), dann wird die Ressource beim Server angefragt * @param string $file Wenn ein STRING übergeben wird, dann wird dieser als Filename interpretiert. Wenn $file noch nicht vorhanden ist * dann wird die Ressource vom Server geladen und in $file gespeichert. * Wenn $file bereits vorhanden ist, dann wird die Ressource aus dem dem File ausgelesen und zurückgegeben * @return array Es wird ein Array mit den Zeilen der Ressource zurückgegeben */ function fetchURL($url=false,$file=false){ if($file !== false && file_exists($_SERVER['DOCUMENT_ROOT'].'/'.basename($file))){ return file($_SERVER['DOCUMENT_ROOT'].'/'.basename($file)); } //die($url); if($url===false | empty($url)){ die('Function fetchURL expects as its name says A URL!!'); } $url = parse_url($url); if(!$fp = @fsockopen($url['host'],80)){ die("Connection to server {$url['host']} could not be established. Most commonly the server has no DNS Record or you misspelled the adress"); } $out = "GET {$url['path']}?{$url['query']} HTTP/1.1\r\n"; $out .= "Host: {$url['host']}\r\n"; $out .= "Connection: Close\r\n\r\n"; //var_dump($url); //echo ($out); //exit; $ret = array(); $body = false; fwrite($fp, $out); while (!feof($fp)) { $t = fgets($fp, 128); //echo $t; //continue; if($body === true){ $ret[] = $t; }elseif(trim($t) == ''){ //die('Geht'); $body=true; continue; } continue; } fclose($fp); $ret = array_slice($ret,1); for($i=0;$i<count($ret);$i++){ if(strpos($ret[$i],'#') === 0 || strpos($ret[$i],'localhost') !== false || trim($ret[$i]) == '' || strpos($ret[$i],'[') !== false || strpos($ret[$i],'.') === false){ unset($ret[$i]); } } if($file !== false){ $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/'.$file,'w'); fwrite($fp,trim(implode('',$ret))); fclose($fp); } return $ret; } /** * Erstellt einen String im vorgegebenen Format * * @param array $filecontent Array mit den Zeilen der Ressource * @param boolean $style Wenn FALSE dann werden die Zeilen unbearbeitet zurückgegeben * @param string $style Wenn dnsmasq dann wird die Zeile für die Verwendung in dnsmasq formatiert * @param string $style Wenn hosts dann wird die Zeile für die Verwendung in HOSTS Dateien formatiert * @param string $ip Legt die IP Adresse fest welche für einen DNS Request nach dem Host zurückgegeben werden soll * @return array Die Zeilen (ggf bearbeitet) der Ressource werden in einem Array zurückgegeben */ function createString($filecontent,$style=false,$ip='127.0.0.1'){ if(!isset($filecontent) || !is_array($filecontent) || count($filecontent) == 0) die('Function createString expects an array of text lines to proccess. Must be an array and must NOT be empty!!'); foreach($filecontent as $key=>$wert){ if(trim($wert) == '' || strpos($wert,'[') !== false){ unset($filecontent[$key]); continue; } switch($style){ case false: break; case 'dnsmasq': $filecontent[$key] = 'address="/'.trim($wert).'/'.$ip.'"'."\r\n"; break; case 'hosts': $filecontent[$key] = "{$ip}\t\t".$wert; break; } } return $filecontent; } /** * Filtert Host-Domain-Namen aus dem Inhalt der Ressource * * @param array $filecontent Array mit den Zeilen der Ressource * @param boolean $exec Wenn TRUE dann wird die Funktion versuchen die Host-Domainnamen herauszufiltern * @param boolean $exec Wenn FALSE dann wird das Array nur alphabetisch sortiert und zurückgegeben. Kann man dann setzen wenn man * die Daten bereits in fertiger Form (HOSTS oder dnsmasq) hat. Auch wenn man nur eine List mit Hostnamen hat sollte man diese Var setzen * denn die Funktion wird in diesem Fall die Namen nicht finden. In diesem Fall kann man FALSE setzen und die Rückgabe direkt an * createString() zur Weiterverarbeitung durchreichen * @return array Array nur mit den Host/Domainnamen der Ressource (wird in dieser Form von createString() erwartet) */ function stripHostsFromContent($filecontent,$exec=true){ $names = array(); sort($filecontent,SORT_STRING); if($exec === false) return $filecontent; foreach($filecontent as $key=>$wert){ $t = str_split($wert); foreach($t as $key=>$wert){ if(trim($wert) == ''){ $t = array_slice($t,$key+1); break; } } if(strpos(implode('',$t),'.') === false) continue; $names[] = trim(implode('',$t))."\r\n"; } //var_dump($names); //exit; return $names; } /** * Schreibt die aufbereiteten Daten in die entsprechenden Files * * @param array $filecontent Array mit Daten zum Schreiben in $name * @param string $name Dateiname wo die Daten reingeschrieben werden sollen * @return string $str Inhalt der gerade geschriebenen Datei (von der Platte gelesen und nicht aus dem Speicher) */ function writeFile($filecontent,$name){ $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/'.$name,'w'); fwrite($fp,implode('',$filecontent)); fclose($fp); $str = '<pre>'.file_get_contents($_SERVER['DOCUMENT_ROOT'].'/'.$name).'</pre>'; return $str; } /* Erstes Beispiel erwartet die Argument auf der Kommandozeile (geht also nur mit ipkg php). Die übergebenen Argumente stellt php in der Variable $argv (array) zur Verfügung. Das erste Element: (0) ist der Scriptname selber. (1) ist die URL. (2) ist der Filename zum Schreiben der Daten auf die HD (3) setzt den Parameter für stripHostsFromContent() */ /* $t = fetchURL($argv[1]); if($argv[3] == 'false'){ $t = stripHostsFromContent($t,false); }else{ $t = stripHostsFromContent($t,true); } $t = createString($t,'dnsmasq'); writeFile($t,$argv[2]); */ /* Das zweite Beispiels erwartet ein Array mit einem Eintrag pro URL. $ret[][0]: URL die abgefragt werden soll $ret[][1]: Name des Zielfiles $ret[][2]: Parameter für stripHostsFromContent() Der letzte Eintrag ist aukommentiert, weil das Laden dieser Liste in einem PHP Fehler endet. Man kann das File jedoch im Browser runterladen und ins Webverzeichnis verschieben. Dann kann man die Funktion fetchURL() mit dem Fileparameter aufrufen, damit die Daten von der Platte geladen werden. Dann ist die Verarbeitung mit den restlichen Funktionen kein Problem mehr */ $ret[] = array('http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=0&mimetype=plaintext','dnsmasq.more.conf',false); $ret[] = array('http://www.mvps.org/winhelp2002/hosts.txt','dnsmasq.more1.conf',true); //$ret[] = array('http://hostsfile.mine.nu/Hosts','dnsmasq.more2.conf',true); foreach($ret as $wert){ $t = fetchURL($wert[0]); $t = stripHostsFromContent($t,$wert[2]); $t = createString($t,'dnsmasq'); writeFile($t,$wert[1]); } /* Letztes Beispiel zeigt die Verarbeitung am Beispiel des obigen Files welches PHP zum crashen bringt. Das File wurde als test.txt im Webverzeichnis gespeichert (z.B. im Browser runtergeladen). Wenn der Fileparameter angegeben wurde dann spielt die URL keine Rolle mehr. Es wird so oder so das angegeben File von der Platte geladen. stripHostFromContent() holt dann die Domain/Hostnamen aus den Daten und createString() erstellt daraus einen String im geforderten Format (hier für dnsmasq) /* $t = fetchURL('http://google.ch','test.txt'); $t = stripHostsFromContent($t,true); $t = createString($t,'dnsmasq'); writeFile($t,'dnsmasq.more2.conf'); */ ?>