#!/usr/bin/php
. */
if($ver = "fb_tools 0.33 (c) GPL 10.12.2022 by Michael Engelke ") {
if(!(isset($cfg) and is_array($cfg))) // Testen ob $cfg existiert und ein array ist
$cfg = array(); // Config-Variable anlegen
foreach(array( // Vorkonfiguration einzeln durchgehen
'sock' => 'auto', // Socket: http, https, ssl, tls
'host' => 'fritz.box', // Fritz!Box-Addresse
'pass' => 'password', // Fritz!Box Kennwort
'uipw' => false, // Fritz!Box Anmeldekennwort (Nur mit AuthBasic-Fernwartung)
'user' => false, // Fritz!Box Username (Optional)
'totp' => false, // Zweite-Faktor-Authentifizierung
'port' => 80, // Fritz!Box HTTP-Port (Normalerweise immer 80)
'fiwa' => 100, // Fritz!Box Firmware (Nur Intern)
'upnp' => 49000, // Fritz!Box UPnP-Port (Normalerweise immer 49000)
'jsdp' => 512, // Maximale Verschachtelung beim parsen von JSON-Daten
'sbuf' => 4096, // TCP/IP Socket-Buffergr��e oder file-Buffer
'tout' => 30, // TCP/IP Socket-Timeout
'pcre' => 64*1024*1024, // pcre.backtrack_limit (RegEx)
'meli' => 128*1024*1024, // Memory Limit
'upda' => 60*60*24*100, // Auto-Update-Check Periode (Kein Update-Check: 0)
'wrap' => 'auto', // Manueller Wortumbruch (Kein Umbruch: 0)
'char' => 'auto', // Zeichenkodierung der Console (auto/ansi/oem/utf8)
'dbfn' => 'debug#.txt', // Template f�r Debug-Dateien
'time' => 'Europe/Berlin', // Zeitzone festlegen
'slct' => 'de_DE', // Locales Datumsformat nach Land festlegen
'drag' => 'info hash *', // Drag'n'Drop-Modus
'fesc' => '|<>?*+"/\\:', // Illegale Dateizeichen
'frep' => '_', // Ersetzungszeichen f�r Illegale Dateizeichen
'fbtg' => 'fbtp_*.php', // Plugin Glob-Pattern
'fbtm' => 'fbtp_([\w-]+)\.php',// Plugin Preg_Match-Pattern
'fbtp' => 'plugins', // Plugin-Pfad
'libs' => 'libs', // PHP-Bibliotheken
'argn' => 'https?:|\w:|[\da-f]{2}:',// Args-Filter
'help' => false, // Hilfe ausgeben
'dbug' => false, // Debuginfos ausgeben
'oput' => false, // Ausgaben speichern
'zlib' => array('mode' => -1), // ZLib-Funktionen (mode: packlevel)
'error' => array(), // Fehler Pool Defininieren
'proxy' => false, // HTTP-Proxy ohne Authentifizierung (proxy.tld:port)
'touch' => ".touch", // Workaround, wenn fb_Tools nicht schreiben kann/darf
'usrcfg'=> 'fb_config.php', // Name der Benutzerkonfiguration
'gz' => 9, // ZIP Deflate Pack Level
) as $key => $var)
if(!isset($cfg[$key])) // Existiert die Variable schon
$cfg[$key] = $var; // Wenn nicht - dann anlegen
}
if(!function_exists('array_combine')) { // http://php.net/array_combine
function array_combine($key,$value,$array=array()) {
if(count($key = array_values($key)) == count($value = array_values($value)))
foreach($value as $k => $v)
$array[$key[$k]] = $v;
return $array ? $array : false;
}
}
if(!function_exists('gzdecode')) { // http://php.net/gzdecode (Workaround)
function gzdecode($data,$len=0,$out=false) {
global $cfg;
$out = '';
if(preg_match('/^\x1f\x8b\x08([\x00-\x1f])[\x00-\xff]{4}\x02[\x00-\xff]([\x00-\xff]+)([\x00-\xff]{4})([\x00-\xff]{4})$/s',$data,$gz)) {
$flag = ord($gz[1]); // Flags lesen
$tmp = $gz[2];
while($flag >>= 1) // Extra-Header �berspringen
$tmp = substr($gz[2],strpos($gzip[2],"\0")+1);
$tmp = gzinflate($tmp); // Deflate-Daten entpacken
if(strlen($tmp) == hexdec(bin2hex(strrev($gz[4]))) and hash('crc32b',$tmp,1) == strrev($gz[3])) // Alles Pr�fen (L�nge & CRC32)
if($len)
$out = substr($data,0,$len);
}
if(!$out and $tmp = tempnam(null,'gz') and $fp = fopen($tmp,'w')) { // Gepackte Daten speichern
fwrite($fp,$data);
fclose($fp);
if($fp = $cfg['zlib']['open']($tmp,'rb')) { // Daten entpackt lesen
while(!$cfg['zlib']['eof']($fp))
$out .= $cfg['zlib']['read']($fp,$cfg['sbuf']);
$cfg['zlib']['close']($fp);
if($len)
$out = substr($out,0,$len);
}
@unlink($tmp); // �berreste l�schen
}
return $out;
}
}
if(!function_exists('hash')) { // http://php.net/hash (Workaround f�r crc32b, md5, sha1 und optional sha256)
function hash($algo,$data,$raw=false) {
return ($algo == 'sha256' and function_exists('mhash') and $a = mhash(MHASH_SHA256,$data)) ? ($raw ? $a : bin2hex($a))
: ((preg_match('/^(md5|sha\d+)$/',$algo) and function_exists($algo) and $a = $algo($data) or $algo == 'crc32b' and $a = sprintf('%08x',crc32($data))) ? ($raw ? pack("H*",$a) : $a) : false);
}
}
if(!function_exists('strftime')) { // http://php.net/strftime
function strfime($data,$time=false,$last=0) {
if(!$time)
$time = time();
if(preg_match_all('/(.)(.)/',"AlBFGoHHIhMiPaSsVWYYZTaDbMddejhMkGlgmmpAsUuNwwyyzO",$m))
$c = array_combine($m[1],$m[2]) + array('D' => 'm/d/y', 'x' => 'm/d/y', 'F' => 'Y-m-d',
'R' => 'H:i', 'T' => 'H:i:s', 'X' => 'H:i:s', 'r' => 'h:i:s A', 'c' => 'D M j H:i:s Y');
while(preg_match('/%(-?)(\w|%)/',substr($data,$last),$m,PREG_OFFSET_CAPTURE)) {
$new = isset($c[$a = $m[2][0]]) ? date($c[$a],$time) : (($a == 'j') ? substr("00".(date('z',$time) + 1),-3)
: (($a == 'C') ? floor(date('Y',$time) / 100) : (($a == 'g') ? substr(date('o',$time),-2) : (($a == 'U')
? substr("0".floor((date('z',$time) + date('w',strtotime(date('Y',$time)."-01-01"))) / 7),-2) : (($a == 'W')
? substr("0".floor((date('z',$time) + date('N',strtotime(date('Y',$time)."-01-01")) - 1) / 7),-2)
: preg_replace('/^%\w$/','',strtr($m[0][0],array("%n" => "\n", "%t" => "\t", "%-n" => "\n", "%-t" => "\t", "%%" => "%"))))))));
$data = substr_replace($data,$m[1][0] ? preg_replace('/^([+-])[0\s]?(\d*)$/','$1$2',$new) : $new,$last + $m[0][1],strlen($m[0][0]));
$last += strlen($m[0][0]) + $m[0][1];
}
return $data;
}
}
function utf8($str,$mode=0) { // UTF-8 Tool mode: Bit0 -> 0:decode 1:encode
if(is_array($str) and preg_array('/[deuhx]|u[0-3]/',$str,5)) {
if(isset($str['u0'])) { // Entwertete Zeichen in UTF8 umwandeln
if(($a = $str['u0']) != "" or isset($str['u3']) and ($a = $str['u3']) != "" or isset($str['x']) and ($a = $str['x']) != "") // hex -> Int
$a = hexdec($a);
elseif(isset($str['u1']) and isset($str['u2']) and $a = $str['u1'] and $b = $str['u2']) // hex 20 Bit -> Int
$a = (hexdec($a) & 1023) * 1024 + (hexdec($b) & 1023) + 65536;
elseif(isset($str['h']) and $a = ifset($str['h'])) // Dec -> Int
$a = intval($a);
else // Fehler
$a = false;
}
else
$a = $str[0];
if(isset($str['e']) or is_int($a)) { // Ansi -> UTF8
// if(function_exists('utf8_encode') and !is_int($a)) return utf8_encode($a);
if(($a = is_int($a) ? $a : ord($a)) < 128)
return chr($a);
$b = "";
$c = 6;
while($a >= 1 << $c and --$c) {
$b = chr($a & 63 | 128).$b;
$a >>= 6;
}
return chr((1 << 7 - $c) -1 << ++$c | $a).$b;
}
elseif(isset($str['d'])) { // UTF8 -> Ansi
// if(function_exists('utf8_decode')) return utf8_decode($a);
for($b = ord($a[0]) % (1 << 7 - strlen($a)), $c = 1; $c < strlen($a); $c++)
$b = $b * 64 + (ord($a[$c]) & 63);
return ($b < 256) ? chr($b) : "\\u".(($b < 65536) ? str_pad(dechex($b),4,0,STR_PAD_LEFT)
: str_pad(dechex(($b - 65536) >> 10 | 55296),4,0,STR_PAD_LEFT)."\\u".str_pad(dechex(($b - 65536) & 1023 | 56320),4,0,STR_PAD_LEFT));
}
return $a;
}
elseif(is_array($str)) { // Array -> utf8[mode]
foreach($str as $key => $var)
if(is_string($var) or is_array($var))
$str[$key] = call_user_func(__FUNCTION__,$var,$mode);
}
else {
$p = "[\x80-\xbf]";
$p = "[\xc0-\xdf]$p|[\xe0-\xef]$p{2}|[\xf0-\xf7]$p{3}|[\xf8-\xfb]$p{4}|[\xfc-\xfd]$p{5}|\xfe$p{6}";
$p = "/".(($mode & 1) ? "(?P$p)|(?P[\x80-\xff])".(($mode & 2)
? '|\\\\(?:u\{(?P[\da-f]+)\}|(?:u(?Pd[89ab][\da-f]{2})\\\\u(?Pd[cdef][\da-f]{2}))|u(?P[\da-f]{4}))|(?:&\#(?:(?P\d+)|x(?P[\da-f]+));)'
: '') : "(?P$p)")."/";
if((float)phpversion() > 5.2)
return preg_replace_callback($p,__FUNCTION__,$str);
elseif(preg_match_all($p,$str,$match,PREG_OFFSET_CAPTURE)) { // Workaround PHP 4.3 - 5.2
for($a=count($match[0])-1; $a >= 0; $a--) {
$var = array($match[0][$a][0]);
$var[(isset($match['e']) and $match['e'][$a][1] > -1) ? 'e' : ((isset($match['d']) and $match['d'][$a][1] > -1) ? 'd' : 'u')] = $var[0];
$str = substr_replace($str,utf8($var),$match[0][$a][1],strlen($match[0][$a][0]));
}
}
}
return $str;
}
function file_contents($file,$data=false,$mode=false) { // (Gepackte) Datei lesen/schreiben|mode: Bit1 -> Lock, Bit3 -> Append
global $cfg;
if(is_string($data)) { // Datei schreiben
if($file == ':') // Bei nur ":" nichts schreiben
return true;
if(strpos($file,'%') !== false) // strftime aufl�sen
$file = @strftime($file);
if(is_bool($mode) and !$mode)
if(preg_match('/\.t?gz$/i',$file) and $fp = $cfg['zlib']['open']($file,'w'.$cfg['zlib']['mode'])) {// Write GZip
dbug("Schreibe GZip-File: $file",9);
$data = $cfg['zlib']['write']($fp,$data);
$cfg['zlib']['close']($fp);
return $data;
}
elseif(preg_match('/\.t?bz(ip)?2?$/i',$file) and ifset($cfg['bzip']) and $fp = bzopen($file,'w')) { // Write BZip2
dbug("Schreibe BZip2-File: $file",9);
$data = bzwrite($fp,$data);
bzclose($fp);
return $data;
}
elseif(preg_match('/\.zip$/i',$file) and !preg_match('/^PK\x03\x04/',$data))
$data = data2zip(array(preg_replace('/.*?([^\/]*)\.zip$/','$1',$file) => $data));
if(function_exists('file_put_contents'))
return file_put_contents($file,$data,$mode); // Ungepackt schreiben
else { // file_put_contents ($mode ist nicht vollst�ndig implemmentiert)
if($fp = fopen($file,($mode & 1<<3) ? 'a' : 'w')) { // FILE_APPEND -> 8
if(is_array($data))
$data = implode('',$data);
if($mode & 1<<1) { // LOCK_EX -> 2
if(flock($fp,2)) { // flock LOCK_EX
fputs($fp,$data);
flock($fp,3); // flock LOCK_UN
}
else {
fclose($fp);
return null;
}
}
else
fputs($fp,$data);
fclose($fp);
$fp = strlen($data);
}
return $fp;
}
}
elseif(!$data and !$mode and !preg_match('/\.t?gz$/i',$file)) // Datei vollst�ndig lesen (data:0)
return file_get_contents($file);
elseif(is_int($data) and (float)phpversion() >= 5.1) { // Datei ab Offset lesen (data:offset, mode:length) & PHP 5.1+
$data = array($file,false,null,filesize($file) + (($data < 0) ? max($data,-filesize($file)) : min($data,filesize($file))));
if($mode)
$data[] = $mode;
return call_user_func_array('file_get_contents',$data);
}
elseif(is_int($data) and $fp = fopen($file,'r')) { // Datei ab Offset lesen (data:offset, mode:length)
dbug("Lese File: $file ($data/$mode)",9);
fseek($fp,$data,($data < 0) ? SEEK_END : SEEK_SET);
$data = "";
if($mode)
$data = fread($fp,$mode);
else
while(!feof($fp))
$data .= fread($fp,$cfg['sbuf']);
fclose($fp);
return $data;
}
elseif(preg_match('/\.t?bz(ip)?2?$/i',$file) and ifset($cfg['bzip']) and $fp = bzopen($file,'r')) { // BZip2 lesen
dbug("Lese BZip2-File: $file",9);
$data = "";
while(($var = bzread($fp,$cfg['sbuf'])) !== false)
$data .= $var;
bzclose($fp);
return $data;
}
elseif($fp = $cfg['zlib']['open']($file,'r')) { // (gz)Datei entpackt lesen
dbug("Lese gzFile: $file",9);
$data = "";
while(!$cfg['zlib']['eof']($fp))
$data .= $cfg['zlib']['read']($fp,$cfg['sbuf']);
$cfg['zlib']['close']($fp);
return $data;
}
return false;
}
function file_stream($file,$data=false) { // Datei-Stream Zeilenweise Lesen/Schreiben - Optional mit GZip/BZip2
global $cfg,$fsData;
$out = $fs = false;
if(!(isset($fsData) and is_array($fsData))) // Globale Variabel vorhanden?
$fsData = array('bs' => $cfg['sbuf'], 'pt' => 0, 'fs' => array()); // Globale Variable anlegen
if(is_string($file)) { // OPEN (file)
$fs = array('file' => $file, 'seek' => 0, 'data' => '', 'mode' => (is_int($data)) ? $data : ($data ? 1 : 0)); // Init
$rw = ($fs['mode'] & 1) ? 'w' : 'r';
$mode = $fs['mode'] & 6;
dbug("file_stream: open ",9,6);
if(($mode == 2 or preg_match('/\.t?gz$/i',$file)) and $fp = $cfg['zlib']['open']($file,$rw.$cfg['zlib']['mode'])) { // GZip
dbug("GZip-File",9,12);
$fs['mode'] |= 2;
$fs['fp'] = $fp;
}
elseif($mode == 4 or preg_match('/\.t?bz(ip)?2?$/i',$file) and ifset($cfg['bzip']) and $fp = bzopen($file,$rw)) { // BZip2
dbug("BZip2-File",9,12);
$fs['mode'] |= 4;
$fs['fp'] = $fp;
}
elseif($fp = fopen($file,$rw)) { // Normal
dbug("File",9,12);
$fs['fp'] = $fp;
}
else {
dbug("Fail",9,12);
$file = $fs = false;
}
if($fs) // Neuen FileStream ablegen
$fsData['fs'][$file = ++$fsData['pt']] = $fs;
$out = $file;
}
elseif($file and is_int($file) and isset($fsData['fs'][$file]) and $fs = $fsData['fs'][$file]) { // Daten lesen / schreiben
$mode = $fs['mode'] & 6; // GZip/BZip2/Std
if(!($fs['mode'] & 1)) { // LESEN
if(is_int($data)) { // Byteweise
if($mode == 2) // GZip
$out = $cfg['zlib']['read']($fs['fp'],$data);
elseif($mode == 4) { // BZip
if(($len = strlen($fs['data'])) < $data)
$fs['data'] .= bzread($fs['fp'],$data-$len);
$out = substr($fs['data'],0,$data+1);
$fs['data'] = substr($fs['data'],strlen($out));
}
elseif(!$mode) // Normal
$out = fread($fs['fp'],$data);
}
elseif($mode == 2) // GZip (Zeilenweise)
$out = $cfg['zlib']['gets']($fs['fp'],$fsData['bs']);
elseif($mode == 4) { // BZip (Zeilenweise)
if(($len = strlen($fs['data'])) < $fsData['bs']) {
$var = bzread($fs['fp'],$fsData['bs'] - $len);
$fs['data'] .= $var;
$fs['seek'] += strlen($var);
}
if(($pos = strpos($fs['data'],"\n")) === false)
$pos = strlen($fs['data']);
$out = substr($fs['data'],0,$pos+1);
$fs['data'] = substr($fs['data'],strlen($out));
}
elseif(!$mode) // Normal (Zeilenweise)
$out = fgets($fs['fp'],$fsData['bs']);
$fs['seek'] += strlen($out);
}
elseif(($fs['mode'] & 1) and $data) { // SCHREIBEN (Byteweise)
if($mode == 2) // GZip
$out = $cfg['zlib']['write']($fs['fp'],$data);
elseif($mode == 4) // BZip
$out = bzwrite($fs['fp'],$data);
elseif(!$mode) // Normal
$out = fwrite($fs['fp'],$data);
$fs['seek'] += $out;
}
if(!$out or $fs['mode'] & 1 and !$data) { // CLOSE
if($mode == 2) // GZip
$cfg['zlib']['close']($fs['fp']);
elseif($mode == 4) // BZip
bzclose($fs['fp']);
elseif(!$mode) // Normal
fclose($fs['fp']);
unset($fsData['fs'][$file]); // Pointer l�schen
$file = $fs = false; // Variabeln l�schen
}
}
if($file and $fs)
$fsData['fs'][$file] = $fs;
return $out;
}
function listDir($pat,$dirs='',$mode=0,$list=array()) { // Liest ein Verzeichnis aus (Pattern, Verzeichnis(e), Modus) // Bit0 > Pattern, Bit1 > PathPat
if(!($mode & 1<<0)) { // Simple-Pattern // Bit2 > basename, Bit3 > noFile, Bit4 > noDir, Bit5 > Recusiv, Bit6 > Sort
if(!$dirs) { // Kein Verzeichnis angegeben
if(file_exists($pat)) // Pattern existiert
if(is_file($pat)) { // Pattern ist ein File
$dirs = dirname($pat);
$pat = basename($pat);
}
else { // Pattern ist ein Verzeichnis
$dirs = $pat;
$pat = '*';
}
elseif($var = ifset($pat,'/^(.*?)([^\\\\\/]*[*?][^\\\\\/]*)$/')) { // Pattern besteht aus Verzeichnis und Pattern (glob)
$dirs = $var[1];
$pat = $var[2];
}
if(!$dirs)
$dirs = '.';
}
if($pat and !function_exists('fnmatch')) { // Workaround wenn fnmatch() nicht verf�gbar ist
$pat = "/^".strtr(preg_quote($pat,'/'),array('\*' => '.*', '\?' => '.', '\[' => '[', '\]' => ']'))."$/i";
$mode |= 1<<0;
}
}
foreach(array_unique((array)$dirs) as $dir) { // Alle Verzeichnisse durchgehen
if(file_exists($dir) and $dp = opendir($dir)) {
$dir = preg_replace('/[\\\\\/]$/','',$dir); // Letzten Slash entfernen
while(($file = readdir($dp)) !== false)
if(!preg_match('/^\.\.?$/',$file)) { // Kein Current oder Parent
$fn = (($mode & 1<<1) ? "$dir/" : '').$file; // Bit 1 -> Filename f�r Pattern
if(!$pat or $mode & 1<<0 and preg_match($pat,$fn) or !($mode & 1<<0) and fnmatch($pat,$fn,FNM_CASEFOLD) // Bit 0 -> Patterncheck
and (!($mode & (1<<3 | 1<<4)) or $mode & 1<<3 and !is_file("$dir/$file") or $mode & 1<<4 and !is_dir("$dir/$file"))) { // Bit3 -> file / Bit4 -> dir
$fn = ($mode & 1<<2) ? $file : (($dir != '.') ? "$dir/" : "").$file.((is_dir("$dir/$file")) ? '/' : '');
if($mode & 1<<2)
$list[realpath("$dir/$file")] = $fn;
else
array_push($list,$fn);
if($mode & 1<<5 and is_dir("$dir/$file") and $array = call_user_func(__FUNCTION__,$pat,"$dir/$file",$mode)) // Bit 5 -> Rekursiv
if($mode & 1<<2) // Bit 2 -> Basename
$list[($mode & 1<<2) ? realpath($file) : $file] = $array; // Assoc
else
$list = array_merge($list,$array); // List
}
}
closedir($dp);
}
}
if(!$mode & 1<<2)
$list = array_unique($list);
if($mode & 1<<6) // Bit 6 -> Sortieren
natcasesort($list);
return $list ? $list : false;
}
function ifset(&$x,$y=false) { // Variabeln pr�fen und Optional vergleichen (var,test)
return (isset($x) and ($x or $x != '')) ? ($y ? ((is_string($y) and preg_match('!^(([^\w\s]).*\2[imsuxADU]{0,8})((\d)|(a))?($)!Us',$y,$w) and is_string($x)
and ($w[5] and preg_match_all($w[1],$x,$z) or preg_match($w[1],$x,$z))) ? (($z and $w[4] != "") ? $z[(int)$w[4]] : $z) : (is_array($x)
? ((is_string($y) and $w) ? preg_grep($y,$x) : (is_int($y) ? count($x) == $y : (is_bool($y) ? $x : array_search($y,$x))))
: (((is_callable($y) and $z = call_user_func($y,$x)) ? (is_bool($z) ? $x : $z) : ((!is_bool($x) or is_bool($y)) and $x == $y)))))
: (is_string($x) ? (is_string($y) ? $x : strlen($x)) : ((is_numeric($x) or is_bool($x)) ? $x : (is_array($x) ? count($x) : !$y)))) : false;
}
function preg_array($x,$y,$z=0) { // Durchsucht einen Array mit Regul�ren Ausdruck (preg,array,mode)
$w = ($z & 1<<1) ? array() : false; // Return All/First // Bit 0: Search 0:value / 1:key 1
foreach($y as $k => $v) // Bit 1: Result 0:first / 1:all 2
if(($z & (1<<4)) and is_array($v) and $u = call_user_func(__FUNCTION__,$x,$v,$z)) // Bit 2: Result 0:value / 1:key 4
if($z & 1<<1) // Result All // Bit 3: Search 0:found / 1:not found 8
$w[$k] = $u; // Bit 4: 0:iterativ / 1:rekusiv 16
else // Result First
return ($z & 1<<2) ? $k : $u; // Return Key/Value
elseif(($z & 1<<3) xor preg_match($x,($z & 1<<0) ? $k : (is_array($v) ? "" : $v))) // (not)Found & Key/Value
if($z & 1<<1) // Result All
$w[$k] = $v;
else // Result First
return ($z & 1<<2) ? $k : $v; // Return Key/Value
return $w;
}
function unBase($data,$base=false,$bits=false) { // unBase2-128 (data-string, base-chars[Default: AVM-Base32], input-bits)
for($base = $base ? $base : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456', $bits = $bits ? $bits : intval(log(strlen($base),2)), $a=$b=$c=0, $out=""; $a < strlen($data); )
if(($e = strpos($base,$data[$a++])) !== false)
for($c = ($c << $bits) + $e, $b += $bits; $b >= 8; $c %= 1 << $b)
$out .= chr($c >> ($b -= 8));
return $out;
}
function getArg($name=false,$preg=false,$arg=null) { // N�chsten Parameter holen (argname, /preg_match/, argname-only & return@false)
global $cfg,$pset; // args,argc,argn,arg,$opts
$tst = $arg; // Parameter retten f�r TEST-Modus
if(is_string($name) and $name[0] == '-') { // Optionen abfragen
$def = 'opts';
$name = substr($name,1);
}
else // Argumente abfragen
$def = 'args';
if($name) { // Benanntes Argument (name)
if(is_bool($name)) // Ungepr�fte Parameter vorhanden? (name -> true)
$arg = preg_array("/^(".str_replace('\|','|',preg_quote(implode('|',array_keys($cfg['argk'])),'/')).")$/",$cfg['arg'],11);
elseif(isset($cfg[$def][$name]) and is_array($var = $cfg[$def][$name])) { // Benanntes Argument ist ein Array
if(is_string($preg) and strlen($preg) == 1) // Array als CSV zur�ckgeben? (preg -> .)
$arg = implode($preg,str_replace($preg,$preg.$preg,$var));
elseif(!is_array($preg) and $var = current($cfg[$def][$name]) and ifset($var,$preg)) // Aktuelles Argument aus Array zur�ckgeben (preg)
$arg = $preg ? $var : current($cfg[$def][$name]);
elseif(is_array($preg)) // Nur Argumente zur�ckgeben, die auf [preg] passen oder alle
$arg = (isset($preg[0]) and $preg[0]) ? preg_array($preg[0],$cfg[$def][$name],(isset($preg[1])) ? $preg[1] : 2) : $cfg[$def][$name];
}
elseif(isset($cfg[$def][$name])) // Benannter Parameter
$arg = $preg ? ifset($cfg[$def][$name],$preg) : $cfg[$def][$name];
}
elseif(is_null($arg) and is_array($preg) and $cfg['argc']) // Alle restlichen Nummerischen Parameter zur�ckgeben
for($arg=array(); $name = array_shift($cfg['argc']);)
$arg[] = $cfg['arg'][$name];
if($def == 'opts') // Optionen sofort zur�ckgeben
return (is_null($arg)) ? false : ((is_array($preg)) ? (array)$arg : $arg); // Vorgabe oder false zur�ckgeben
elseif($tst === true) // Parameter nur Testweise zur�ckgeben
return ($arg === true) ? (($var = ifset($cfg['arg'][$name = reset($cfg['argc'])],$preg)) ? ($preg ? $var : $cfg['arg'][$name]) : false) : $arg;
elseif(is_null($arg) or $arg == $tst and $cfg['argc']) { // Nummerierter/Unbenannter Parameter
foreach($cfg['argc'] as $val => $name) // Auf Inhaltpr�fen
if(($var = ifset($cfg['arg'][$name],$preg)) != "")
break;
if(ifset($var) != "") { // Wurde ein Nummerierter/Unbenannter Parameter gefunden?
if(!$cfg['argn']) // �bergabe/Abfrage vom alten Parameter-System erm�glichen
$pset++;
unset($cfg['argc'][$val]); // Parameter l�schen
$arg = $preg ? $var : $cfg['arg'][$name];
}
}
return (is_null($arg) or !$arg and (is_array($arg) or is_string($arg) and is_bool($arg))) ? false : $cfg['argk'][$name] = ((is_array($preg)) ? (array)$arg : $arg); // Vorgabe oder false zur�ckgeben
}
function out($str,$mode=0,$lf=PHP_EOL) { // Textconvertierung vor der ausgabe (mode: 0 -> echo / 1 -> noautolf / 2 -> debug)
global $cfg;
$cp = ifset($cfg['char']) ? (array)$cfg['char'] : array('c' => 1);
if(ifset($cp['n'])) // Char:none
return ""; // Keine Ausgabe
if(is_array($str))
$str = print_r($str,true);
if(is_string($str) and $str != "") {
if(!($mode & 1<<1) and preg_match('/\S$/D',$str)) // AutoLF
$str .= $lf;
if($mode & 1<<2) // Unn�tige Whitespaces im Debug-Modus l�schen
$str = preg_replace('/(?<=\n\n|\r\n\r\n)\s+$/','',$str);
if($cfg['oput'] and !($mode & 1<<2)) // Ausgabe speichern
file_contents($cfg['oput'],textTable($str,-1),8);
if(ifset($cp['d']) and preg_match_all('/(.)(.)/',base64_decode(
"thSnFceA/IHpguKD5ITgheWG54fqiOuJ6Irvi+6M7I3EjsWPyZDmkcaS9JP2lPKV+5b5l/+Y1pncmqOc4aDtofOi+qPxpNGlqqa6p7+orKq9q7ysoa2rrruv3+G15rHx9/aw+Lf6sv2g/"
.((substr($cp['d'],-3) == 437) ? "6KbpZ0=" : "/ib2J3Xnq6pwbXCtsC3qbiivaW+48bDx6TP8NDQ0crSy9PI1M3WztfP2KbdzN7T4NTi0uP15NXl/ufe6Nrp2+rZ6/3s3e2v7rTvrfC+87b0p/W496j5ufuz/A==")),$m))
$str = strtr(utf8($str),array_combine($m[1],$m[2])); // DOS
elseif(ifset($cp['m']) and preg_match_all('/(.)(.)/',"ǀ��������Ďɐ����֙ܚמ��������������¶����������������������������������",$m))
$str = strtr(utf8($str),array_combine($m[1],$m[2])); // cp852
elseif(ifset($cp['u']))
$str = utf8($str,3); // UTF8
elseif(ifset($cp['h']) and preg_match_all('/(.)([\da-z#]+)/','&gt"quot\'#39�auml�ouml�uuml�szlig�Auml�Ouml�Uuml',$m))
$str = strtr($str,array_combine($m[1],preg_replace('/.+/','&$0;',$m[2]))); // HTML
elseif((ifset($cp['c']) or ifset($cp['l']) or ifset($cp['r']) or !ifset($cp['a']))
and preg_match_all('/([^ -~]+)([ -~]+)/','�!�GBP�|�\\S�"�(c)�<<�-�(R)��\'�^�+-�2�3�\'�u�I�\''
.'�.�1�>>�1/4�1/2�3/4�?�AE�Ae�Oe�Ue��ae�oe�ue�ss�����A�C����E����I�D�N�����O���UݥY�p�����a�c����e����i�n�������o���u�P��y�x�:',$m)) {
$a = array(); // 7 Bit ASCII
foreach($m[1] as $key => $var)
for($b=0; $b < strlen($var); $b++)
$a[$var[$b]] = $m[2][$key];
$str = strtr(utf8($str),$a);
}
else // Ansi
$str = utf8($str);
$str = textTable($str,-1); // Tabelle im String
if($var = ifset($cp['l'],"") and preg_match_all('/([a-z\d])(.)/i','1I2Z3E4A5S6G7T8B9g0Oa4A4b8B8e3E3g6G6l1L1o0O0q9Q9s5S5t7T7z2Z2'.(is_numeric($var) ? '' : 'c Debug) # dbug(compact(explode(',','array,key,var')));
global $cfg;
if(floor($cfg['dbug']/(1<<$level))%2) { // Nur Entsprechenden Debug-Level ausgaben
if(is_string($mode)) // Entweder Mode-Angabe oder Dateiname
if(preg_match('/^(\d+),(.+)$/',$mode,$var)) {
$mode = $var[1];
$file = $var[2];
}
else {
$file = $mode;
$mode = 4;
}
else
$file = false;
$time = ($cfg['dbug'] & 1<<2 and !($mode & 1<<3)) ? number_format(array_sum(explode(' ',microtime()))-$cfg['time'],3,',','.').' ' : '';
if($cfg['dbug'] & 1<<1 and $cfg['dbfn'] and $file) // Debug: Array in separate Datei sichern
if(strpos($file,'#') and is_array($str))
foreach($str as $key => $var) // Debug: Array in mehrere separaten Dateien sichern
file_contents($cfg['dbcd'].str_replace('#',"-".str_replace('#',$key,$file),$cfg['dbfn']),$time.((is_array($var)) ? print_r($var,true) : $var),8);
else
file_contents($cfg['dbcd'].str_replace('#',"-$file",$cfg['dbfn']),$time.((is_array($str)) ? print_r($str,true) : $str),8); // Alles in EINE Datei Sichern
else {
if(is_string($str)) {
if(preg_match('/^\$(\w+)$/',$str,$var) and isset($GLOBALS[$var[1]])) // GLOBALS Variable ausgeben
$str = "$str => ".(is_array($GLOBALS[$var[1]]) ? print_r($GLOBALS[$var[1]],true) : $GLOBALS[$var[1]]);
elseif(!($mode & 1<<1) and preg_match('/\S$/D',$str))// AutoLF
$str .= "\n";
}
elseif(is_array($str))
$str = print_r($str,true);
if($cfg['dbug'] & 1<<1 and $cfg['dbfn']) { // Debug: Ausgabe/Speichern
file_contents($cfg['dbcd'].str_replace('#','',$cfg['dbfn']),$time.$str,8);
if(!$level) // Nur Level 0 Ausgeben
out($time.$str,($mode | 4) & 7);
}
else
out($time.$str,($mode | 4) & 7);
}
}
}
function errmsg($msg=0,$name='main') { // Fehlermeldung(en) Sichern
global $cfg;
if(!ifset($cfg['errmute'])) // Fehleraufzeichnung pausieren?
if($msg) { // Fehlermeldung speichern
dbug("Fehler: $msg",9);
$cfg['error'][$name][] = trim($msg);
}
else { // Letzte Fehlermeldung abrufen
dbug("Suche Fehler von Funktion: $name",9);
if($name == "*" and $var = array_keys($cfg['error']))
$name = end($var); // Letzte Fehlermeldung finden
while(isset($cfg['error'][$name]) and is_array($cfg['error'][$name]))// Fehlermeldung vorhanden?
if($val = end($cfg['error'][$name]) and preg_match('/^\w+$/',$val)) // M�glicher Rekusive Fehlermeldung?
$name = $val; // N�chste Fehlermeldung suchen
else {
if($name != 'main')
$cfg['error']['main'][] = $val;
return (substr($val,0,2) != '1:') ? preg_replace('/^\d+:/','',$val) : false;// Nur Fehlermeldung ohne Error-Code ausgeben
}
}
return ($msg and $name == 'main') ? preg_replace('/^\d+:/','',$msg) : false; // Ohne Funktionsname: Fehler ausgeben oder fehlschlag
}
function phperr($no,$str,$file,$line) { // PHP-Fehler Debuggen
foreach(preg_split("/\s+/","ERROR WARNING PARSE NOTICE CORE_ERROR CORE_WARNING COMPILE_ERROR COMPILE_WARNING
USER_ERROR USER_WARNING USER_NOTICE STRICT RECOVERABLE_ERROR DEPRECATED USER_DEPRECATED UNKNOWN") as $b => $c)
if($no == 1 << $b)
break;
$a = "$str on line $line";
$b = &$GLOBALS["cfg"]["error"][$c][$file];
// $b["backtrace"][] = debug_backtrace();
if(!isset($a,$b) or array_search($a,$b) === false)
$b[] = $a;
return false;
}
function makedir($dir,$mode=1) { // Erstellt ein Verzeichnis und wechselt dorthin
if(!$dir or ifset($dir,$GLOBALS['cfg']['ptar'])) // Self-Dir und Archive nicht bearbeiten
return true;
$dir = preg_replace('/[\\\\\/]+$/','',$dir); // Abschlussshlash entfernen
if(strpos($dir,'%') !== false) // strftime aufl�sen (Problematische Zeichen werden umgewandelt)
$dir = @strftime($dir);
if(preg_match('/^(\w:)?(.*)$/',$dir,$var)) // Windows Verzeichnis Pr�fen
$dir = $var[1].preg_replace('/[<:*|?">]+/','-',$var[2]);
if(!file_exists($dir)) { // Neues Verzeichniss erstellen
if($mode) // Debug-Meldung unterdr�cken
dbug("Erstelle Ordner $dir");
$dirs = preg_split('/[\\\\\/]/',$dir); // Verzeichniskette erstellen
$val = '';
foreach($dirs as $var) {
$val .= $var;
if($val and !file_exists($val))
mkdir($val);
$val .= '/';
}
}
if($mode and is_dir($dir)) { // Aktuelles-Dir setzen
dbug("Wechsle zu Ordner $dir");
chdir($dir);
}
return is_dir($dir) ? $dir : false;
}
function mytouch($mode=false) { // Ermitteln ob fb_Tools wieder nach Updates suchen soll
global $cfg,$script;
$rt = false;
if(is_string($mode)) { // Pr�fen, ob eine Datei geschrieben werden kann
$file = $mode;
if(file_exists($file)) { // Test mit einer Datei, die schon da ist
$new = preg_replace('/(?=\.\w+$)|$/','_test',$file);
if(rename($file,$new)) {
if(file_contents($file,$file) and unlink($file))
$rt = true;
rename($new,$file);
}
}
elseif(file_contents($file,$file) and unlink($file)) // Einfacher Schreibtest
$rt = true;
}
else {
$dbg = ($cfg['upda'] < 0) ? 0 : 9; // Debug-Modus festlegen
$time = time(); // Aktuelle Uhrzeit
$name = "/$cfg[touch]-$cfg[cu]"; // Touch-Dateinamen aus der Konfig holen
$temp = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : (($var = getenv('TEMP')) ? $var : "/tmp");
$array = array_unique(array_merge(array_reverse(array_slice($cfg['fbta'],2)),array_reverse(array_slice($cfg['fbtl'],2)),array_slice($cfg['fbta'],1,1),
array_slice($cfg['fbtl'],1,1),array($script,"$cfg[dir]/$cfg[usrcfg]","$cfg[home]/$cfg[usrcfg]",$cfg['dir'],$cfg['home'],".",$temp)));
# dbug($array,$dbg);
if($mode) { // Datum setzen
foreach($array as $file) // Verschiedene Speicherorte probieren
if(file_exists($file = realpath($file)) and (is_file($file) and @touch($file,$time) or is_dir($file) and @file_contents($file .= $name,"$time") and file_exists($file)) and filemtime($file) == $time) {
dbug("Touch-Datei: '$file' erfolgreich auf '".date('r',$time)."' gesetzt",$dbg);
return true;
}
}
elseif($cfg['upda'] > 0) { // Datum abfragen
$max = filemtime($script); // Das Script selber
array_push($array,$cfg['dir'],$cfg['home']); // Touch-Datei
if($cfg['usrcfg']) // Globale/Lokale Konfig-Datei
array_unshift($array,"$cfg[dir]/$cfg[usrcfg]","$cfg[home]/$cfg[usrcfg]",$cfg['usrcfg'],"$cfg[dir]/.$cfg[usrcfg]","$cfg[home]/.$cfg[usrcfg]",".$cfg[usrcfg]");
if(ifset($cfg['loadcfg'])) // Geladene Konfig-Datei
array_merge((array)explode(',',$cfg['loadcfg']),$array);
array_push($array,"$temp");
$dir = array(); // Pfade auf echte Pfade reduzieren
foreach($array as $file)
if($var = realpath($file))
$dir[$var] = 1;
$array = array_keys($dir);
foreach($array as $var)
if($var and file_exists($var) and (is_dir($var) and $files = glob(realpath($var)."/$cfg[touch]-*") or is_file($var) and $files = array($var)))
foreach($files as $file) {
$max = max($max,filemtime($file)); // Das neuste Datum sichern
dbug("Touch-Datei gefunden: $file",$dbg);
}
dbug("Letztes Touch-Datum: ".date('r',$max),$dbg);
$rt = $time - $max > $cfg['upda']; // Vergleichen
}
}
return $rt; // ALLES ist fehlgeschlagen
}
function otpauth($key,$rep=1,$time=0,$digit=6,$sec=30) {// OTP-Token Generieren f�r Zweite-Faktor-Authentifizierung
dbug("OATH-TOTP-Secret: $key",9,2);
$otp = array();
if(function_exists('hash_hmac') or cfgdecrypt(0,'hashtool')) {
$time = floor(($time ? $time : time()) / $sec); // Zeit auf $sec Sekunden runden
while($rep--) {
$hash = hash_hmac('sha1',str_pad(pack('N*',$time),8,"\0",STR_PAD_LEFT),unBase(strtoupper($key),'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'),true); // Hash aus Zeit und Secret berechnen
$hash = unpack('N',substr($hash,ord(substr($hash,-1)) & 15, 4)); // Hash auf 32 Bits reduzieren
$otp[$time++*$sec] = str_pad(($hash[1] & (1 << 31) - 1) % 1e6,$digit,0,STR_PAD_LEFT);// fertigen Code ausgeben
}
}
else
return errmsg("hash_hmac steht nicht zur verf�gung",__FUNCTION__);
dbug(" -> Token: ".implode(", ",$otp),9);
return (count($otp) == 1) ? reset($otp) : $otp;
}
function xml2array($xml,$attr="_attribute") { // Konvertiert eine XML-Datei in ein Array
if(preg_match_all('/<([\w:.-]+)([^\/>]*)(?:\/>|>\s*((?:[^<]|<(?!\/?\1>)|(?R))*)\s*<\/\1>)/x',$xml,$val)) {
$xml = array();
foreach($val[1] as $key => $var) {
$sub = call_user_func(__FUNCTION__,$val[3][$key],$attr);// Untertag einlesen
if($val[2][$key] and preg_match_all('/([\w:.-]+)="((?:[^"]+|\\\\")*)"/',$val[2][$key],$m))
foreach($m[1] as $k => $v) { // Attribute einlesen
if(is_string($sub))
$sub = $sub ? array($sub) : array();
if($attr)
$sub[$attr][$v] = $m[2][$k];
else
$sub[$v] = $m[2][$k];
}
if(isset($xml[$var])) { // Tag schon vorhanden
if(!isset($xml[$var][0]) or !is_array($xml[$var])) // Noch nicht Nummeriert?
$xml[$var] = array($xml[$var]); // Eintr�ge in Nummer 0 verschieben
elseif(isset($xml[$var][0]) and !is_array($xml[$var][0]) and isset($xml[$var][$attr])) {
$xml[$var][0] = array($xml[$var][0],$attr => $xml[$var][$attr]);
unset($xml[$var][$attr]);
}
$xml[$var][] = $sub; // Tag hinten dran h�ngen
}
else
$xml[$var] = $sub; // Tag normal speichern
}
}
return $xml;
}
function tar2array($file,$preg=false) { // Liest ein Tar-Archiv vom File als Array ein
global $cfg;
if(file_exists($file) and preg_match($cfg['ptar'],$file,$var) and $func = ($cfg['bzip'] and ifset($var[3])) ? array('bzopen','bzread','bzclose')
: array($cfg['zlib']['open'],$cfg['zlib']['read'],$cfg['zlib']['close']) and $fp = call_user_func($func[0],$file,'r')) {
dbug("Entpacke Tar-Archiv aus Datei",9);
$tar = array();
while($meta = call_user_func($func[1],$fp,512) and preg_match('/^[^\0]+/',substr($meta,0,100),$name)) {
$data = substr_replace($meta," ",148,8);
for($crc=$a=0; $a < 512; $crc += ord($data[$a++]));
if($crc != octdec(substr($meta,148,6)))
return errmsg("16:Defektes Tar-Archiv",__FUNCTION__);
if($size = octdec(substr($meta,124,11)))
for($data = "", $a = $size + 512 - $size % 512; $a and ($var = call_user_func($func[1],$fp,$a)) !== false; $a -= strlen($var))
$data .= $var;
if(!$meta[156] and (!$preg or preg_match($preg,$name[0])))
$tar[$name[0]] = substr($data,0,$size);
}
call_user_func($func[2],$fp);
dbug($tar,9,'8,tar2array-#');
return $tar;
}
return errmsg("8:TAR-Archiv nicht gefunden oder l��t sich nicht �ffnen",__FUNCTION__);
}
function datatar2array($tar,$preg=false) { // Parst aus einer Variable ein Tar-Archiv mit Meta-Daten als Array
dbug("Entpacke Tar-Archiv aus Variable",9);
if(preg_match_all('/(\D+)(\d+)/',"name100mode8UID8GID8SIZE12MTIME12CHKSUM8TYPEFLAG1linkname100magic6VERSION2uname32gname32devmajor8devminor8prefix155",$array))
$array = array_combine($array[1],$array[2]);
$out = array();
$pos = 0;
while($pos < strlen($tar) and $tar[$pos] != "\0") {
$meta = array();
$data = substr_replace(substr($tar,$pos,512)," ",148,8);// Buffer ohne Checksumme vorbereiten
for($crc=$a=0; $a < 512; $crc += ord($data[$a++])); // Checksumme berechnen
if($crc != octdec(substr($tar,$pos + 148,6)))
return errmsg("16:Defektes Tar-Archiv",__FUNCTION__);
$a = $pos;
foreach($array as $key => $var) {
if($data = preg_replace('/\0+$/','',substr($tar,$a,$var)))
$meta[strtolower($key)] = (strtoupper($key) == $key and preg_match('/^[0-7]+$/',$data)) ? octdec($data) : $data;
$a += $var;
}
$meta['data'] = substr($tar,$pos + 512,$meta['size']);
if($size = $meta['size'])
$pos += $size + 512 - $size % 512;
$pos += 512;
if(!ifset($meta['typeflag']) and (!$preg or preg_match($preg,$meta['name'])))
$out[$meta['name']] = $meta;
}
return $out;
}
function data2tar($name,$data='',$time=0) { // Erstellt ein Tar-Header
$data = str_pad($name,100,chr(0))."0100777".chr(0).str_repeat(str_repeat("0",7).chr(0),2).str_pad(decoct(strlen($data)),11,"0",STR_PAD_LEFT).chr(0)
.str_pad(decoct($time),11,"0",STR_PAD_LEFT).chr(0)." 0".str_repeat(chr(0),100)."ustar".chr(0)."00".str_repeat(chr(0),247)
.$data.str_repeat(chr(0),(512 - strlen($data) % 512) % 512);
for($a=$b=0; $a<512; $a++)
$b += ord($data[$a]);
return substr_replace($data,str_pad(decoct($b),6,"0",STR_PAD_LEFT).chr(0)." ",148,8);
}
function zip2array($data,$pass=array(),$zip=array(),$x=0) {// Liest ein ZIP-Archiv auf einer Variable als Array ein
global $cfg;
if(is_int($pass)) { // Unterfunktionen f�r zip2array
if($pass >=0) { // le2int (str,pos,len,raw)
$data = strrev(substr($data,intval($pass),$zip ? intval($zip) : 2));
$zip = $x ? $data : hexdec(bin2hex($data));
}
elseif($pass >= -2) { // zipcrypto (str,-[12],array(zipcrc))
$nhash = "";
for($a = 0; $a < strlen($data); $a++) {
if($pass == -2)
$nhash .= chr(ord($data[$a]) ^ call_user_func(__FUNCTION__,$b = $zip[2] | 2,-5,$b ^ 1) >> 8 & 255);
$zip[0] = call_user_func(__FUNCTION__,call_user_func(__FUNCTION__,$nhash ? $nhash[$a] : $data[$a],-3,$zip[0]),-4,0);
$zip[1] = call_user_func(__FUNCTION__,call_user_func(__FUNCTION__,$zip[1] + ($zip[0] & 255),-5,0x8088405) + 1,-4,0);
$zip[2] = call_user_func(__FUNCTION__,call_user_func(__FUNCTION__,chr(call_user_func(__FUNCTION__,$zip[1],-4,24)),-3,$zip[2]),-4,0);
}
if($pass == -2)
$zip = $nhash;
}
elseif($pass == -3) { // crc32 (str,-3,crc)
if(!isset($cfg['czip']))
for($a=0; $a < 256; $cfg['czip'][$a++] = $c)
for($b=0,$c=$a; $b < 8; $b++)
$c = ($c>>1) & 0x7FFFFFFF ^ ($c & 1) * 0xEDB88320;
for($zip = intval($zip), $a=0; $a < strlen($data); $a++)
$zip = $cfg['czip'][($zip ^ ord($data[$a])) & 255] ^ ( $zip >> 8 ) & 0xFFFFFF;
# $zip = substr("0000000".dechex($zip < 0 ? ~$zip : 0xFFFFFFFF + ~ --$zip),-8);
}
elseif($pass == -4) { // urShift (a,-4,b)
if($zip >= 32 or $zip < -32)
$zip %= 32;
elseif($zip < 0)
$zip += 32;
$zip = !$zip ? ($data>>1 & 0x7fffffff) * 2 + ($data>>$zip & 1) : (($data < 0) ? ($data >> 1 & 0x7fffffff | 0x40000000) >> $zip - 1 : $data >> $zip);
}
elseif($pass == -5) // imul (a,-5,b)
$zip = call_user_func(__FUNCTION__,($data >> 16 & 65535) * ($c = $zip & 65535) + ($data &= 65535) * ($zip >> 16 & 65535) << 16,-4,0) + $data * $c;
}
else { // data2zip
if(!$pass and ifset($cfg['zp']))
$pass = $cfg['zp'];
if($pass and (!($aes = cfgdecrypt(0,'aes')) or !preg_array('/^(openssl|mcrypt)$/i',$aes,1) or !(function_exists('hash_pbkdf2') or cfgdecrypt(0,'hashtool'))
or !(function_exists('hash_algos') or !cfgdecrypt(0,'mhash') or !cfgdecrypt(0,'sha256')))) // Ist Verschl�sslung m�glich?
return errmsg("Keine AES-CTR Funktion gefunden",__FUNCTION__);
for($pos = $d = 0; $pos < strlen($data)
and preg_match('/^PK(?:(\x03\x04)|(\x01\x02)|\x05(?:(\x05)|(\x06))|\x06(?:(\x06)|(\x07)|(\x08))|(\x07\x08))()/',substr($data,$pos),$c); $pos += $d) {
if($c[1] and call_user_func(__FUNCTION__,$data,$pos + 4,1) < 52) { // \x03\x04 (Local file header) Bis Version 5.1
$g = (call_user_func(__FUNCTION__,$data,$pos + 6) & 8 and preg_match('/PK\x07\x08.{12}PK[\x01-\x09]{2}/s',substr($data,$pos),$h)) ? $h : 0; // Stream-ZIP Ersatz-Header suchen
$i = substr($data,$pos + 30,$d = $h = call_user_func(__FUNCTION__,$data,$pos + 26)); // Dateiname
$j = strtotime((1980 + (($e = call_user_func(__FUNCTION__,$data,$pos + 10,4))>>25))."-".($e>>21 & 15)."-".($e>>16 & 31)." ".($e>>11 & 31).":".($e>>5 & 63).":".(($e & 31) * 2)); // Datum
$e = substr($data,$pos + 30 + ($d += call_user_func(__FUNCTION__,$data,$pos + 28)),($f = $g ? call_user_func(__FUNCTION__,$g[0],8,4) : call_user_func(__FUNCTION__,$data,$pos + 18,4))); // Gepackte Daten holen (f = l�nge)
$d += 30 + $f; // Offset um Header mit Daten zu �berspringen
if(!(call_user_func(__FUNCTION__,$data,$pos + 6) & ~2062) and (!$e or ($e = (($f = call_user_func(__FUNCTION__,$data,$pos + 8)) == 8) ? gzinflate($e)// Flags abfragen
: (($f == 12 and $cfg['bzip']) ? bzdecompress($e) : (!$f ? $e : "")))) // UnZip
and strlen($e) == ($g ? call_user_func(__FUNCTION__,$g[0],12,4) : call_user_func(__FUNCTION__,$data,$pos + 22,4)) // Stimmt die L�nge?
and (hash('crc32b',$e,1) == ($g ? call_user_func(__FUNCTION__,$g[0],4,4,1) : call_user_func(__FUNCTION__,$data,$pos + 14,4,1)))) { // Entpackte Daten korrekt?
if(substr($i,-1) != "/")
$zip[$i] = $x ? $e : array('data' => $e, 'mtime' => $j); // Entpackte Daten & Datum sichern
$i = 0;
}
else if(!$g and !(($g = call_user_func(__FUNCTION__,$data,$pos + 6)) & ~2055) and $g % 2 and call_user_func(__FUNCTION__,$data,$pos + 8) == 99 and substr($data,$g = $pos + 30 + $h,2) == "\x01\x99" // AES-ZIP
and (($f = call_user_func(__FUNCTION__,$data,$g + 4)) == 2 and !call_user_func(__FUNCTION__,$data,$pos + 14,4) or $f == 1) and $f = call_user_func(__FUNCTION__,$data,$g + 8,1) and $f = ++$f * 64) { // f: AES-Bits / g: offset extra-header
if(!$pass)
return errmsg("Archiv ben�tigt ein Kennwort (-zp:'password')",__FUNCTION__);
foreach($pass as $pw) // Password-manager befragen
if(substr(($c = hash_pbkdf2("sha1",$pw,substr($e,0,$f >> 4),1e3,$f / 4 + 16,1)),$f / 4,2) == substr($e,$f >> 4,2))// Kennwort-Hash erstellen und testen
break;
else
$pw = false;
if($c and $pw and substr($c,$f / 4,2) == substr($e,$f >> 4,2) and substr(hash_hmac("sha1",$h = substr($e,$f / 16 + 2, strlen($e) - ($f / 16 + 2) - 10),substr($c,$f / 8, $f / 8),1),0,10) == substr($e,-10)) {
for($e = ""; strlen($e) < strlen($h); ) {
$b = array(substr($h,strlen($e),16),substr($c,0,$f/8),str_pad(pack('V',(strlen($e) >> 4) + 1),16,chr(0)));
if(isset($aes['openssl']))
$e .= openssl_decrypt($b[0],"aes-$f-ctr",$b[1],OPENSSL_RAW_DATA,$b[2]);
elseif(isset($aes['mcrypt'])) // Extension: MCrypt
$e .= mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$b[1],$b[0],'ctr',$b[2]);
else
break;
}
if(($e = (($c = call_user_func(__FUNCTION__,$data,$g + 9)) == 8) ? gzinflate($e) : (($c == 12 and $cfg['bzip']) ? bzdecompress($e) : (!$c ? $e : "")) or $e === "")// UnZip
and strlen($e) == call_user_func(__FUNCTION__,$data,$pos + 22,4) and (($c = call_user_func(__FUNCTION__,$data,$g + 4)) == 1 and call_user_func(__FUNCTION__,$data,$pos + 14,4,1) == hash('crc32b',$e,1) or $c == 2)) { // L�nge & Optional CRC32 �berpr�fen
if(substr($i,-1) != "/") // Nur Dateien eintragen
$zip[$i] = $x ? $e : array('data' => $e, 'mtime' => $j, 'pass' => $pw, 'bits' => $f); // Entpackte Daten & Datum sichern
$i = 0;
}
else
return errmsg("Entschl�sselung ist fehlgeschlagen",__FUNCTION__);
}
else
return errmsg("Das Kennwort ist falsch",__FUNCTION__);
}
else if(($g = call_user_func(__FUNCTION__,$data,$pos + 6)) % 2 and !($g & ~2063) and call_user_func(__FUNCTION__,$data,$pos + 14,4)) { // Crypto-ZIP
if(!$pass)
return errmsg("Archiv ben�tigt ein Kennwort (-zp:'password')",__FUNCTION__);
foreach($pass as $pw) {// Password-manager befragen
$f = call_user_func(__FUNCTION__,$pw,-1,array(0x12345678,0x23456789,0x34567890));
if(substr($data,$pos + ($g & 8 ? 11 : 17),1) == substr($f = call_user_func(__FUNCTION__,$e,-2,$f),11,1)) // Kennwort-Hash erstellen und testen
break;
else
return errmsg("Das Kennwort ist falsch",__FUNCTION__);
}
if($f and (!($e = substr($f,12)) or ($e = ($f = call_user_func(__FUNCTION__,$data,$pos + 8)) == 8 ? gzinflate($e) : (($f == 12) ? bzdecompress($e) : (!$f ? $e : "")))// UnZip
and strlen($e) == call_user_func(__FUNCTION__,$data,$pos + 22,4) and hash('crc32b',$e,1) == call_user_func(__FUNCTION__,$data,$pos + 14,4,1))) { // L�nge & CRC32 �berpr�fen
if(substr($i,-1) != "/") // Nur Dateien eintragen
$zip[$i] = $x ? $e : array('data' => $e, 'mtime' => $j, 'pass' => $pw, 'bits' => $f); // Entpackte Daten & Datum sichern
$i = 0;
}
}
if($i)
$data .= 0; // Fehler erkennen (Sourcel�nge ver�ndern)
}
else // Alle Header werden �bersprungen (Ignoriert)
$d = $c[2] ? 46 + call_user_func(__FUNCTION__,$data,$pos + 28) + call_user_func(__FUNCTION__,$data,$pos + 30) + call_user_func(__FUNCTION__,$data,$pos + 32)// \x01\x02 (Central directory file header)
: ($c[3] ? call_user_func(__FUNCTION__,$data,$pos + 4) + 6 // \x05\x05 (Digital signature)
: ($c[4] ? call_user_func(__FUNCTION__,$data,$pos + 20) + 22 // \x05\x06 (End of central directory record)
: ($c[5] ? call_user_func(__FUNCTION__,$data,$pos + 4,8) + 12 // \x06\x06 (Zip64 end of central directory record)
: ($c[6] ? 20 // \x06\x07 (Zip64 end of central directory locator)
: ($c[7] ? call_user_func(__FUNCTION__,$data,$pos + 4,4) + 8 // \x06\x08 (Archive extra data record)
: ($c[8] ? 16 : 1)))))); // \x07\x08 (Stream-Header: crc32, df-len, if-len)
}
# dbug($zip,9,'8,zip2array-#');
if($pos != strlen($data))
$zip = errmsg("Archiv ist besch�digt oder wird nicht unterst�tzt",__FUNCTION__);
}
return $zip;
}
function data2zip($files,$pass=false,$time=false) { // Erstellt aus ein Array ein ZIP-Archiv
global $cfg;
if(!is_array($files))
return errmsg("Unbekannte Parameter",__FUNCTION__);
if(!$pass and ifset($cfg['zp'])) // Password von Optionen �bernehmen
$pass = $cfg['zp'] ? reset($cfg['zp']) : false;
if($pass) // Pr�fen ob Verschl�sselung �berhaupt m�glich ist
if(!$aes = cfgdecrypt(0,'aes') or !preg_array('/^(openssl|mcrypt)$/i',$aes,1) or !(function_exists('hash_pbkdf2') or cfgdecrypt(0,'hashtool'))
or !(function_exists('hash_algos') or !cfgdecrypt(0,'mhash') or !cfgdecrypt(0,'sha256')) or !$cfg['zb']) // Ist Verschl�sslung m�glich?
return errmsg("Keine m�glichkeit gefunden die AES-CTR Funktion auszuf�hren",__FUNCTION__);
$zip = $dir = ""; // Leeres Zip-Archiv
foreach($files as $file => $meta) { // Array durchgehen
if(!is_array($meta))
$meta = array('data' => $meta);
$time = isset($meta['time']) ? $meta['time'] : ($time ? $time : time());
$m = "";
$i = strlen($meta['data']) ? ($cfg['bz'] ? bzcompress($meta['data'],$cfg['bz']) : ($cfg['gz'] ? gzdeflate($meta['data'],$cfg['gz']) : "")) : ""; // Deflate Data
if(!$i or strlen($i) > strlen($meta['data'])) // Store Data?
$i = $meta['data'];
if($pass) { // Verschl�sselung AES-AE2 (128/192/256)
$jk = function_exists("openssl_random_pseudo_bytes") ? openssl_random_pseudo_bytes($cfg['zb']/8) : sha1(mt_rand().time()); // key
$js = substr(hash_hmac('sha256',$file.time().serialize($meta).$pass,$jk,1),0,$cfg['zb']/16);
$jh = hash_pbkdf2("sha1",$pass,$js,1e3,$cfg['zb']/4+16,1); // (48,64,80)
for($k = $m; strlen($k) < strlen($i);) {
$b = array( substr($i,strlen($k),16), // Data
substr($jh,0,$cfg['zb'] / 8), // Key
str_pad(pack('V',(strlen($k) >> 4) + 1),16,"\0")); // Counter
if(isset($aes['openssl']))
$k .= openssl_encrypt($b[0],"aes-$cfg[zb]-ctr",$b[1],OPENSSL_RAW_DATA,$b[2]);
elseif(isset($aes['mcrypt']) and $x = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'','ctr','')) { // Extension: MCrypt
mcrypt_generic_init($x, $b[1], $b[2]); // https://github.com/beyonderyue/aes-ctr-php
$k .= mcrypt_generic($x, $b[0]);
mcrypt_generic_deinit($x);
mcrypt_module_close($x);
}
else
break;
}
$m = "\1\x99\7\0\2\0AE".chr($cfg['zb']/64-1).chr((strlen($k) == strlen($meta['data'])) ? 0 : ($cfg['bz'] ? 12 : 8))."\0"; // Extra-Data Header
$i = $js.substr($jh,$cfg['zb'] / 4,2).$k.substr(hash_hmac("sha1",$k,substr($jh,$cfg['zb'] / 8,$cfg['zb'] / 8),1),0,10);// Salt + Chk + Cipher + Hash
}
$k = (($k = utf8($file)) != $file) ? $k : $file;
$j = ($m ? "\x33" : (($i != $meta['data']) ? chr($cfg['bz'] ? 46 : 20) : "\n"))."\0"
.pack("v",(($k != $file) ? 2048 : 0) | ($m ? 1 : 0)).($m ? "c" : chr(($i != $meta['data']) ? ($cfg['bz'] ? 12 : 8) : 0))."\0"
.pack('v*',intval(date('G',$time)) * (1<<11) + intval(date('i',$time)) * (1<<5) + (intval(date('s',$time)) >>1),// Time
(intval(date('Y',$time)) - 1980) * (1<<9) + intval(date('n',$time)) * (1<<5) + intval(date('j',$time))) // Date
.strrev(!$m ? hash("crc32b",$meta['data'],1) : pack("V",0)) // CRC32
.pack('V*',strlen($i),strlen($meta['data'])).pack('v*',strlen($k),strlen($m));
$dir .= "PK\1\2\0\0$j".str_repeat("\0",10).pack('V',strlen($zip)).$k.$m; // Central directory file header
$zip .= "PK\3\4$j$k$m$i"; // Local file header
}
return $zip.$dir."PK\5\6\0\0\0\0".str_repeat(pack('v',count($files)),2).pack('V*',strlen($dir),strlen($zip))."\0\0";
}
function json2array($str,$o=array(),$s=array(),$c=0) { // JSON-Parser mit UTF8-Decoder
global $cfg;
if(is_array($str)) // Decode UTF8
$o = $str[1] ? chr(strpos("01234567btnvfr",$str[1])) : utf8(array($str[4] ? (hexdec($str[4]) & 1023) * 1024 + (hexdec($str[5]) & 1023) + 65536 : hexdec("$str[2]$str[3]$str[6]")));
elseif(function_exists("json_decode") and !$o and $v = json_decode($str,true,$cfg['jsdp'])) // PHP-Funktion nutzen
$o = $v;
else // Parse JSON
while(preg_match('/^\s*(?:(?:(["\']?)(?![-.\d])([^!-,\/;-@\[-^\]`\{|\}\s]*)(? $cfg['jsdp'])
return errmsg("16:Arrays oder Objekte zu tief verschachtelt ($cfg[jsdp])",__FUNCTION__);
$s[] = $k = array($o,$s ? $v[0]: null,$m[3]);
$o = array();
$v = false;
}
elseif($m[10]) {
if(!($k = is_array($s) ? end($s) : false) or $k[2] != '[' and $m[10] == ']' or $k[2] != '{' and $m[10] == '}')
return errmsg("16:Array oder Objekt falsch geschlossen",__FUNCTION__);
if($k[1])
$k[0][$k[1]] = $o;
elseif(is_null($k[1]))
$k[0] += $o;
else
$k[0][] = $o;
$o = $k[0];
array_pop($s);
$v = false;
}
elseif($x = strtolower($m[4]))
$v[] = ($x == 'null') ? null : $x == 'true';
elseif($m[5] != '')
$v[] = $m[6] ? floatval($m[5].$m[6]) : intval($m[5]);
elseif($m[7])
$v[] = preg_replace_callback('/\\\\(?:([0-7btnvfr])|(x[\da-f]{2})|u\{([\da-f]+)\}|(?:u(d[89ab][\da-f]{2})\\\\u(d[cdef][\da-f]{2})|u([\da-f]{4})))(\b|\B)/i',__FUNCTION__,preg_replace("/\\\\($m[7])/",'$1',$m[8]));
elseif($m[9])
$v[] = $m[9];
else
$v = false;
if($v)
if($v[0])
$o[$v[0]] = $v[1];
elseif($k[2] == '[')
$o[] = $v[1];
}
return $o;
}
function textTable($table,$cols=0,$col="|",$row="\n",$tab=" ",$sp=" ") { // Text als Text-Tabelle konvertieren
if($cols == -1) // Creole-Aufruf
return preg_replace_callback('/\{\{\{(?:tt|77)((?:,[^,\}]*)*)\}(.*?)\}\}/s',__FUNCTION__,$table);
elseif(is_array($table)) { // Creole-Funktion
if($var = ifset($table[1],'/,([^,]*)/a')) {
array_unshift($var[1],$table[2]);
$opts = $var[1];
if(ifset($opts[4],'/;/'))
$opts[4] = explode(';',$opts[4]);
if(ifset($opts[5],'/;/'))
$opts[5] = explode(';',$opts[5]);
}
else
$opts = array($table[2]);
return call_user_func_array(__FUNCTION__,$opts);
}
elseif(!$cols and $cols = $GLOBALS['cfg']['wrap'])
$cols -= 2;
$esc = array();
$pos = 0;
$p = "[\x80-\xbf]";
while(preg_match("/\x7f|[\xc0-\xdf]$p|[\xe0-\xef]$p{2}|[\xf0-\xf7]$p{3}|[\xf8-\xfb]$p{4}|[\xfc-\xfd]$p{5}|\xfe$p{6}
|\\\\(u\{[\da-f]+\}|ud[89ab][\da-f]{2}\\\\ud[cdef][\da-f]{2}|u[\da-f]{4})|(&\#(\d+|x[\da-f]+);)/x",substr($table,$pos),$m,PREG_OFFSET_CAPTURE)) {
$table = substr_replace($table,"\x7f",$pos + $m[0][1], strlen($m[0][0]));
$esc[] = $m[0][0];
$pos += $m[0][1] + 1;
}
$lines = explode($row,trim($table));
$lens = $max = $min = $ali = $table = array();
$col = array('/(? $line) {
$table[$kl] = preg_replace($col[1],'',preg_split($col[0],$line));
foreach($table[$kl] as $kr => $rift)
if(preg_match('/^(\s*)(.*?)(\s*)$/',$rift,$var)) {
$table[$kl][$kr] = $var[2];
$ali[$kl][$kr] = ($var[1] and $var[3]) ? STR_PAD_BOTH : (($var[1] and !$var[3]) ? STR_PAD_LEFT : STR_PAD_RIGHT);
$max[$kr] = max((isset($max[$kr])) ? $max[$kr] : 0, strlen($var[2]));
}
}
if($cols and array_sum($max) + count($max) -1 > $cols) {
$cols = max($cols,count($max) * 2);
foreach($table as $kl => $line)
foreach($line as $kr => $rift)
$min[$kr] = max((isset($min[$kr])) ? $min[$kr] : 0,max($lens[$kl][$kr] = array_map('strlen',explode((is_array($sp)) ? $sp[$kr] : $sp,$table[$kl][$kr]))));
while(($cols and array_sum($max) + count($max) -1 > $cols) and array_sum($max) > array_sum($min)) {
$mlen = array();
foreach($lens as $kl => $line) {
$var = count($line) -1;
$key = array();
foreach($line as $kr => $rift) {
$var += array_sum($rift) + count($rift) -1;
if(!$key or $key[1] < count($rift))
$key = array($kr,count($rift));
}
if(!$mlen or $mlen[1] <= $var and $mlen[3] < $key)
$mlen = array_merge(array($kl,$var),$key);
}
if($mlen)
array_pop($lens[$mlen[0]][$mlen[2]]);
else
break;
$max = $min;
foreach($lens as $kl => $line)
foreach($line as $kr => $rift)
$max[$kr] = max((isset($max[$kr])) ? $max[$kr] : 0, array_sum($rift) + count($rift) -1);
}
while(array_sum($max) + count($max) -1 > $cols)
$max[array_search(max($max),$max)]--;
}
$out = array();
foreach($table as $tk => $line) {
$wrap = 0;
foreach($line as $key => $var) {
$line[$key] = explode($row,wordwrap($var,$max[$key],$row,true));
$wrap = max($wrap,count($line[$key]));
}
for($a=0; $a < $wrap; $a++) {
$buf = "";
foreach($line as $key => $var)
$buf .= str_pad((isset($line[$key][$a])) ? $line[$key][$a] : "",$max[$key],(is_array($sp)) ? $sp[$key] : $sp,$ali[$tk][$key]).((is_array($tab)) ? $tab[$key] : $tab);
$out[] = rtrim($buf);
}
}
$table = implode($row,$out);
$m = 0;
while(($m = strpos($table,"\x7f",$m)) !== false) {
$table = substr_replace($table,$esc[0],$m,1);
$m += strlen(array_shift($esc));
}
return $table;
}
function request($method,$page='/',$body=0,$head=0,$host=0,$port=0,$sock=0,$user=0,$pass=0) { // HTTP-Request durchf�hren
global $cfg;
if(!$method) { // Unterfunktion: HTTP Auth zusammenstellen ($page,$arg,$auth)
if(is_string($head) and preg_match('/^(\w+)\s+(.*)$/',$head,$m)) { // Erste Anmeldung
$head = array();
$m[1] = strtolower($m[1]);
if($m[1] == 'basic') {
$head['username'] = $body['user'];
$head['password'] = $body['pass'];
$head[$m[1]] = "Basic ".base64_encode(implode(":",$head)); // Absolut unknackbar ;-)
$cfg['auth'] = $head;
}
elseif($m[1] == 'digest' and preg_match_all('/(\w+)\s*=\s*(\\\\?["\']?)(.*?)\2(,\s*|\s*$)/',$m[2],$m)) {// HTTP Auth Digest
dbug($m,4);
$head = array_merge(array(
'username' => $body['user'],
'nc' => 0,
'cnonce' => substr(hash('md5',time().rand()),16),
),array_combine($m[1],$m[3]));
}
if(isset($head['username']))
dbug("HTTP Auth ".((isset($head['basic'])) ? "Basic" : "Digest")." f�r $head[username]",5);
}
if(is_array($head))
if(isset($head['basic'])) // HTTP Auth Basic
$method = $head['basic'];
elseif(isset($head['username'])) { // HTTP Auth Digest
$head['nc'] = str_pad(intval($head['nc']) + 1,8,0,STR_PAD_LEFT); // Z�hler erh�hen
$head['uri'] = $page; // Aktuelle Seite
$hash = (ifset($head['algorithm'])) ? strtolower(str_replace('-','',$head['algorithm'])) : 'md5';// Hash Methode festlegen
if($head['response'] = hash($hash,hash($hash,"$head[username]:$head[realm]:$body[pass]")
.":$head[nonce]:$head[nc]:$head[cnonce]:$head[qop]:".hash($hash,strtoupper(preg_replace('/-.*/','',$body['method'])).":$page"))) {
$cfg['auth'] = $head; // Werte sichern
foreach($head as $key => $var)
$head[$key] = "$key=\"$var\"";
$method = "Digest ".implode(', ',$head); // Anmeldedaten zusammenstellen
}
}
return $method;
}
elseif(is_array($method)) // Parameter aus Array holen
extract($method);
elseif(is_string($method) and $val = ifset($method, // Parameter aus String holen (GET-array)
'/^(https?):(?:\[([^\[\s\]]+)\])?\/\/(?:([^@:\s]+):)?(?:([^@\s]+)@)?
((?:(?!-)[a-z\d-]+(? $var)
if($var and ifset($val[$key+1]))
$$var = $arg[$var] = ($var == 'host') ? preg_replace('/^\[|\]$/','',$val[$key+1]) : $val[$key+1];
$method = (ifset($mode)) ? $mode : 'GET';
if(!$port) // Port festlegen
$port = $arg['port'] = ($sock == 'http') ? 80 : 443;
if($val[10])
return $arg;
}
foreach(explode(',','sock,host,port,user,pass') as $var)// Host, Port, user & pass setzen
if(!$$var)
$$var = $cfg[$var];
if(!$head) // Head Initialisieren
$head = $cfg['head'];
if($mode = preg_match('/^(\w+)(?:-(.+))?/',$method,$var)) {
$method = strtoupper($var[1]);
$mode = (isset($var[2])) ? $var[2] : (($var[1] == strtolower($var[1])) ? 'array' : false);// Result-Modus festlegen
}
$arg = array_flip(explode(',','method,mode,sock,host,port,page,head,body,user,pass'));// Parameter sichern
foreach($arg as $key => $var)
$arg[$key] = $$key;
$http = $sock;
if($sock = ($sock == 'auto' and ($port == 80 or $port == 8080 or $port == 49000) or $sock == 'http') ? '' : ((ifset($sock,'/^(ssl|tls)$/')) ? "$sock://" : 'ssl://'))
if(!$cfg['ssl'])
if($var = cfgdecrypt(0,'openssl')) {
$cfg['ssl'] = $var;
dbug("OpenSSL nachgeladen: $var",9);
}
else
return errmsg("8:OpenSSL nicht verf�gbar",__FUNCTION__);
if($var = ifset($cfg['proxy'],'/^([\w.-]+):(\d+)$/')) {// Primitive Proxy-Umleitung
if(!isset($cfg['http']))
dbug("Benutze Proxy: $var[0]",9);
$page = "http".($sock ? "s" : "")."://$host:$port$page";
$head['host'] = $host; // .($sock ? ":$port" : "");
$host = $var[1];
$port = $var[2];
}
dbug("$sock$host:$port",5);
if(!isset($cfg['fail']["$host:$port"]) and function_exists('stream_socket_client')
and $fp = @stream_socket_client(($sock ? $sock : "tcp://")."$host:$port",$errnr,$errstr,$cfg['tout'],
STREAM_CLIENT_CONNECT,stream_context_create((ifset($http,'/auto|https/i'))
? array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false)) : array()))
or $fp = @fsockopen($sock.$host,$port,$errnr,$errstr,$cfg['tout'])) {// Verbindung aufbauen
if($cfg['tout'])
stream_set_timeout($fp,$cfg['tout']); // Timeout setzen
// stream_set_blocking($fp,0);
if($method == 'POST') { // POST-Request vorbereiten
if(is_array($body)) { // Multipart-Post vorbereiten
$row = "---".hash('md5',rand().time());
foreach($body as $key => $var) {
$val = array('','');
if(is_array($var)) // Unter-Header im Header
foreach($var as $k => $v)
if($k == '') // Content
$var = $v;
elseif($k == 'filename') // Weitere Angaben im Header
$val[0] .= "; $k=\"$v\"";
else // Sub-Header
$val[1] = "$k: $v\r\n";
$body[$key] = "$row\r\nContent-Disposition: form-data; name=\"$key\"$val[0]\r\n$val[1]\r\n$var\r\n";
}
$body = implode('',$body)."$row--\r\n";
$var = "multipart/form-data; boundary=$row";
}
else
$var = 'application/x-www-form-urlencoded'; // Standard Post
if(!isset($head['content-type']))
$head['content-type'] = $var;
if(!isset($head['content-length']))
$head['content-length'] = strlen($body);
$body = "\r\n$body";
}
elseif($method == 'GET' and $body) { // GET-Request vorbereiten
if(is_array($body)) {
$val = array();
foreach($body as $key => $var)
$val[] = urlencode($key)."=".urlencode($var);
$body = implode('&',$val);
}
$page .= "?$body";
$body = "\r\n";
}
elseif($method == 'PUT' and $body) { // PUT-Request vorbereiten
if(!isset($head['content-type']) and preg_match('/^\{.*\}$/s',$body))
$head['content-type'] = 'application/json';
if(!isset($head['content-length']))
$head['content-length'] = strlen($body);
}
else
$body = "\r\n";
if(!isset($head['host'])) // Host zum Header hinzuf�gen
$head['host'] = $host;
if($cfg['auth'] and $auth = call_user_func(__FUNCTION__,0,$page,$arg,$cfg['auth']))// HTTP Auth in folge
$head['Authorization'] = $auth;
if(!isset($head['connection'])) // Connection zum Header hinzuf�gen
$head['connection'] = "close";
foreach($head as $key => $var) { // Header vorbereiten
$k = $key;
if($cfg['php'][3] > 5.3)
$k = ucwords($key,'-');
elseif(preg_match_all('/(?<=^|-)[a-z]/',$k,$m,PREG_OFFSET_CAPTURE)) // ucwords f�r PHP 5.3 und �lter
for($a=count($m[0])-1; $a >= 0; $a--)
$k = substr_replace($key,strtoupper($m[0][$a][0]),$m[0][$a][1],strlen($m[0][$a][0]));
$head[$key] = "$k: $var";
}
$sp = preg_match('/^(?:save|down(?:load)?):(.*?(\.gz)?)$/i',$mode,$file);
$head = "HTTP/1.1\r\n".implode("\r\n",$head)."\r\n"; // Header Finalisieren
dbug("$method $page".(($cfg['dbug'] & 1<<7) ? " $head$body\n\n" : ''),5,__FUNCTION__);// Debug Request
fwrite($fp,"$method $page $head$body"); // Request Absenden
if($mode == 'putonly') // Nur Upload durchf�hren
return fclose($fp);
$head = array();
$header = "";
while($a = trim($b = fgets($fp,$cfg['sbuf']))) { // Alle Header herunterladen
$header .= $b;
if(preg_match('/^([\w-]+):\s*(.*)$/',$a,$b))
$head[ucwords($b[1])] = $b[2];
elseif(preg_match('!^HTTP/[\d.]+\s*(\d+)\s*(.+?)\s*$!im',$a,$b)) {// HTTP_Code abfangen
$head[] = $a;
$head['HTTP_Code'] = $b[1]; // Error-Code
$head['HTTP_Info'] = $b[2]; // Error-Name
}
}
if(!isset($head['HTTP_Code'])) { // Request fehlgeschlagen und als Timeout Kennzeichnen
$head['HTTP_Code'] = 504;
$head['HTTP_Info'] = "Timeout";
}
$cfg['http'] = $head; // Header Global sichern
if($method == 'HEAD' or $mode == 'header') { // Nur Header herunterladen
fclose($fp);
return $head;
}
if($head['HTTP_Code'] >= 400) { // Blacklist erkennen
fclose($fp);
if($head['HTTP_Code'] == 401 and !isset($arg['head']['Authorization']) and isset($head['WWW-Authenticate'])
and $auth = call_user_func(__FUNCTION__,0,$page,$arg,$head['WWW-Authenticate'])) {// HTTP Auth
$arg['head']['Authorization'] = $auth;
return call_user_func(__FUNCTION__,$arg);
}
return errmsg("16:HTTP-Fehler: $head[HTTP_Code] $head[HTTP_Info] $page",__FUNCTION__);
}
$size = (ifset($head['Content-Length'])) ? $head['Content-Length'] : 0;
$rp = "";
if($sp) { // Download -> Datei
$gz = ifset($file[2]); // GZip komprimieren?
if(!feof($fp)) { // Nur weitermachen wenn noch Daten kommen
$file[1] = preg_replace('/(?<=[\\\\\/])$|^\.?$/',preg_replace($cfg['fesc'],$cfg['frep'],(ifset($file[1],'/^[.\\\\\/]*$/')
and $var = ifset($head['Content-Disposition'],'/^(?:attachment;\s*)?filename=(["\']?)(.*?)\1$/mi'))
? $var[2] : basename(urldecode($page))),$file[1]);
dbug("Downloade '".basename($file[1])."'".($size ? " ".number_format($size,0,'.',',')." Bytes" : ""));
$a = $b = 0; // Antwort vorbereiten
if($sp = $gz ? $cfg['zlib']['open']($file[1],'w'.$cfg['zlib']['mode']) : fopen($file[1],'w')) {
if(ifset($head['Transfer-Encoding'],'chunked')) // Chunked decodieren
while(!feof($fp) and $var = fgets($fp,$cfg['sbuf'])) { // Chunk-L�nge holen
$len = (preg_match('/^([\da-f]+)\s*$/i',$var,$m)) ? hexdec($m[1]) : 0; // Chunk-L�nge ermitteln
while(!feof($fp) and $buf = ($len > $cfg['sbuf']) ? $cfg['sbuf'] : $len) { // Buffer-L�nge nicht �berschreiten
$len -= $buf; // Restl�nge bestimmen
$var = ""; // Buffer setzen
while(strlen($var) < $buf) // Soll-Daten WIRKLICH gelesen?
$var .= fread($fp,$buf-strlen($var)); // Daten in Buffer lesen
if($gz) // Buffer schreiben
$cfg['zlib']['write']($sp,$var);
else
fwrite($sp,$var);
$a += strlen($var); // Fortschritts-Anzeige berechnen
$c = $size ? floor($a / max($a,$size) * max($cfg['wrap']-1,10)) - $b : 1;
dbug(str_repeat(".",$c),0,10); // Download-Anzeige
$b += $c;
}
fgets($fp,$cfg['sbuf']); // Pad-Daten �berspringen
}
else // Normaler Download
while(!feof($fp) and $var = fread($fp,$cfg['sbuf'])) {
if($gz)
$cfg['zlib']['write']($sp,$var);
else
fwrite($sp,$var);
$a += strlen($var);
$c = $size ? floor($a / max($a,$size) * max($cfg['wrap']-1,10)) - $b : 1;
dbug(str_repeat(".",$c),0,10); // Download-Anzeige
$b += $c;
}
if($gz)
$cfg['zlib']['close']($sp);
else
fclose($sp);
dbug("\n",0,8); // Download-Anzeige abschlie�en
if(!$a) { // Wurde wirklich was heruntergeladen?
unlink($file[1]);
return errmsg("8:Download Fehlgeschlagen: Keine Daten erhalten",__FUNCTION__);
}
else
touch($file[1],(isset($head['Last-Modified'])) ? strtotime($head['Last-Modified']) : time());
}
else
return errmsg("32:$file[1] kann nicht zum Schreiben ge�ffnet werden",__FUNCTION__);
}
else
return errmsg("8:Download abgebrochen: Keine Daten erhalten",__FUNCTION__);
}
else { // Daten nur lesen
if(preg_match('/^seek:([-+]?)(\d+)(?:-(\d+))?$/i',$mode,$var)) {// Nur einen Teil lesen (Seek:-+-)
fseek($fp,intval($var[2]),(ifset($var[1])) ? SEEK_CUR : SEEK_SET);
if(ifset($var[3]))
$size = intval($var[3]);
}
while(!feof($fp) and $var = fread($fp,$cfg['sbuf'])) {
$rp .= $var;
dbug(".",6,10); // Download-Anzeige
}
$meta = stream_get_meta_data($fp);
if($meta['timed_out'] )
$err = "Timeout: Keine Reaktion nach $cfg[tout] Sekunden";
elseif(!$meta['eof']) // Sollte nie auftreten und macht bei ssl probleme
while($meta = stream_get_meta_data($fp) and !$meta['eof']) // Solange was runterladen bis es NICHTS mehr gibt
while(!feof($fp) and $var = fread($fp,$cfg['sbuf'])) {
$rp .= $var;
dbug(".",6,10); // Download-Anzeige
}
if(ifset($head['Transfer-Encoding'],'chunked')) // Chunked decodieren
for($vas=$rp, $rp=''; $vas; $vas=trim($vas)) {
$rp .= substr($vas,$pos = strpos($vas,"\r\n") +2,$len = intval($vas,16));
$vas = substr($vas,$pos + $len);
}
}
if(ifset($err))
dbug($meta,7,'Stream-Metadata');
fclose($fp);
dbug("\n",6,8); // Download-Anzeige abschlie�en
dbug((($cfg['dbug'] & 1<<7) ? "$header$rp" : preg_replace('/\n.*$/s','',"$header\n$rp"))."\n\n",6,__FUNCTION__);// Debug Response
$cfg['body'] = $rp; // Download-Content in Globale Variable sichern
if($mode == 'array') { // Ausgabe mit HTTP-Header
$fp = $head;
$fp[1] = $rp;
}
elseif(substr($mode,0,4) == 'save')
$fp = $head;
else // Nur Netto-Daten zur�ckgeben
$fp = $rp;
}
else {
$err = "$host:$port - Fehler $errnr: $errstr";
if(!isset($cfg['fail']["$host:$port"]))
$cfg['fail']["$host:$port"] = "$errnr: $errstr";
}
if(ifset($err))
errmsg("16:$err",__FUNCTION__);
return $fp;
}
function login($pass=0,$user=0,$uipw=0,$sid=0) { // In der Fritz!Box einloggen
global $cfg;
if(is_array($pass)) { // Login-Response berechnen
dbug($pass[0],6);
$preg = "(2(\\$\\d+\\$[\\da-f]+){2}|[\\da-f]+)"; // Ausdruck um Challenge zu erhalten
if(preg_match("!$preg !i",$pass[0],$var)
or preg_match("/(?:security:status\/challenge.*?|\"?challenge\"?:)\"?$preg\"?,?\s*(\"|$)/mi",$pass[0],$var)) {
dbug("Kodiere Kennwort aus Challenge: $var[1] - OS ".(($var[1][1] == '$') ? '7.24' : '4.74'),9);
$hash = (function_exists('hash_pbkdf2') and substr($var[1],0,2) == '2$' and $var = explode('$',$var[1]))
? "response=$var[4]$".hash_pbkdf2('sha256',hash_pbkdf2('sha256',utf8($pass[1],1),pack("H*",$var[2]),$var[1],32,true),pack("H*",$var[4]),$var[3],64,false) // Ab OS7.24
: "response=$var[1]-".hash('md5',preg_replace('!.!',"\$0\0","$var[1]-$pass[1]")); // Ab OS4.74
if($pass[2] and $cfg['fiwa'] == 100)
$cfg['fiwa'] = (substr($pass[2],-4) == '.lua') ? (isset($var[4]) ? '724' : '530') : '474';
dbug($hash,9);
return $hash;
}
else
return errmsg("12:Keine Challenge erhalten (".((substr($pass[2],-4) == '.lua') ? 'lua' : 'xml').")",__FUNCTION__);
}
elseif(is_bool($pass) and !$pass and !$sid) { // Firmware-Version ermitteln
if($cfg['fiwa'] == 100) {
dbug("Ermittle Boxinfos");
if($data = request('GET','/jason_boxinfo.xml') and preg_match_all('/<([jeq]:(\w+))>([^<>]+)<\/\1>/m',$data,$array)) { // BoxInfos holen
dbug($array,4);
$cfg['boxinfo'] = array_combine($array[2],$array[3]);
$cfg['boxinfo']['Time'] = strtotime($cfg['http']['Date']);
if(preg_match('/^\d+\.0*(\d+?)\.(\d+)(-\d+)?$/',$cfg['boxinfo']['Version'],$var)) // Firmware-Version sichern
$cfg['fiwa'] = $var[1].$var[2];
}
}
return (($fw = $cfg['fiwa']) != 100 and ($user and $fw < $user or $uipw and $fw > $uipw)) ? false : $fw; // Optional: min:$user & max:$uipw
}
else { // Normaler Aufruf
$login = array("/login_sid.lua","/cgi-bin/webcm?getpage=../html/login_sid.xml","/login.lua","/twofactor.lua");
$page = explode('?',$login[1]);
$preg = '/(\w+)<\/SID>/i';
if($sid) { // SID-Session best�tigen lassen
if($rp = request('GET',"$login[0]?sid=$sid") and preg_match($preg,$rp,$var) and $var[1] == $sid) {
if($cfg['fiwa'] == 100)
$cfg['fiwa'] = 530;
}
elseif($rp = request('GET',"$login[1]&sid=$sid") and preg_match($preg,$rp,$var) and $var[1] == $sid) {
if($cfg['fiwa'] == 100)
$cfg['fiwa'] = 474;
}
else
$sid = false; // SID ist ung�ltig
return $sid; // SID zur�ckgeben
}
else
$sid = $rp = $err = false;
call_user_func(__FUNCTION__,false); // Firmware ermitteln
if(isset($cfg['fail']["$cfg[host]:$cfg[port]"]))
return errmsg("8:Host '$cfg[host]:$cfg[port]' antwortet nicht",__FUNCTION__);
foreach(array('user','pass','uipw') as $var) // User & Pass setzen
if(($var != 'uipw' or $cfg['fiwa'] < 500) and !$$var)
$$var = $GLOBALS['cfg'][$var];
if($cfg['fiwa'] < 500 and $uipw) { // Passwordanmeldung mit Fernwartung
$pass = $uipw;
$user = false;
}
if($cfg['fiwa'] > 723 and !$user) { // Anmeldung ab Fritz!OS 7.24+ ohne Benutzernamen
dbug("Suche Benutzernamen");
if($rp = request('GET',$login[0]) and (preg_match_all('!]*>(fritz\d+) !i',$rp,$var) and count($var[1]) == 1
or preg_match_all('!]*>([\w\s,.-]+) !i',$rp,$var) and count($var[1]) == 1)) {
dbug("Nutze: ".$var[1][0]);
$user = $cfg['user'] = $var[1][0];
}
else
return errmsg("12:Keinen Benutzernamen angegeben",__FUNCTION__);
}
$bug = ($user ? " $user@" : " ")."$cfg[host] - Methode";
if(!$sid and ($cfg['fiwa'] == 100 or $cfg['fiwa'] > 529)) { // Login lua ab 05.29 und 7.24
dbug("Login$bug SID.lua (5.30)");
if($rp = request('GET',$login[0].(($cfg['fiwa'] >= 724 and (function_exists('hash_pbkdf2') or cfgdecrypt(0,'hashtool'))
and (function_exists('hash_algos') or cfgdecrypt(0,'mhash') or cfgdecrypt(0,'sha256'))) ? "?version=2" : ""))
and ($auth = call_user_func(__FUNCTION__,array($rp,$pass,$login[0]))) and $rp = request('POST',$login[0],($user ? "$auth&username=$user" : $auth)) and preg_match($preg,$rp,$var)) {
if($auth = ifset($rp,'/(\w+)<\/Name>\s*(\w+)<\/Access>/ia')) {
$cfg['auth'] = array_combine($auth[1],$auth[2]);
dbug("Benutzerrechte: ".implode(", ",$auth[1]),9);
}
if($cfg['fiwa'] == 100)
$cfg['fiwa'] = 530;
if(hexdec($var[1]) != 0)
$sid = $var[1];
else
$err = ", SID.lua ist ung�ltig";
}
elseif(!$rp and !$err)
$err = ", keine Antwort";
}
if(!$sid and ($cfg['fiwa'] == 100 or $cfg['fiwa'] > 473)) { // Login cgi ab 04.74 (Zwischen 4.74 bis 5.29)
dbug("Login$bug SID.xml (4.74)");
if(($rp = request('GET',$login[1]) and $auth = call_user_func(__FUNCTION__,array($rp,$pass,$page[0])) or $rp = request('GET',$login[2]) and $auth = call_user_func(__FUNCTION__,array($rp,$pass,$page[0])))
and $rp = request('POST',$page[0],"$page[1]&login:command/$auth") and preg_match($preg,$rp,$var)) {
if($cfg['fiwa'] == 100)
$cfg['fiwa'] = 474;
if(hexdec($var[1]) != 0)
$sid = $var[1];
elseif(!$err)
$err = ", SID.xml ist ung�ltig";
}
}
if(!$sid and ($cfg['fiwa'] == 100 or $cfg['fiwa'] < 490)) { // Login classic bis 4.89 (z.B. FRITZ!Repeater N/G)
dbug("Login$bug PlainText");
if($var = request('POST',$page[0],"login:command/password=$pass") and !preg_match('/Anmeldung|logincheck\.lua/',$var))
$sid = true;
elseif(!$var and !$err)
$err = ", keine Antwort";
}
elseif($sid and $var = xml2array($rp) and ifset($var['SessionInfo']))
$cfg['sessioninfo'] = $var['SessionInfo'];
if($cfg['fiwa'] > 668 and $sid and $tfa = (($uipw and is_bool($uipw) or !$uipw) and $cfg['totp'] and (is_string($cfg['totp']) or !$cfg['uipw'])) ? $cfg['totp']
: ((($uipw and is_bool($uipw) or is_bool($cfg['totp']) and $cfg['totp']) and $cfg['uipw']) ? $cfg['uipw'] : $uipw)) { // Zwei-Faktor-Authentisierung
$done = $cfg['2fa'] = false; # Besten Dank an Alexander Palm: (https://www.alexander-palm.de/2022/10/29/fritzbox-tools-mein-retter/)
if(is_string($tfa)) {
if(strlen(preg_replace('/\W/','',$tfa)) != 32 and file_exists($tfa)) { // Pr�fen ob Token/Key ein Datei ist
dbug("Lade $tfa nach");
$tfa = file_contents($tfa); // Token/Key von Datei laden
}
if(!ifset($tfa,'/^\d{6}$/')) { // Pr�fen ob es kein Token ist
$tfa = otpauth($tfa); // Token aus Key erstellen
dbug("Generiere 2fa-Token: $tfa");
}
else
dbug("Token: $tfa");
}
dbug("Starte Zwei-Faktor-Authentisierung");
if($rp = request('POST',$login[3],"xhr=1&sid=$sid&tfa_start=&no_sidrenew=") and $m = ifset($rp,'/"state":"([^"]*?\\b(button|googleauth|dtmf;\d+)\\b[^"]*?)"/')) {
$d = 0;
$info = "Bitte an der Fritz!Box in den n�chsten $cfg[tout] Sekunden mit einer Taste best�tigen"
.(($var = ifset($m[1],'/\bdtmf;(\d+)\b/')) ? " oder w�hlen Sie *1$var[1] mit dem Telefon" : "")."!";
if($cfg['fiwa'] > 689 and ifset($m[1],'/\\bgoogleauth\\b/') and ifset($tfa,'/^\d{6}$/')) { // Google Authenticator (Funktioniert ohne https:// erst ab Fritz!OS 7.20)
sleep(1);
request('POST',$login[3],"xhr=1&sid=$sid&tfa_googleauth=$tfa&no_sidrenew=");
$d++;
}
else
out($info);
for($a=$b=0; $a < $cfg['tout']; $a++) { // Warten
if($d and $a == 1) // Fallback, falls der Token vom Google Authenticator falsch ist
out($info);
sleep(1);
if($rp = request('POST',$login[3],"xhr=1&sid=$sid&tfa_active=&no_sidrenew=") and $done = ifset($rp,'/"done":true/')) // Pr�fen ob ok
break;
else { // Warte-Anzeige
$c = $cfg['tout'] ? floor($a / max($a,$cfg['tout']) * max($cfg['wrap']-1,10)) - $b : 1;
out(str_repeat(".",$c),2);
$b += $c;
}
}
if($b) // Warte-Anzeige abschlie�en
out("\n",2);
}
elseif($done = ifset($rp,'/"state":""/'))
dbug("Zwei-Faktor-Authentisierung ist nicht erforderlich!");
else
dbug("Zwei-Faktor-Authentisierung konnte nicht initiiert werden!");
if($done or isset($cfg['opts']['f']) and $cfg['opts']['f']) // 2FA war erfolgreich oder wurde mit -f erzwungen
$cfg['2fa'] = $done;
else { // Fehlschlag
logout($sid);
return errmsg("Zwei-Faktor-Authentisierung fehlgeschlagen",__FUNCTION__);
}
}
return ($cfg['sid'] = $sid) ? $sid : errmsg(($var = ":Anmeldung fehlgeschlagen$err" and !ifset($pass,'/^[ -~]+$/')) ?
"5$var\nHinweis: Das Login-Kennwort enth�lt Sonderzeichen, die bei unterschiedlicher Zeichenkodierung Probleme bereiten k�nnen" : "4$var",__FUNCTION__);
}
}
function logout($sid=0) { // Aus der Fritz!Box ausloggen
if(!$sid)
$sid = $GLOBALS['cfg']['sid'];
dbug("Logout ".$GLOBALS['cfg']['host']);
if(is_string($sid) and $sid) // Ausloggen
request('GET',(($GLOBALS['cfg']['fiwa'] < 529) ? "/cgi-bin/webcm" : "/login_sid.lua"),"security:command/logout=1&logout=1&sid=$sid");
}
function supportcode($str = false) { // Supportcode aufschl�sseln
dbug("Entschl�ssele Supportcode");
return ($str or $str = request('GET','/cgi-bin/system_status')) ? ((preg_match('!
^\s*(?:(?:<[^>]+>\s*)*(?:.*\n)?|System Status[^-]*-*[\s\r\n]*)?
(([^<>]+?)-
([AB]|Kabel|Cable|Ohne)-
([01]\d|2[0-3])([0-2]\d|3[01])(0\d|1[01])-
(\d\d)(\d\d)([0-2]\d|3[01])-
([0-7X]{6})-
([0-7X]{6})-
(1[49]|21|78|8[35])(67|79)(\d\d)
(?:-(\d{2,3})(\d\d)(\d\d)-(\d+))?
(?:-((?=[^-]*[a-z])\w+))?
(?:-([a-z]+))?
|([^<>]+?)\W(\w+)\W(\d\d)(\d\d)(\d\d)\W(\d\d)(\d\d)(\d\d)(?:\W(\d{6})\W(\d{6}))?
(?:\W(\d\d)(\d\d)(\d\d))?
(?:\W(\d{2,3})(\d\d)(\d\d)\W(\d+))?
(?:\W(\w+))?
(?:\W(\w+))?)
!ix',$str,$a))
? dbug($a,4).$a[1].((ifset($a[21]) and array_splice($a,2,19)) ? " (Ung�ltig)".dbug($a,4) : "")."\n\n".textTable("Modell|$a[2]"
.(ifset($a[15]) ? "\nFirmware|$a[15].$a[16].$a[17]\nVersion|$a[18]" : "")
.(ifset($a[20]) ? "\nSprache|$a[20]" : "")
.(ifset($a[19]) ? "\nMarke|$a[19]" : "")
."\nAnnex|$a[3]"
."\n|\nLaufzeit|".preg_replace(array('/\b0*(\d+)(\D+)/','/(\b1\D+?)\D(?=,|$)/','/\b0+\D+/','/^\s+|,\s*$/','/^\s*$/'),array(' $1 $2','$1','','',0),"$a[7]Jahre,$a[6]Monate,$a[5]Tage,$a[4]Stunden,")
."\nNeustarts|".($a[8] * 32 + $a[9])
.(($a[10] and $a[10] != "XXXXXX") ? "\n|\nCRC32 (Bootloader)|".strtoupper(str_pad(dechex((intval($a[10],8) >> 2) ^ 65535).str_pad(substr(dechex(intval($a[11],8) ^ 65535),-4),4,0,STR_PAD_LEFT),8,0,STR_PAD_LEFT))
. " (".str_pad(decbin(intval(substr($a[10],-1).$a[11][0],8) >> 1 & 15),4,0,STR_PAD_LEFT).")" : "")
.($a[12] ? "\n|\ndebug.cfg|".(($a[12] % 64 == 14) ? "Nicht v" : "V")."erf�gbar"
."\nFirmware-Attribut|".(($a[12] < 64) ? "Ge�ndert" : "Unver�ndert")
."\n|\nOEM|".(($a[13] == 67) ? "Custom" : "Original")
."\nRunClock|$a[14]" : "")."\n")
: errmsg(($var = ifset($str,'/(.*?)<\/title>/i')) ? "16:Fehler: $var[1]" : "16:Unbekannt: $str",__FUNCTION__)) : errmsg('request',__FUNCTION__);
}
function boxinfo($data=false,$mode=false) { // jason_boxinfo.xml / juis_boxinfo.xml auslesen und auswerten
global $cfg;
if(!$data and login(false) and ifset($cfg['http'])) { // Boxinfo aus der Fritz!Box auslesen
$body = array('jason_boxinfo.xml' => $cfg['http'] + array(1 => $cfg['body']));
$data = $cfg['body'];
$date = isset($cfg['http']['Date']) ? $cfg['http']['Date'] : 0;
if($var = request('GET','/juis_boxinfo.xml')) {
$body['juis_boxinfo.xml'] = $cfg['http'] + array(1 => $var);
$data .= $var;
}
}
dbug($cfg['http'],6);
dbug($data,6);
if(preg_match_all('/<([ejqs]:(\w+))>([^<>]+)<\/\1>/m',$data,$array)) {
dbug($array,4);
$jason = array(
'Name' => 'Modell',
'HW' => 'Hardware-Version',
'Version' => 'Firmware-Version',
'Revision' => 'Firmware-Revision',
'OEM' => 'Marke',
'Annex' => 'Annex (Festnetz)',
'Lab' => 'Labor',
'Country' => 'Land-Vorwahl',
'Major' => 'Hauptversion',
'Minor' => 'Nebenversion',
'Patch' => 'Unterversion',
'Buildnumber' => 'Firmware-Revision',
'Firmware_attrib' => 'Firmware-Attribut',
'Serial' => array('MAC-Adresse (LAN)',array('/\w\w(?!$)/','$0:')),
'Buildtype' => array('Firmware-Typ',array(
array(1007 => "PLUS Beta", 1006 => "TEST Beta", 1004 => "Phone", 1001 => 'Frisch aus der Entwicklung', 1000 => 'Inhouse', 1 => 'Normal'))),
'UpdateConfig' => array('Aktualisierung',array(
array("-/-","Benachrichtigen","Benachrichtigen & Sicherheitsaktualisierungen","Automatische Aktualisierungen"))),
'Lang' => array('Sprache',array(
array('de' => "Deutsch", 'en' => "English", 'es' => "Espa�ol", 'fr' => "Fran�ais", 'it' => "Italiano", 'pl' => "Polski"))),
'Flag' => array('Flags',array(
array( 'crashreport' => "Absturzbericht",
'avm_acs' => "TR-069 (AVM)",
'prov_acs' => "TR-069 (Provider)",
'myfritz_letsencrypt' => "HTTPS mit LetsEncrypt",
'botnet_detection' => "Viren Erkennung",
'mesh_master_no_trusted' => "Einsame Mesh-Zentrale",
'mesh_repeater_no_trusted' => "Einsamer Mesh-Teilnehmer",
'mesh_master' => "Mesh mit Teilnehmern",
'mesh_repeater' => "Mesh-Teilnehmer",
'nomini' => "Kein FRITZ!Mini",
'2nd_factor_disabled' => 'Kein zweiter Faktor',
'remote_login_service' => 'Fernwartung',
'medium_dsl' => 'DSL-Internet',
'medium_lan' => 'LAN-Internet'))),
);
$boxinfo = array();
foreach($array[2] as $key => $var)
$boxinfo[$var][] = html_entity_decode($array[3][$key]);
$array = array();
foreach($boxinfo as $key => $var) {
$var = array_unique($var);
if(isset($jason[$key]))
if(is_array($jason[$key])) {
if(ifset($jason[$key][1]))
$var = (count($jason[$key][1]) == 2) ? preg_replace($jason[$key][1][0],$jason[$key][1][1],$var)
: str_replace(array_keys($jason[$key][1][0]),array_values($jason[$key][1][0]),$var);
$title = $jason[$key][0];
}
else
$title = $jason[$key];
else
$title = $key;
$array[$title] = "$title|".implode(", ",$var);
}
if($cfg['fiwa'] > 723) { // Erweitere Daten aus login_sid.lua auslesen
if($rp = request('GET','/login_sid.lua') and preg_match_all('!<(User)([^>]*)>([ \w,.-]+)\1>!i',$rp,$user)) { // XML-Login
$body['login_sid.xml'] = $cfg['http'] + array(1 => $rp);
if($var = ifset($rp,'/<(BlockTime)>(\d+)<\/\1>/i') and $var[2])// Ist immer 0?
$array['blocktime'] = "Sperrzeit|$var[2] Sekunden";
if(count($user[3]) > 1 and ($last = preg_array('/./',$user[2],4)) !== false)
$array['lastuser'] = "Letzter Benutzer|".$user[3][$last];
$array['admin'] = "Benutzer (Admin)|".implode(", ",$user[3]);
}
else
$user = false;
if($rp = request('GET','/nas/api/login.lua') and $js = json2array($rp) and $flag = ifset($js['session'],true)) { // NAS-Login
$body['login_nas.json'] = $cfg['http'] + array(1 => $rp);
$flag = $js['session'];
if($a = ifset($js['session']['activeUsers'],true) and (!$user or array_diff($user[3],$a) or array_diff($a,$user[3])))// NAS-User
$array['nas'] = "Benutzer (NAS)|".implode(", ",$a);
}
if($rp = request('GET','/myfritz/api/login.lua') and $js = json2array($rp) and $b = ifset($js['session'],true)) { // MyFritz-Login
$body['login_myfritz.json'] = $cfg['http'] + array(1 => $rp);
$flag += $b;
if($b = ifset($js['session']['activeUsers'],true) and (!ifset($user) or array_diff($user[3],$b) or array_diff($b,$user[3]))
and (!ifset($a) or array_diff($a,$b) or array_diff($b,$a))) // MyFritz-User
$array['myfritz'] = "Benutzer (MyFritz)|".implode(", ",$b);
}
if(isset($array['admin']) and !isset($array['myfritz']) and !isset($array['nas']))
$array['admin'] = preg_replace('/^(\w+)[^|]*/','$1',$array['admin']);
$flags = "";
if(ifset($flag['fromInternet']))
$flags .= ", Internet-Zugang";
if(ifset($flag['noUserList']))
$flags .= ", Keine Benutzerliste";
if(isset($flag['firstStartWizardDone']) and !$flag['firstStartWizardDone'])
$flags .= ", Assistent beim Start";
if(isset($flag['nasActive']))
$flags .= ", NAS ist a".($flag['nasActive'] ? "n" : "us");
if($key = ifset($flag['viewMode'],""))
$flags .= ", ".(($key == "loginOnlyWithPwd") ? "Login nur mit Kennwort" : "Benutzer-Login" );
if($key = ifset($flag['migratedUser'],""))
$array['migrated'] = "Migrierter Benutzer|$key";
if($flags)
$array['Flags'] = ifset($array['Flags']) ? $array['Flags'].$flags : substr($flags,2);
}
if($date)
$array['Boxtime'] = 'Aktuelle Uhrzeit|'.date('d.m.Y H:i:s',strtotime($date));
$data = textTable(implode("\n",$array));
dbug($body,6);
if($mode) { // RAW-Daten mit zur�ckgeben
array_unshift($body,$data);
$data = $body;
}
return $data;
}
else
return '';
}
function upnprequest($page,$ns,$rq,$exp=false) { // UPnP Request durchf�hren
global $cfg;
dbug("Setzte UPnP request ab: $page - $rq",9);
if($rp = request(array(
'method' => 'POST-array',
'page' => $page,
'body' => utf8("\n"
."\n"
." \n ",1),
'head' => array_merge($GLOBALS['cfg']['head'],array('content-type' => 'text/xml; charset="utf-8"', 'soapaction' => "\"$ns#$rq\"")),
'port' => $GLOBALS['cfg']['upnp']))) {
if($cfg['fiwa'] != 100 and $var = ifset($rp['SERVER'],'/0*([1-9])\.(\d{2})\s*$/')) // Firmware-Version auslesen
$cfg['fiwa'] = intval($var[1].$var[2]);
if($exp and is_string($exp)) // Nur einen Wert extrahieren
return (preg_match("!<$exp>(.*?)$exp>!",$rp[1],$var)) ? $var[1] : errmsg('16:Kein Erwartetes Ergebnis erhalten',__FUNCTION__);
elseif(is_array($exp) and preg_match_all('!<(\w+)>(.+?)\1>!',$rp[1],$array)) { // Alle Werte in ein Array packen
dbug($array,4,__FUNCTION__);
foreach($array[1] as $key => $var) // Ergebnisse zusammenstellen
$exp[$var] = $array[2][$key];
return $exp;
}
else // Response RAW zur�ckgeben
return $rp;
}
else // Fehler aufgetreten
return errmsg('request',__FUNCTION__);
}
function getupnppath($urn) { // Helper f�r UPnP-Requests
dbug("Ermittle UPnP Pfad: $urn",9);
if($rp = request(array('method' => 'GET', 'page' => '/igddesc.xml', 'port' => $GLOBALS['cfg']['upnp']))
and preg_match("!<(service)>.*?<(serviceType)>(urn:[^<>]*".$urn."[^<>]*)\\2>.*?<(controlURL)>(/[^<>]+)\\4>.*?\\1>!s",$rp,$var)) {
dbug($var,4);
$rp = array($var[3],$var[5]);
}
else
$rp = errmsg('request',__FUNCTION__);
return $rp;
}
function getexternalip() { // Externe IPv4-Adresse �ber UPnP ermitteln
global $cfg;
dbug("Ermittle IP-Adresse �ber UPnP f�r $cfg[fiwa]");
$ip = array();
if($val = getupnppath('WANIPConnection')) {
if($var = upnprequest($val[1],$val[0],'GetExternalIPAddress','NewExternalIPAddress'))
$ip['IPv4'] = $var;
if($cfg['http']['HTTP_Code'] == 200 and ($cfg['fiwa'] >= 550 or $cfg['fiwa'] == 100)) { // IPv6 und DNS bei neueren Boxen
$k = "X_AVM_DE_Get";
if($var = upnprequest($val[1],$val[0],$k.'ExternalIPv6Address','NewExternalIPv6Address'))
$ip['IPv6'] = $var;
if($var = upnprequest($val[1],$val[0],$k.'IPv6Prefix',array()) and ifset($var['NewIPv6Prefix']))
$ip['IPv6-Prefix'] = "$var[NewIPv6Prefix]/$var[NewPrefixLength]";
if($var = upnprequest($val[1],$val[0],$k.'DNSServer',array()) and $var = preg_array('/New(IPv4)?DNSServer/',$var,3))
$ip['DNSv4'] = implode(", ",$var);
if($var = upnprequest($val[1],$val[0],$k.'IPv6DNSServer',array()) and $var = preg_array('/NewIPv6DNSServer/',$var,3))
$ip['DNSv6'] = implode(", ",$var);
}
if($ip)
return $ip;
}
return errmsg('request',__FUNCTION__);
}
function forcetermination() { // Internetverbindungen �ber UPnP neu aufbauen
dbug("WAN Neueinwahl �ber UPnP");
return ($val = getupnppath('WANIPConnection') and $var = upnprequest($val[1],$val[0],'ForceTermination'))
? $var : errmsg('request',__FUNCTION__);
}
function saverpdata($file,$data,$name) { // HTTP-Downloads in Datei speichern
global $cfg;
if(!$file or is_bool($file)) { // File ist leer
$dir = "./";
$file = "";
}
elseif($file == ':') // Es soll nichts geschrieben werden
return true;
elseif(file_exists($file) and is_dir($file)) { // file ist ein Verzechnis
$dir = str_replace('\\','/',realpath($file))."/";
$file = false;
}
elseif($dir = dirname($file)."/" and file_exists($dir) and is_dir($dir))// file enth�lt ein Verzeichnis
$file = basename($file);
else { // file ist nur eine Datei...
$dir = "./";
if(!file_exists($file)) // ...dass nicht existiert
$file = basename($file);
}
if(!is_array($data))
$data = $cfg['http'] + array(1 => $data);
$cfg['file'] = $file = preg_replace($cfg['fesc'],$cfg['frep'],(!$file and isset($data['Content-Disposition']) and preg_match('/filename="(.*)"/',$data['Content-Disposition'],$var)) ? $var[1] : ($file ? $file : $name));
dbug("Speichere Daten in $dir$file",9);
return file_contents($dir.$file,$data[1]);
}
function supportdata($file=false,$tm=false,$sid=0) { // Supportdaten anfordern
dbug("Hole Supportdaten");
if(!$sid)
$sid = $GLOBALS['cfg']['sid'];
$array = array();
if(!is_bool($sid))
$array['sid'] = $sid;
$mode = 'SupportData';
if($tm !== false) {
if($GLOBALS['cfg']['fiwa'] < 680 and $GLOBALS['cfg']['fiwa'] >= 650) { // Telemetrie ab OS6.5 aktivieren
dbug("Telemetrie wird ".($tm ? '' : 'de') ."aktiviert");
request('POST','/data.lua',"xhr=1&sid=$sid&lang=de&no_sidrenew=".($tm ? '&supportdata_enhanced=on' : '')."&support_plus=&oldpage=/support.lua");
}
elseif($GLOBALS['cfg']['fiwa'] >= 680 and !$tm) {
dbug("Aktiviere Telemetrie");
$mode .= 'Enhanced';
}
}
$array[$mode] = '';
$data = $file ? (bool)request("POST-save:$file",'/cgi-bin/firmwarecfg',$array) : request("POST-array",'/cgi-bin/firmwarecfg',$array);
return $data ? $data : errmsg('request',__FUNCTION__);
}
function supportdataextrakt($data,$mode=0,$file='') { // Supportdaten extrahieren
global $cfg;
$info = array();
if(is_array($mode) and $mode[0] == 'sec') {
$preg = '/^#{5} +BEGIN +SECTION +(\S+) *([^\r\n]+\s*)?(.*?)^#{5} +END +SECTION +\1\s+/sim';
if(preg_match_all($preg,$data,$array)) {
dbug($array,4,'SupportDataExtrakt-#');
foreach($array[1] as $key => $var)
if(trim($array[3][$key]))
$info = array_merge($info,(($val = trim(preg_replace($preg,'',$array[3][$key]))) ? array($var => $array[2][$key].$val) : array()),call_user_func(__FUNCTION__,$array[3][$key],array('sec')));
}
}
else {
dbug("Zerlege Supportdaten");
$mstr = $mlen = array(0,0);
$val = $list = array();
if(substr($data,0,5) == '#####')
$array = call_user_func(__FUNCTION__,$data,array('sec'));
elseif(preg_match('/^Support Data\n-+\n/',$data)
and preg_match_all('/([()\/\w@:. -]+)\n-+\n([\s\S]+?)(?=End Of Support Data\s*$|\n\n[()\/\w@:. -]+\n-+\n|$)/i',$data,$array))
$array = array_combine($array[1],$array[2]);
if($array) {
if(ifset($file,'/\.zip$/i')) {
if($zip = data2zip($array))
file_contents($file,$zip);
}
else { // Tar-Archiv
if($mode and $file) // Tar-Archiv Initialisieren
$fp = ($mode == 2) ? $cfg['zlib']['open']($file,'w'.$cfg['zlib']['mode']) : call_user_func(($cfg['bzip'] and $mode == 3) ? 'bzopen' : 'fopen',$file,'w');
foreach($array as $key => $var) { // Maximale L�ngen ermitteln
$key = preg_replace($cfg['fesc'],$cfg['frep'],$key);
$list[] = array($key,number_format(strlen($var),0,",","."));
if($mode == 3 and $fp)
bzwrite($fp,data2tar("$key.txt",$var,$date));
elseif($mode == 2 and $fp)
$cfg['zlib']['write']($fp,data2tar("$key.txt",$var,$date));
elseif($mode == 1 and $fp)
fwrite($fp,data2tar("$key.txt",$var,$date));
elseif($file)
file_contents("$key.txt",$var);
}
if($mode and $fp) { // Tar-Archiv abschlie�en
$data = str_repeat("\0",512);
if($mode == 3) {
bzwrite($fp,$data);
bzclose($fp);
}
elseif($mode == 2) {
$cfg['zlib']['write']($fp,$data);
$cfg['zlib']['close']($fp);
}
else {
fwrite($fp,$data);
fclose($fp);
}
}
}
for($a=0; $a < ceil(count($list)/2); $a++)
foreach(array($a,$a+ceil(count($list)/2)) as $b)
if(isset($list[$b]))
$val[$a] = ((isset($val[$a])) ? $val[$a]."||" : "").$list[$b][0]."| ".$list[$b][1]." Bytes";
$info = textTable(implode("\n",$val));
}
else
dbug("Das zerlegen der Supportdaten ist fehlgeschlagen");
}
return $info;
}
function dial($dial,$fon=false,$sid=0) { // Wahlhilfe
global $cfg;
if(!$sid)
$sid = $cfg['sid'];
$sid = (!is_bool($sid)) ? "&sid=$sid" : '';
$dial = preg_replace('/[^\d*#]+/','',$dial);
$rdial = urlencode($dial);
$fon = ($var = ifset($fon,'/^((?P[1-4]|5[0-8]|6[0-5])|(?Pfon[1-4]?|isdn[0-8]?|dect[0-6]?))($)/i'))
? (($var['i']) ? intval($var['i']) : (($var = ifset($var['s'],'/(\D+)(\d?)/')) ? ((ifset($var[1],'/fon/i')) ? (($var[2]) ? intval($var[2]) : 1)
: ((ifset($var[0],'/isdn|dect0?$/i')) ? 50 : 59) + intval($var[2])) : 0)) : false;
if($cfg['fiwa'] >= 530) {
if($fon) {
dbug("Dial: �ndere Anruf-Telefon auf $fon");
request('POST',"/fon_num/dial_fonbook.lua","clicktodial=on&port=$fon&btn_apply=$sid");
}
dbug("Dial: ".($dial ? "W�hle $dial" : "Auflegen"));
request((($cfg['fiwa'] >= 708) ? 'POST' : 'GET'),"/fon_num/fonbook_list.lua",($dial ? "dial=$rdial" : "hangup=&orig_port=$fon").$sid);
}
else { // Classic
request('POST',"/cgi-bin/webcm","telcfg:settings/UseClickToDial=1"
.($dial ? "&telcfg:command/Dial=$rdial" : "&telcfg:command/Hangup=")
.($fon ? "&telcfg:settings/DialPort=$fon" : "").$sid);
dbug("Dial: ".($dial ? "W�hle $dial".($fon ? " f�r Telefon $fon" : "") : "Auflegen"));
}
return $dial ? $dial : "-";
}
function cfgexport($mode,$pass=false,$sid=0) { // Konfiguration Exportieren (NUR Exportieren)
dbug("Exportiere Konfig");
$body = array('ImportExportPassword' => $pass, 'ConfigExport' => false);
$path = '/cgi-bin/firmwarecfg';
if(!$sid) {
$sid = $GLOBALS['cfg']['sid'];
if(!is_bool($sid))
$body = array_merge(array('sid' => $sid),$body);
}
return $mode ? (($mode === 'array') ? request('POST-array',$path,$body)
: request('POST-save:'.(($mode === true) ? './' : $mode),$path,$body))
: request('POST',$path,$body);
}
function cfgcalcsum($data) { // Checksumme f�r die Konfiguration berechnen
if(preg_match_all('/^(\w+)=(\S+)\s*$|^(\*{4}) (?:CRYPTED)?(CFG|BIN|B64)FILE:(\S+)\s*(.*?)\3 END OF FILE \3\s*$/sm',$data,$array)) {
dbug("Berechne Konfig-Checksumme",9);
dbug($array,4,'CfgCalcSum-#');
foreach($array[4] as $key => $var)
$array[0][$key] = ($array[1][$key]) ? $array[1][$key].$array[2][$key]."\0" : $array[5][$key]."\0".(($var == 'BIN')
? pack('H*',preg_replace('/[^\da-f]+/i','',$array[6][$key])) : (($var == 'B64') ? base64_decode($array[6][$key])
: preg_replace('/\r|\\\\(?=\\\\)/','',substr($array[6][$key],0,-1))));
dbug($array[0],4,'8,CfgCalcSumArray-#');
dbug(join('',$array[0]),4,'8,CfgCalcSumData');
}
return ($array and preg_match('/(?<=^\*{4} END OF EXPORT )[A-Z\d]{8}(?= \*{4}\s*$)/m',$data,$key,PREG_OFFSET_CAPTURE))
? array($key[0][0],$var = strtoupper(hash('crc32b',join('',$array[0]))),substr_replace($data,$var,$key[0][1],8)) : errmsg('16:Keine Konfig-Datei',__FUNCTION__);
}
function cfgimport($file,$pass='',$mode=false,$sid=0) { // Konfiguration importieren (Wird vermutlich bald �berarbeitet)
global $cfg;
if($file and ( is_file($file) and preg_match($cfg['ptar'],$file,$var) and ($data = cfgmake($var[4] ? zip2array(file_contents($file)) : tar2array($file)))
or is_file($file) and ($data = file_contents($file))
or is_dir($file) and ($data = cfgmake($file))
) or !$file and $data = $mode and substr($mode,0,4) == '****') {
if($mode and $var = cfgcalcsum($data))
$data = $var[2];
dbug("Upload Konfig-File an ".$cfg['host']);
$body = array('ImportExportPassword' => $pass,
'ConfigImportFile' => array('filename' => $file, 'Content-Type' => 'application/octet-stream', '' => $data),
'apply' => false);
if(!$sid) {
$sid = $cfg['sid'];
if(!is_bool($sid))
$body = array_merge(array('sid' => $sid),$body);
}
if($cfg['fiwa'] >= 724)
$res = request('POST','/data.lua',"xhr=1&recovery&$sid=$sid&ImportExportPassword=".urlencode($pass)."&uiPass=".urlencode($pass)
."&cfgtakeover=all&restore=&lang=de&page=sysImp");
return request('POST','/cgi-bin/firmwarecfg',$body);
}
else
return errmsg('8:Import-Datei/Ordner nicht gefunden',__FUNCTION__);
}
function cfginfo($data,$mode=0,$file='',$text=false) { // Konfiguration in Einzeldateien sichern (mode: 0->show, 1->Dir, 2->Tar, 3->tgz, 4->tbz)
global $cfg;
if(preg_match_all('/^(?:
\*{4}\s(.*?)\sCONFIGURATION\sEXPORT|(\w+=\S+))\s*$ # 1 Fritzbox-Modell, 2 Variablen
|^\*{4}\s(?:CRYPTED)?(CFG|BIN|B64)FILE:(\S+)\s*?\r?\n(.*?)\r?\n # 3 Typ, 4 File, 5 Data
^\*{4}\sEND\sOF\sFILE\s\*{4}\s*?$/msx',$data,$array) and $array[1][0] and $crc = cfgcalcsum($data)) {
$list = $val = $vars = array();
$mstr = $mlen = array(0,0);
dbug($array,4,'CfgInfo-#');
if($mode == 4 and !$cfg['bzip']) {
$mode -= 2;
$file = preg_replace('/(\.tar)?\.t?bz(ip)?2?|/i','.tar',$file);
}
elseif($mode == 5)
$zip = array();
$fp = ($mode < 5 and $mode >= 2 and $file) ? (($mode == 3) ? $cfg['zlib']['open']($file,'w'.$cfg['zlib']['mode']) : call_user_func(($mode == 4) ? 'bzopen' : 'fopen',$file,'w')) : false; // tar/tgz initialisieren
foreach($array[3] as $key => $var) // Config-Dateien aufteilen
if($var) {
if($array[3][$key] == 'CFG') {
$bin = preg_replace('/\r|\\\\(?=\\\\)/','',$array[5][$key]);
if(!isset($vars['Date']) and preg_match('/^\s\*\s([\s:\w]+)$/m',$bin,$var))
$vars['Date'] = strtotime($var[1]);
}
else
$bin = ($array[3][$key] == 'B64') ? base64_decode($array[5][$key]) : pack('H*',preg_replace('/[^\da-f]+/i',"",$array[5][$key]));
$list[] = array($array[3][$key],$array[4][$key],number_format(strlen($bin),0,",","."));
if($mode == 5)
$zip[$array[4][$key]] = array('data' => $bin, 'date' => $vars['Date']);
elseif($fp and $mode == 4)
bzwrite($fp,data2tar($array[4][$key],$bin,$vars['Date']));
elseif($fp and $mode == 3)
$cfg['zlib']['write']($fp,data2tar($array[4][$key],$bin,$vars['Date']));
elseif($fp and $mode >= 2)
fwrite($fp,data2tar($array[4][$key],$bin,$vars['Date']));
elseif($mode >= 1)
file_contents($array[4][$key],$bin);
unset($array[2][$key]);
}
elseif($var = ifset($array[2][$key],'/^(\w+)=(.*)$/'))
$vars[$var[1]] = $var[2];
else
unset($array[2][$key]);
$name = "index.txt"; // Konfig-Schablone sichern
$data = preg_replace('/^(\*{4}\s(?:CRYPTED)?(?:CFG|BIN|B64)FILE:\S+\s*?\r?\n).*?\r?\n(^\*{4}\sEND\sOF\sFILE\s\*{4}\s*?)$/msx','$1$2',$data);
$list[] = array("TXT",$name,number_format(strlen($data),0,",","."));
if($mode == 5)
$zip[$name] = array('data' => $data, 'date' => $vars['Date']);
elseif($fp and $mode == 4)
bzwrite($fp,data2tar($name,$data,$vars['Date']));
elseif($fp and $mode == 3)
$cfg['zlib']['write']($fp,data2tar($name,$data,$vars['Date']));
elseif($fp and $mode >= 2)
fwrite($fp,data2tar($name,$data,$vars['Date']));
elseif($mode >= 1)
file_contents($name,$data);
if($text) { // Zugangsdaten sichern
$name = "zugangsdaten.txt";
$list[] = array("TXT",$name,number_format(strlen($text),0,",","."));
if($mode == 5)
$zip[$name] = array('data' => $text, 'date' => $vars['Date']);
if($fp and $mode == 4)
bzwrite($fp,data2tar($name,$text,$vars['Date']));
elseif($fp and $mode == 3)
$cfg['zlib']['write']($fp,data2tar($name,$text,$vars['Date']));
elseif($fp and $mode >= 2)
fwrite($fp,data2tar($name,$text,$vars['Date']));
elseif($mode >= 1)
file_contents($name,$text);
}
if($mode == 5 and $zip = data2zip($zip))
file_contents($file,$zip);
elseif($fp) { // tar/tgz finalisieren
$data = str_repeat("\0",512);
if($mode == 4) {
bzwrite($fp,$data);
bzclose($fp);
}
elseif($mode == 3) {
$cfg['zlib']['write']($fp,$data);
$cfg['zlib']['close']($fp);
}
elseif($mode == 2) {
fwrite($fp,$data);
fclose($fp);
}
}
for($a=0; $a < ceil(count($list)/2); $a++)
foreach(array($a,$a+ceil(count($list)/2)) as $b)
if(isset($list[$b]))
$val[$a] = ((isset($val[$a])) ? $val[$a]."||" : "").$list[$b][0].":|".$list[$b][1]."| ".$list[$b][2]." Bytes";
$list = "\nModell: {$array[1][0]}\n";
if(ifset($vars['Date']))
$list .= "Datum: ".date('d.m.Y H:i:s',$vars['Date'])."\n";
if(ifset($vars['FirmwareVersion']))
$list .= "Firmware: $vars[FirmwareVersion]\n";
return $list."Checksum: $crc[0]".((!$mode and $text) ? "" : " (".(($crc[0] == $crc[1]) ? "OK" : "Inkorrekt! - Korrekt: $crc[1]").")")."\n\n"
.textTable(implode("\n",$val))."\n".((!$mode and $text) ? $text : '');
}
else
return errmsg('16:Keine Konfig-Datei',__FUNCTION__);
}
function cfgmake($dir,$mode='',$file=false) { // Konfiguration wieder zusammensetzen
if(is_array($dir) and isset($dir[0]) and !$mode and !$file) { // Helper f�r Preg_Replace CfgMake
if(is_array($GLOBALS['val']) and isset($GLOBALS['val'][$dir[3]]))
$mode = $GLOBALS['val'][$dir[3]];
elseif(file_exists("$GLOBALS[val]/$dir[3]"))
$mode = file_contents("$GLOBALS[val]/$dir[3]");
return $dir[1].(($dir[2] == 'CFG') ? str_replace("\\","\\\\",$mode)
: wordwrap(($dir[2] == 'BIN') ? strtoupper(implode('',unpack('H*',$mode))) : base64_encode($mode),80,$dir[4],1)).$dir[4].$dir[5];
}
elseif($dir and (is_array($dir) and $data = preg_array('/^(index|pattern)\.txt$/',$dir,1) or ($var = glob("$dir/{index,pattern}.txt",GLOB_BRACE))
and ($data = file_contents($var[0]))) and preg_match('/^\*{4}\s+\w+.*CONFIGURATION EXPORT/',$data,$array)) {
dbug("Setze Konfig-Daten zusammen");
$GLOBALS['val'] = $dir;
$data = preg_replace_callback('/(^\*{4}\s(?:CRYPTED)?(CFG|BIN|B64)FILE:(\S+)\s*?(\r?\n))(^\*{4}\sEND\sOF\sFILE\s\*{4}\s*?$)/m',__FUNCTION__,$data);
if(preg_match('/^\*{4}\s(.*?)\sCONFIGURATION\sEXPORT.*?FirmwareVersion=(\S+)/s',$data,$array) and $crc = cfgcalcsum($data)) {
$val = "Modell: $array[1]\nFirmware: $array[2]\nChecksum: $crc[0] ";
$val .= (($crc[0] == $crc[1]) ? "(OK)" : "Inkorrekt! - Korrekt: $crc[1]")."\n";
$data = $mode ? $crc[2] : $data;
if($file)
file_contents($file,$data);
return $file ? $val : $data;
}
}
return errmsg("8:Keine Konfig-Daten - Konfig-Schablone nicht gefunden",__FUNCTION__);
}
function cfgdecrypt($data=false,$pass=false) { // Konfig-Datei entschl�sseln
global $cfg;
if(is_array($pass) and substr($copy = $data,0,4) == '$$$$') { // Fritz Decrypt
$a = substr($d = unBase($data),0,16); // AES iv
$b = substr($d,16).str_pad("\0",16 - strlen($d) % 16); // AES data.pad
foreach($cfg['aes'] as $aes => $var) { // Alle AES-Bibliotheken durchprobieren
for($c=count($pass)-1; $c >= 0; $c--) { // Alle Kennw�rter durchprobieren
if($pass[$c] == 1) // Letzter Schl�ssel im Bund
$data = false;
elseif($aes == 'openssl') // Extension: OpenSSL
$data = openssl_decrypt($b, "AES-256-CBC", $pass[$c], OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $a);
elseif($aes == 'mcrypt') // Extension: MCrypt
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pass[$c], $b, MCRYPT_MODE_CBC, $a);
elseif($aes == 'aes5') // Script: Aes.php
$data = eval('$d = new PhpAes\Aes($pass[$c], "CBC", $a); return $d->decrypt($b);');
elseif($aes == 'aes4') { // Script: AES_4.class.php
$d = new Aes($pass[$c], "CBC", $a);
$data = $d->decrypt($b);
}
if(substr(hash('md5',substr($data,4,strlen($data) - 20),true),0,4) == substr($data,0,4)) { // Checksum
$data = substr($data,8,hexdec(bin2hex(substr($data,4,4)))); // Extract
return (end($pass) == 1) ? preg_replace(array('/\0?$/','/[\\"]/'),array('','\\\\$0'),$data) : $data;
}
}
}
dbug("Fail: $copy",4);
return false;
}
elseif(preg_match('/^\*{4} .*? CONFIGURATION EXPORT$/mi',$data) and $pass) { // Konfig einlesen und zur entschl�sselung vorbereiten
dbug($data,4,'12,CfgDeCrypt-Crypted');
if(preg_match('/^\s*(?:([A-Z](?:0[1-9]|[1-4]\d|5[0-3])[1-7]\.?\d{3}\.?\d{2}(?:\.?\d{3}){2})\W)?((?:[\dA-F]{2}([:-]|(?=\s*$))){6})\s*$/i',$pass,$var)) // Alternative zur Konfiguationen ohne Kennwort
$pass = ((ifset($var[1])) ? str_replace('.','',$var[1]) : str_repeat('0',16))."\n".strtoupper(str_replace('-',':',$var[2]))."\n"; // Seriennummer und MacA-Adresse als Kennwort
$pass = array(str_pad(hash('md5',$pass,true),32,"\0"));
if(preg_match_all('/(Password\d*=)(\${4}\w+)/i',$data,$match,PREG_OFFSET_CAPTURE))
for($a=count($match[0])-1; $a >= 0; $a--)
if($key = call_user_func(__FUNCTION__,$match[2][$a][0],$pass) and strlen($key) == 32 and substr($key,0,16) == substr($key,16)) { // Schl�ssel extraieren
$pass[] = str_pad(substr($key,16),32,"\0"); // Schl�ssel merken
$data = substr_replace($data,strtoupper(bin2hex(substr($key,16))),$match[2][$a][1],strlen($match[2][$a][0])); // Schl�ssel in Plaintext
}
if(count($pass) > 1 and preg_match_all('/(\${4}\w+)(?="|$)|^(\*{4}\sB(64|IN)FILE:.*\s*)([\dA-F\s]*?(?:24\s*){4}(?:[46][1-9A-F]|[57][0-9A]|3\d|\s*)+[\dA-F\s]*|[\w+\/\s]*?(?:JCQkJ|QkJC|kJCQk)[\w+\/\s=]+)(?=\s+\*{4})|^(\*{4}\sCRYPTEDB(64|IN)FILE:.*\s*)([\dA-F\s]+)(?=\s+\*{4})/im',$data,$match,PREG_OFFSET_CAPTURE)) {
$pass[] = 1; // Schl�sselring anschlie�en
for($a=count($match[0])-1; $a >= 0; $a--) {
if($match[1][$a][0])
$data = substr_replace($data,call_user_func(__FUNCTION__,$match[1][$a][0],$pass),$match[1][$a][1],strlen($match[1][$a][0]));
else {
if($match[5][$a]) {
$match[2][$a] = $match[5][$a];
$match[3][$a] = $match[6][$a];
$match[4][$a] = $match[7][$a];
}
$b = $match[2][$a][0];
$c = ($match[3][$a][0] == 64) ? base64_decode($match[4][$a][0]) : pack("H*", preg_replace('/\W+/','',$match[4][$a][0]));
if(isset($match[5][$a][0]) and $match[5][$a][0] == $b) { // CryptedBin
foreach($cfg['aes'] as $aes => $var) {
$d = $c.str_repeat("\0",16 - strlen($c) % 16);
if($aes == 'openssl')
$d = openssl_decrypt($d, "AES-256-ECB", $pass[0], OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
elseif($aes == 'mycrypt')
$d = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pass[0], $d, MCRYPT_MODE_ECB, substr($d,0,16));
elseif($aes == 'aes5')
$d = eval('$d = new PhpAes\Aes($pass[0], "ECB"); return $d->decrypt($d);');
elseif($aes == 'aes4') {
$f = new Aes($pass[0], "ECB");
$d = $f->decrypt($d);
}
$f = -1; // Workaround f�r strrpos
while($e = strpos($d,"AVM\0",$f + 1))
$f = $e;
if($aes and $f > 0) { // $f = strrpos($d,"AVM\0")
$c = substr($d,4,hexdec(bin2hex(substr($d,$f + 12,4))));
$b = str_replace('CRYPTED','',$b);
break;
}
}
}
elseif(preg_match_all('/\${4}\w+(?="|$)/',$c,$var,PREG_OFFSET_CAPTURE))
for($d=count($var[0])-1; $d >= 0; $d--)
$c = substr_replace($c,call_user_func(__FUNCTION__,$var[0][$d][0],$pass),$var[0][$d][1],strlen($var[0][$d][0]));
$data = substr_replace($data,$b.preg_replace('/.{80}/',"\$0\n",($match[3][$a][0] == 64) ? base64_encode($c) : strtoupper(bin2hex($c))),$match[0][$a][1],strlen($match[0][$a][0]));
}
}
return $data;
}
else
return errmsg('4:Falsches Konfig-Kennwort',__FUNCTION__);
}
elseif(!$data) { // AES init
if(!ifset($cfg['php'][5])) {
ob_start();
phpinfo();
if(preg_match('/^Configuration File.*?=>\s*(.*)$/m',ob_get_contents(),$array))
$cfg['php'][5] = $array[1];
ob_end_clean();
}
$ext = array();
foreach(array(
'openssl' => array('ext' => 1, 'min' => 5.4, 'func' => 'openssl_decrypt', 'preg' => '/\b(php_)?openssl\.(so|dll)/i'),
'mcrypt' => array('ext' => 1, 'func' => 'mcrypt_decrypt', 'preg' => '/\b(php_)?mcrypt\.(so|dll)/i'),
'mhash' => array('ext' => 1, 'max' => 5.1, 'func' => 'mhash', 'preg' => '/\b(php_)?mhash\.(so|dll)/i'),
'zlib' => array('ext' => 1, 'func' => 'gzread', 'preg' => '/\b(php_)?zlib\.(so|dll)/i'),
'bzip2' => array('ext' => 1, 'func' => 'bzread', 'preg' => '/\b(php_)?bz2\.(so|dll)/i'),
'mysqli' => array('ext' => 1, 'min' => 5.0, 'obj' => 'mysqli', 'preg' => '/\b(php_)?mysqli\.(so|dll)/i'),
'sqlite3' => array('ext' => 1, 'min' => 5.3, 'obj' => 'SQLite3', 'preg' => '/\b(php_)?sqlite3\.(so|dll)/i'),
'aes5' => array('php' => 1, 'min' => 5.3, 'max' => 8.11, 'obj' => 'PhpAes\Aes', 'preg' => '/\baes\.php/i'),
'aes4' => array('php' => 1, 'max' => 7.1, 'obj' => 'Aes', 'preg' => '/\baes_?4.*?\.php/i'),
'sha256' => array('php' => 1, 'max' => 5.2, 'func' => 'sha256', 'preg' => '/\bsha.?256\.php/i'),
'sha512' => array('php' => 1, 'max' => 5.2, 'func' => 'sha512', 'preg' => '/\bsha.?512\.php/i'),
'hashtool' => array('php' => 1, 'max' => 5.6, 'func' => 'hash_pbkdf2', 'preg' => '/\bhashtool\.php/i')) as $key => $var)
if(!isset($ext[$key]) and (!$pass or $pass == 'aes' or strstr($pass,$key))
and ($pass and $pass != 'aes' and strstr($pass,$key) or (!isset($var['min']) or $cfg['php'][3] >= $var['min']) and (!isset($var['max']) or $cfg['php'][3] < $var['max']))
and ((isset($var['ext']) and ((isset($var['func']) and $val = function_exists($var['func']) or isset($var['obj']) and $val = class_exists($var['obj']))
or @ini_get('enable_dl') and (defined('PHP_BINARY') and $val = listDir($var['preg'],dirname(PHP_BINARY),1)
or $cfg['php'][5] and $val = listDir($var['preg'],dirname($cfg['php'][5]),1) or $val = listDir($var['preg'],realpath(@ini_get('extension_dir')),1))))
or (isset($var['php']) and ((isset($var['func']) and $val = function_exists($var['func']) or isset($var['obj']) and $val = class_exists($var['obj']))
or $val = listDir($var['preg'],$cfg['fbtl'],1)))) and (is_bool($val) or $val = ifset($val,$var['preg']))) {
if(is_array($val)) {
$val = array_values($val);
if(isset($var['ext'])) {
if(realpath(@ini_get('extension_dir')) != dirname($val[0]))
@ini_set('extension_dir',dirname($val[0]));
@dl(basename($val[0]));
}
if(isset($var['php']))
include_once $val[0];
}
if(isset($var['func']) and function_exists($var['func']) or isset($var['obj']) and class_exists($var['obj'])) { // Erweiterung einrichten
$ext[$key] = (is_array($val)) ? ((count($val) > 1) ? $val : $val[0]) : $val;
dbug($key." nachgeladen",9);
}
}
if($pass == 'openssl' and $ext['openssl'] = (defined('OPENSSL_VERSION_TEXT')) ? OPENSSL_VERSION_TEXT : ((defined('OPENSSL_NO_PADDING')) ? "OpenSSL 0.9x" : false)) {
if(substr($cfg['head']['User-Agent'],-1) == ' ')
$cfg['head']['User-Agent'] .= $ext['openssl'];
$cfg['osn'] = ($var = ifset($ext['openssl'],'/[\d.]+/')) ? (float)$var[0] : false;
}
if(isset($cfg['aes']))
$cfg['aes'] = array_merge($cfg['aes'],$ext);
foreach($ext as $key => $var)
if(!isset($cfg['mods'][$key]))
$cfg['mods'][$key] = $var;
return ($pass == 'aes') ? preg_array('/aes\d+|openssl|mcrypt/',$ext,3) : ((count($ext) == 1 and isset($ext[$pass])) ? $ext[$pass] : $ext);
}
else
return $pass ? errmsg('16:Keine Konfig-Datei',__FUNCTION__) : false;
}
function konfig2array($data) { // FRITZ!Box-Konfig -> Array
$config = array();
if($data[0] == '*')
dbug("Konvertiere Fritz!Konfig...");
if($data[0] == '*' and preg_match_all('/^(?:\*{4}\s(.*?)\sCONFIGURATION\sEXPORT|(\w+)=(\S+))\s*$
|^\*{4}\s(?:CRYPTED)?(CFG|BIN|B64)FILE:(\S+)\s*?\r?\n(.*?)\r?\n^\*{4}\sEND\sOF\sFILE\s\*{4}\s*?($)/msx',$data,$array)) {
dbug($array,4,'Konfig2Array-#'); // Debugdaten Speichern
foreach($array[4] as $key => $var)
if($array[1][$key]) // Routername
$config['Name'] = $array[1][$key];
elseif($array[2][$key]) // Variablen
$config[$array[2][$key]] = $array[3][$key];
elseif(ifset($array[4][$key],'B64')) // Base64 Data
$config[$array[5][$key]] = base64_decode($array[6][$key]);
elseif(ifset($array[4][$key],'BIN')) // Bin Data
$config[$array[5][$key]] = pack('H*',preg_replace('/[^\da-f]+/i','',$array[6][$key]));
elseif(ifset($array[4][$key],'CFG') and preg_match_all('/^(\w+)\s(\{\s*$.*?^\})\s*$/smx',
str_replace(array("\r","\\\\"),array("","\\"),$array[6][$key]),$match)) // CfgData
foreach($match[1] as $k => $v)
$config/*[$array[5][$key]]*/[$v] = call_user_func(__FUNCTION__,$match[2][$k]);
dbug($config,4,'Konfig2Array'); // Debugdaten Speichern
}
elseif($data[0] == '{' and preg_match_all('/\{\s*?$.*?^\}/msx',$data,$array)) {
dbug($array,4,'Konfig2Array-Multi-#'); // Debugdaten Speichern
if(count($array[0]) > 1) // Ein oder Multi-Array
foreach($array[0] as $var) // Weitere Matches auf selber Ebene
$config[] = call_user_func(__FUNCTION__,$var);
elseif(preg_match_all('/^\s{8}(?:(\w+)\s(?:=\s(?:([^\s"]+)|(".*?(? $var) // Array durch arbeiten
if($match[2][$key]) // Einfache Werte
$config[$var] = ($match[2][$key] == 'yes') ? true : (($match[2][$key] == 'no') ? false : ((ifset($match[2][$key],'/^\d+(\.\d+)?$/')) ? (int)($match[2][$key]) : $match[2][$key]));
elseif($match[3][$key] and preg_match_all('/"(.*?)(? 1) ? $val[1] : $val[1][0]);
elseif($match[4][$key]) // Verschachteltes Array
$config[$var] = call_user_func(__FUNCTION__,preg_replace('/^\s{8}/m','',$match[4][$key]));
}
}
else
return errmsg('16:Keine Konfig-Datei',__FUNCTION__);
return $config;
}
function showaccessdata($data) { // Die Kronjuwelen aus Konfig-Daten heraussuchen
if(is_array($data))
return chr(intval($data[1],8));
$text = '';
$config = array();
if($konfig = konfig2array($data)) { // Konfig als Array umwandeln
dbug("Stelle Zugangsdaten zusammen...");
$access = array(
'Mobile-Stick' => array(&$konfig['ar7cfg']['serialcfg'],'=number,provider,username,passwd'),
'DSL' => array(&$konfig['ar7cfg']['targets'],'-name,>local>username,>local>passwd'),
'IPv6' => array(&$konfig['ipv6']['sixxs'],'=ticserver,username,passwd,tunnelid'),
'DynamicDNS' => array(&$konfig['ddns']['accounts'],'=domain,username,passwd'),
'MyFRITZ!' => array(&$konfig['jasonii'],'=user_email,user_password,box_id,box_id_passphrase,dyn_dns_name'),
'FRITZ!Box-Oberfl�che' => array(&$konfig['webui'],'=username,password'),
'Fernwartung' => array(&$konfig['websrv']['users'],'=username,passwd'),
'GUI-Unterordner' => array(&$konfig['websrv.subfolder']['=name,passwd']),
'TR-064' => array(&$konfig['TR_064'],'=username,password'),
'TR-069-Fernkonfiguration' => array(&$konfig['tr069cfg']['igd']['managementserver'],'=url,username,password,ConnectionRequestUsername,ConnectionRequestPassword'),
'Diagnose/Wartung' => array(&$konfig['tr069cfg']['lab'],'=CRUsername,CRPassword','+username,password,domain_name,update_url'),
'Netzwerkumgebung' => array(&$konfig['landevices']['landevices'],'-ip,name,neighbour_name,remotelogin_username,remotelogin_password'),
'Telekom-Mediencenter' => array(&$konfig['t_media'],'=refreshtoken,accesstoken'),
'Google-Play-Music' => array(&$konfig['gpm'],'=emailaddress,password,partition,servername'),
'Onlinespeicher' => array(&$konfig['webdavclient'],'=host_url,username,password'),
'WLAN' => array(&$konfig['wlancfg'],'/^(((guest|sta)_)?(ssid(_(scnd|thrd))?|pskvalue)|(sta_)?key_value\d|wps_pin|wds_(key|ssid))$/i'),
'Push-Dienst' => array(&$konfig['emailnotify'],'=From,To,SMTPServer,accountname,passwd','+To,arg0'),
'DECT-eMail' => array(&$konfig['configd'],'!<\?xml.*?.*?.*?(.*?) !s','!((name)|user_name|(?:smtp_)?server|user|pass|uipin|port)="([^"]+)"!s'),
'FRITZ!Box-Benutzer' => array(&$konfig['boxusers']['users'],'-name,email,passwd,password,googleauth_sharedsecret,googleauth_devicename'),
'Apps' => array(&$konfig['apps']['apps'],'-displayname,username,password,id,appavmaddress'),
'Apps2' => array(&$konfig['apps'],'=box_senderid,enc_secret,box_auth_id,box_auth_pwd'),
'InternetTelefonie' => array(&$konfig['voipcfg'],'_name,username,authname,passwd,registrar,stunserver,stunserverport,gui_readonly'),
'IP-Telefon' => array(&$konfig['voipcfg']['extensions'],'-extension_number,username,authname,passwd,clientid'),
'Online-Telefonbuch' => array(&$konfig['voipcfg']['onlinetel'],'-pbname,url,serviceid,username,passwd,refreshtoken,accesstoken'),
'FRITZ!NAS Share' => array(&$konfig['usbhost.filelinks'],'-id,path'),
'Virtual-Privat-Network' => array(&$konfig['vpncfg']['connections'],'-name,>localidremoteidlocalidremoteidxauth>username,>xauth>passwd'),
'WireGuard-Interface' => array(&$konfig['vpncfg']['global'],'/^wg_(private_key|public_key|listen_port)$/i'),
'WireGuard-Peer:' => array(&$konfig['vpncfg']['connections'],'-name,wg_public_key,wg_preshared_key'),
'Tickets' => array(&$konfig['usercfg']['valid_tickets'],'-#ticket'),
);
foreach($access as $key => $var) // Accessliste durcharbeiten
if(ifset($var[0])) {
if($var[1][0] == '/') { // Regul�re Ausdr�cke verwenden (Schl�sselname)
foreach($var[0] as $k => $v)
if(preg_match($var[1],$k) and $var[0][$k])// Schl�ssel Suchen und Pr�fen
$config[$key][$k] = $var[0][$k];
}
elseif($var[1][0] == '!' and preg_match($var[1],$var[0],$val) and preg_match_all($var[2],$val[1],$val)) { // Regul�re Ausdr�cke verwenden (Inhalt)
foreach($val[3] as $k => $v)
if(ifset($val[2][$k]))
$name = $v;
else
$config[$key][$name][$val[1][$k]] = $v;
}
elseif($var[1][0] == '=') { // Normal abfragen
$keys = explode(',',substr($var[1],1));
foreach($keys as $k)
if(ifset($var[0][$k])) // Schl�ssel Testen
$config[$key][$k] = $var[0][$k];
}
if(preg_match('/^([-+_])(.+)$/',$var[(isset($var[2])) ? 2 : 1],$keys)) { // Eine Schl�ssel-Ebene �berspringen
if($keys[1] == '-' and count(array_filter(array_keys($var[0]),'is_string')) > 0)
$var[0] = array($var[0]);
$keys[3] = explode(',',$keys[2]);
foreach($var[0] as $k => $v)
if((preg_match('/\d+\s*$/',$k,$val) or $keys[1] == '+') and is_array($v)) { // Neue Ebene gefunden
$name = $val ? false : $k;
foreach($keys[3] as $val)
if($val[0] == '>' and preg_match('/(\w+)([<>])(\w+)/',$val,$va1) and ifset($var[0][$k][$va1[1]][$va1[3]])) // Mit Regul�re Ausdr�cke noch eine Ebene �berspringen
if($name === false)
$name = (string)$var[0][$k][$va1[1]][$va1[3]];
else
$config[$key][$name][(($va1[2] == '<') ? $va1[1] : $va1[3])] = $var[0][$k][$va1[1]][$va1[3]]; // Den Vorigen Schl�ssel verwenden?
elseif($val[0] == '#' and ifset($var[0][$k][$kk = substr($val,1)])) { // Ketten-Werte
if(!isset($config[$key][$kk])) // Objekt schon vorhanden
$config[$key][$kk] = array(); // Leere Kette anlegen
$config[$key][$kk][] = $v[$kk]; // Kettenglied dranh�ngen
}
elseif(ifset($var[0][$k][$val])) // Auf der neuen Ebene Pr�fen
if($name === false)
$name = (string)$var[0][$k][$val];
else
$config[$key][$name][$val] = $var[0][$k][$val];
}
}
}
dbug($config,4,'ShowAccessData'); // Alle Fundst�cke ungefiltert sichern
foreach($config as $key => $var) // Filter: Doppelte Kategorien zusammenfassen
if($val = ifset($key,'/^([\w-]+)\d+$/') and isset($config[$val[1]])) {
$config[$val[1]] = array_merge($config[$val[1]],$var);
unset($config[$key]);
}
if(ifset($config['InternetTelefonie'])) // Filter: StunServerPort 3478 filtern
foreach($config['InternetTelefonie'] as $key => $var)
if(ifset($var['stunserverport'],3478))
unset($config['InternetTelefonie'][$key]['stunserverport']);
if(ifset($config['IPv6']) and ifset($config['IPv6']['ticserver']) and count($config['IPv6']) == 1) // Filter: IPv6 tivserver
unset($config['IPv6']);
if(ifset($config['TR-069-Fernkonfiguration']) and ifset($config['TR-069-Fernkonfiguration']['url']) and count($config['TR-069-Fernkonfiguration']) == 1) // Filter: TR069 url
unset($config['TR-069-Fernkonfiguration']);
if(ifset($config['Mobile-Stick']) and ifset($config['Mobile-Stick']['username'],'ppp') and ifset($config['Mobile-Stick']['passwd'],'ppp')) // Filter: Surf-Stick ppp
unset($config['Mobile-Stick']);
if(ifset($config['Onlinespeicher']) and !ifset($config['Onlinespeicher']['password'])) // Filter: Onlinespeicher
unset($config['Onlinespeicher']);
if(ifset($config['DECT-eMail'])) // Filter: DECT-eMail
foreach($config['DECT-eMail'] as $key => $var) {
if(ifset($var['server']) and ifset($var['port'])) { // Server & Port zusammenf�hren
$config['DECT-eMail'][$key]['server'] .= ":$var[port]";
unset($config['DECT-eMail'][$key]['port']);
}
if(ifset($var['user'],$key)) // Doppelte Namen
unset($config['DECT-eMail'][$key]['user']);
if(ifset($var['user_name'],$key))
unset($config['DECT-eMail'][$key]['user_name']);
}
if(ifset($config['Netzwerkumgebung'])) // Filter: Netzwerkumgebung
foreach($config['Netzwerkumgebung'] as $key => $var) // Hosts ohne Kennwort
if(!ifset($var['remotelogin_password']))
unset($config['Netzwerkumgebung'][$key]);
if(ifset($config['TR-064']) and !ifset($config['TR-064']['password'])) // Filter: TR-064
unset($config['TR-064']);
if(is_null($config['TR-069-Fernkonfiguration'])) // Filter: TR-069
unset($config['TR-069-Fernkonfiguration']);
elseif(is_null($config['TR-069-Fernkonfiguration']['url'])) // Filter: TR-069
unset($config['TR-069-Fernkonfiguration']['url']);
if(isset($config['WLAN'])) // Filter: WLAN
foreach(array('','WDS_','STA_') as $key)
if(isset($config['WLAN'][$key."ssid"])) { // Doppelte SSID
if(isset($config['WLAN'][$key."ssid_thrd"]) and ($config['WLAN'][$key."ssid"] == $config['WLAN'][$key."ssid_thrd"]
or isset($config['WLAN'][$key."ssid_scnd"]) and $config['WLAN'][$key."ssid_thrd"] == $config['WLAN'][$key."ssid_scnd"]))
unset($config['WLAN'][$key."ssid_thrd"]);
if(isset($config['WLAN'][$key."ssid_scnd"]) and $config['WLAN'][$key."ssid"] == $config['WLAN'][$key."ssid_scnd"])
unset($config['WLAN'][$key."ssid_scnd"]);
if($key)
foreach(array('ssid','key','pskvalue') as $var) // Doppelte Kennw�rter
if(isset($config['WLAN'][$var]) and isset($config['WLAN'][$key.$var]) and $config['WLAN'][$var] == $config['WLAN'][$key.$var]
or isset($config['WLAN']['pskvalue']) and isset($config['WLAN'][$key.$var]) and $config['WLAN']['pskvalue'] == $config['WLAN'][$key.$var])
unset($config['WLAN'][$key.$var]);
}
$a = array('/^\${4}\w+/','(Verschl�sselt)'); // Verschl�sselte Eintr�ge umschreiben
foreach($config as $key => $var)
if($var) {
if($val = preg_array($a[0],$var,3)) { // Array-Schl�ssel umbennenen
foreach($val as $k => $v) {
$config[$key][] = $v;
unset($config[$key][$k]);
}
$var = $config[$key];
}
foreach($var as $k => $v)
if(is_array($v)) { // Unterwert umschreiben
foreach($v as $kk => $vv)
if(ifset($vv,$a[0]))
$config[$key][$k][$kk] = $a[1];
}
elseif(ifset($v,$a[0])) // Hauptwert umschreiben
$config[$key][$k] = $a[1];
}
foreach($config as $name => $keys) // Array in Text Umwandeln
if($keys) {
foreach($keys as $key => $data) {
if(is_array($data) and array_values($data) !== $data) // Assoc-Array
foreach($data as $k => $v)
$data[$k] = "$k=$v";
$keys[$key] = "|$key|->|".str_replace('|','\|',implode(', ',(array)$data));
}
$text .= "\n$name\n".textTable(implode("\n",$keys))."\n";
}
}
else
dbug("showaccessdata fehlgeschlagen");
return preg_replace_callback('/\\\\([0-7]{3})/',__FUNCTION__,$text); // Zum Schluss noch Oktale-Ansi-Zeichen decodieren
}
function getevent($filter='aus',$sid=0) { // Ereignisse abrufen
global $cfg;
$filters = array('aus','system','internet','telefon','wlan','usb');
$jfilter = array('all','sys','net','fon','wlan','usb');
$filter = (($var = ifset($filters,$filter)) !== false) ? $var : 0;
dbug("Hole Ereignisse (Filter: {$filters[$filter]})");
if(!$sid)
$sid = $cfg['sid'];
$sid = (!is_bool($sid)) ? "&sid=$sid" : '';
if($cfg['fiwa'] < 500)
$data = request('POST-array','/cgi-bin/webcm',"getpage=../html/de/system/ppSyslog.html&logger:settings/filter=$filter$sid");
elseif($cfg['fiwa'] < 669)
$data = request('GET-array',"/system/syslog.lua?tab={$filters[$filter]}&event_filter=$filter&stylemode=print$sid");
$array = array(); // Date,Time,Text,Code,View,Help
if(ifset($data) and preg_match('!\["[\w:/]+log_separate"\]\s*=\s*\{((\s*\[\d+\]\s*=\s*\{(\s*\[\d+\]\s*=\s*".*?",?)+\s*\},?)+)\s*\}!',$data[1],$code)
and preg_match_all('!\s*\[(\d+)\]\s*=\s*\{((\s*\[\d+\]\s*=\s*".*?",?)+)\s*\}!',$code[1],$lines)) {
foreach($lines[2] as $key => $line)
if(preg_match_all('/"(.*?)(?(\S*)\s*(\S*)\s*(.*?)
!'
: '!]*>(?:)?(.*?)(?:
)? ]*>(.*?) ]*>]*?href="(.*?(\d+)\.html?)"[^>]*?>(.*?) !',$data[1],$lines)) {
if(count($lines) < 5)
foreach($lines[3] as $key => $line)
$array[] = array(0 => $lines[1][$key], 1 => $lines[2][$key], 2 => $line);
else
foreach($lines[5] as $key => $line)
$array[] = array(0 => $lines[1][$key], 1 => $lines[2][$key], 2 => $line, 3 => $lines[4][$key], 5 => $lines[3][$key]);
}
elseif($cfg['fiwa'] >= 669 and $data = request('POST-array','/data.lua',"xhr=1$sid&lang=de&page=log&xhrId=log&filter=".(($cfg['fiwa'] < 739) ? $filter : $jfilter[$filter])."&no_sidrenew=") and $js = json2array($data[1]) and $log = ifset($js['data']['log'],true)) {
$group = array_flip($jfilter);
foreach($log as $key => $var) {
$var = preg_replace('/sid=[\da-f]+&|[?&]sid=[\da-f]+$|\\\\(?=\/)/','',$var);
$array[] = ($cfg['fiwa'] >= 739)
? array($var['date'],$var['time'],$var['msg'],$var['id'],$group[$var['group']],$var['helplink'])
: $var;
}
}
else {
if(ifset($data))
dbug($data,4,'GetEvent-data');
return errmsg("8:Keine Ereignisse bekommen".(($var = errmsg(0,'request')) ? " ($var)" : ""),__FUNCTION__);
}
$event = array();
$a = count($array);
$b = 1;
while($a)
$event[strtotime("20".implode('-',array_reverse(explode('.',$array[--$a][0])))." ".$array[$a][1]).".".$b++] = $array[$a];
dbug($event,4,'GetEvent_array');
return $event;
}
function getcall($mode='call',$sid=0) { // Anrufliste auslesen (mode: array,call,data)
global $cfg;
if(!$sid)
$sid = $cfg['sid'];
if($cfg['fiwa'] > 530 and $data = request('get','/fon_num/foncalls_list.lua',"sid=$sid&apply=&csv=") // Download der Anrufliste
or $data = request('get','/cgi-bin/webcm',"getpage=../html/de/FRITZ!Box_Anrufliste.csv&sid=$sid")) {
$sep = (preg_match('/^sep=(.+)/',$data[1],$var)) ? $var[1] : ';';
$psep = preg_quote($sep,'/');
if(preg_match_all("/^".($preg = "([0-4]$psep((0[1-9]|[12]\d|3[10])\.(0[1-9]|1[0-2])\.(?:20)?(\d\d)\s+([\d:]+)|[\w .:\/+-]+)($psep(.*?)){4,5})\s*$/")."m",$data[1],$array)) {
dbug($array,4);
if($mode == 'data')
return $data[1];
foreach($array as $key => $var) // Komplette Matchliste umdrehen
$array[$key] = array_reverse($var);
$call = array();
foreach($array[1] as $key => $var)
if($time = strtotime(($array[3][$key]) ? "20{$array[5][$key]}-{$array[4][$key]}-{$array[3][$key]} {$array[6][$key]}" : $array[2][$key]))
$call["$time.$key"] = preg_split("/(? $sep, 'csv' => preg_replace('/\d[\s\S]*$/','',$data[1]), 'call' => $call, 'data' => $data[1]);
}
else
return errmsg("8:Keine Anrufliste bekommen",__FUNCTION__);
}
else
return errmsg("8:Anforderung der Anrufliste fehlgeschlagen".(($var = errmsg(0,'request')) ? " ($var)" : ""),__FUNCTION__);
}
function gettraffic($sid=0) { // Traffic-Z�hler als array auslesen
global $cfg;
if(!$sid)
$sid = $cfg['sid'];
$out = array();
dbug("Hole Traffic-Daten ",0,2);
if($cfg['fiwa'] < 550 // Fritz!OS 4 - 5.49
and $rp = request('GET','/cgi-bin/webcm',"getpage=../html/de/menus/menu2.html&var:lang=de&var:pagename=inetstat&var:menu=home&var:tabInetstat=1&sid=$sid")
and preg_match_all('/(?:^\s*(?:var\s)?(?:time|v?(?:in|out)[hl]|ap2ap)\s*=\s*[^;]*;\s*)+SetRow\(.*?\);|^\s*(?:var\s)?(?:max|rec|sent)(?:low|high)\s*=\s*\d*;/sm',$rp,$array)) {
dbug("f�r OS 4 - 5.49");
dbug($array,4);
foreach($array[0] as $line)
if(preg_match('/(time)\s=*\s*(\d*).*?SetRow\("(\w+)"/s',$line,$var)) {
$key = $var[3];
$out[$key][$var[1]] = intval($var[2]);
if(preg_match('!.*? \s*(\d*) !',$rp,$var))
$out[$key]['connect'] = intval($var[1]);
if(preg_match_all('/(in|out)([hl])\s*=\s*(\d*);/',$line,$m))
foreach($m[3] as $k => $v) {
if(!isset($out[$key][$m[1][$k]]))
$out[$key][$m[1][$k]] = 0;
$out[$key][$m[1][$k]] += ($m[2][$k] == 'h') ? pow(2,32) * intval($v) : intval($v);
}
$out[$key]['sum'] = $out[$key]['in'] + $out[$key]['out'];
}
elseif(preg_match('/(\w+?)(low|high)\s*=\s*(\d*);/',$line,$m)) { // Online-Z�hler (Traffic)
if(!isset($out['Counter'][$m[1]]))
$out['Counter'][$m[1]] = 0;
$out['Counter'][$m[1]] += ($m[2] == 'high') ? pow(2,32) * intval($m[3]) : intval($m[3]);
}
if(preg_match_all('!^\s*(?:var\s)?(cur|max)\s*=\s*Math.ceil\((\d+)/60\);!m',$rp,$m)) {
dbug($m,4);
$array = array('max' => 'maxtime', 'cur' => 'time');
foreach($m[1] as $key => $var)
if($m[2][$key])
$out['Counter'][$array[$var]] = floor(intval($m[2][$key]) / 60);
}
$out['Counter']['sum'] = $out['Counter']['rec'] + $out['Counter']['sent'];
}
elseif($cfg['fiwa'] >= 550 and $cfg['fiwa'] < 650 and $rp = request('GET','/internet/inetstat_counter.lua',"sid=$sid") and preg_match_all('!\["inetstat:status/(\w+)/(\w+)"\]\s*=\s*"(\d*)",!',$rp,$m)) { // OS 5.50 - 6.49
dbug("f�r OS 5.50 - 6.49");
dbug($m,4);
$array = array('BytesReceived' => 'in', 'BytesSent' => 'out', 'OutgoingCalls' => 'connect', 'PhyConnTimeOutgoing' => 'time');
foreach($m[3] as $key => $var)
if(preg_match('/^(.*?)((High)|Low)$/',$m[2][$key],$x)) {
if(!isset($out[$m[1][$key]][$array[$x[1]]]))
$out[$m[1][$key]][$array[$x[1]]] = 0;
$out[$m[1][$key]][$array[$x[1]]] += (isset($x[3])) ? pow(2,32) * $var : $var;
}
else
$out[$m[1][$key]][$array[$m[2][$key]]] = $var;
foreach($out as $key => $var)
$out[$key]['sum'] = $out[$key]['in'] + $out[$key]['out'];
dbug("Hole Budget-Z�hler");
if($rp = request('GET','/internet/inetstat_budget.lua',"sid=$sid") and preg_match_all('!\["(?:inetstat:status/ThisMonth|connection\d:settings/Budget)/(\w+?)(Low|High)?"\]\s*=\s*"(\d*)",!',$rp,$m)) {
dbug($m,4);
$array = array('ConnectionTime' => 'maxtime', 'Volume' => 'max', 'BytesReceived' => 'rec', 'BytesSent' => 'sent', 'PhyConnTimeOutgoing' => 'time');
foreach($m[3] as $key => $var)
if(preg_match('/^((High)|Low)$/',$m[2][$key],$x)) {
if(!isset($out['Counter'][$array[$m[1][$key]]]))
$out['Counter'][$array[$m[1][$key]]] = 0;
$out['Counter'][$array[$m[1][$key]]] += (isset($x[3])) ? pow(2,32) * $var : $var;
}
elseif(isset($array[$m[1][$key]]))
$out['Counter'][$array[$m[1][$key]]] = $var;
$out['Counter']['sum'] = $out['Counter']['rec'] + $out['Counter']['sent'];
}
}
elseif($cfg['fiwa'] >= 650 and $cfg['fiwa'] < 724 and $rp = request('POST','/data.lua',"xhr=1&sid=$sid&lang=de&no_sidrenew=&page=netCnt") and preg_match_all('!]*>[^<>\n]+ \s*(?:]*>[\d:]+ \s*){5} !x',$rp,$m)) { // OS 6.50 - 7.23
dbug("f�r OS 6.50+");
dbug($m,4);
$cols = array('label','time','sum','out','in','connect');
$rows = array('Today','Yesterday','ThisWeek','ThisMonth','LastMonth');
foreach($m[0] as $key => $var)
if(preg_match_all('!]*>([^<>]+) !',$var,$line))
foreach($line[1] as $k => $v)
if($k)
$out[$rows[$key]][$cols[$k]] = ($k < 5 and $k > 1) ? $v * 1024 * 1024 : (($k == 1 and $x = explode(':',$v)) ? intval($x[0]) * 60 + intval($x[1]) : $v);
if(preg_match('!\s*]*>[^<>]* \s*]*>]*>(?:]*>\s* )+\s*
\s* \s*(?:(\d+)\D+(\d+)\sMB|(\d+)\D+(\d+)\D+(\d+)\D+) \s* !',$rp,$m)) {
dbug($m,4);
if($m[2]) {
$out['Counter']['sum'] = intval($m[1]) * 1024 * 1024;
$out['Counter']['max'] = intval($m[2]) * 1024 * 1024;
}
else {
$out['Counter']['time'] = intval($m[3]) * 60 + intval($m[4]);
$out['Counter']['maxtime'] = intval($m[5]) * 60;
}
}
}
elseif($cfg['fiwa'] >= 724 and $rp = request('POST','/data.lua',"xhr=1&sid=$sid&lang=de&no_sidrenew=&page=netCnt") and preg_match_all('!]*>]*>[^<>\n]+ \s*(?:]*>[\d:\s]+ \s*)+ !x',$rp,$m) and preg_match_all('/"(\w+)":\{((?:"\w+":"\d+",?)+)\}/sx',$rp,$n)) { // OS 7.24+
dbug("f�r OS 7.24+");
foreach($m[0] as $var)
if(preg_match('!(?:]*>(?:(\d+):)?([\w\s]+) \s*){2}(?:]*>([\s\d]+) \s*){4}!',$var,$v)) {
$out[$v[1]]['time'] = $v[2] * 60 + $v[3];
$out[$v[1]]['connect'] = $v[4];
$out[$v[1]]['in'] = $out[$v[1]]['out'] = $out[$v[1]]['sum'] = 0;
}
$cols = array('Sent' => 'out', 'Received' => 'in');
foreach($n[2] as $key => $var)
if(preg_match_all('/"Bytes(Sent|Received)(High|Low)":"(\d+)"/',$var,$x))
foreach($x[1] as $k => $v) {
$k = $x[3][$k] * (($x[2][$k] == 'Low') ? 1 : pow(2,32));
$out[$n[1][$key]][$cols[$v]] += $k;
$out[$n[1][$key]]['sum'] += $k;
}
if(preg_match('! \s*]*>\w+ \s*\s*\s*]*> \s*]*> \s*
\s* \s*(?:(\d+)\D+(\d+)\sMB|(?:(\d+)\s\w+\s)?(?:(\d+)\s\w+)?\D+(\d+)\s\w+) \s* !sx',$rp,$v))
if($v[1].$v[2]) {
$out['Counter']['sum'] = intval($v[1]) * 1024 * 1024;
$out['Counter']['max'] = intval($v[2]) * 1024 * 1024;
}
else {
$out['Counter']['time'] = intval($v[3]) * 60 + intval($v[4]);
$out['Counter']['maxtime'] = intval($v[5]) * 60;
}
}
else {
dbug("- fehlgeschlagen");
$out = errmsg("8:Traffic konnte nicht ermittelt werden",__FUNCTION__);
}
if($out) {
$out['Time'] = ($cfg['http']['Date']) ? strtotime($cfg['http']['Date']) : 0;
dbug($out,9);
}
return $out;
}
function smarthome($cmd=0,$ain=0,$set=array(),$sid=0) { // SmartHome Ger�teliste, Infos, Schalten (cmd:string/array, ain, set:array, sid)
global $cfg;
if($cmd == 'temp') // temp: Temperatur entschl�sseln
$out = ($ain == 0 or $ain == 253) ? "aus" : (($ain == 1 or $ain == 254) ? "an" : (($ain == 2) ? 'um' : ($ain/2)."�C"));
elseif($cmd == 'functionbit') { // functionbit: functionbitmask Entschl�sseln
$name = explode(',',"HANFUN Ger�t,Bit1,Lampe,Bit3,Alarm-Sensor,Taster,Heizk�rperregler,Energie Messger�t,Temperatursensor,Schaltsteckdose,"
."AVM DECT Repeater,Mikrofon,Gruppe,HANFUN Unit,Bit14,Schaltbar,Dimmbar,Farblampe");
foreach($name as $key => $var) {
if($ain % 2)
$set[$key] = $var;
$ain >>= 1;
}
return $set;
}
elseif($cmd == 'template') {
foreach($set as $var)
if(isset($var['template']))
foreach($var['template'] as $val)
if($ain == $val['identifier'] or $ain == $val['id'] or strtolower($ain) == strtolower($val['name']))
return $val;
return false;
}
elseif($ain === true and is_array($cmd) and !$set) { // Type STRING aus Array weitgehend in INT/FLOAT umwandeln
foreach($cmd as $key => $var)
$set[(preg_match('/^\d+$/',$key)) ? intval($key) : $key] = (is_array($var)) ? call_user_func(__FUNCTION__,$var,true)
: ((is_string($var) and preg_match('/^(?:(\d{1,7})|((?!0\.0$)\d{1,7}\.\d+))($)/',$var,$val))
? (($val[1] != '') ? intval($var) : (($val[2] != '') ? floatval($var) : $var)) : $var);
return $set;
}
else {
dbug(compact(explode(',','cmd,ain,set,sid')),9);
if(!$sid)
$sid = $cfg['sid'];
dbug("Hole SmartHome Ger�teliste");
$out = false;
$link = '/webservices/homeautoswitch.lua';
$parm = "sid=$sid&switchcmd=";
$device = array();
$hfu = array();
if($ain and $set === true and preg_match('/on|off|trip/',$cmd)) { // Force-Modus
$do = array('Aktor wurde ausgeschaltet','Aktor wurde eingeschaltet','on' => 'setswitchon', 'off' => 'setswitchoff', 'trip' => 'setswitchtoggle');
if($out = request('GET',$link,$parm.$do[$cmd]."&ain=$ain")) {
if(ifset($out,'/^\d+$/') and isset($do[(int)$out]))
$out = $do[(int)$out];
}
else
$out = "Aktor '$ain' nicht gefunden";
}
elseif($xml = request('GET',$link,$parm."getdevicelistinfos") and preg_match_all('!<(device|group)\s([^>]+)>(.*?)\1>!s',preg_replace('/[\r\n]+/','',$xml),$list)) {
if($cmd == 'xml') // xml: Gebe ROH-Daten zur�ck
return $xml;
dbug($xml,9);
dbug($list,4);
foreach($list[2] as $k => $v) { // Devices und Gruppen durchgehen
$device[$k] = xml2array($list[3][$k],false); // Device Infos einlesen
if(preg_match_all('/([\w-]+)="([^"]+)"/',$v,$m)) // Device Attribute einlesen
foreach($m[1] as $key => $var)
$device[$k][$var] = $m[2][$key];
if(ifset($device[$k]['functionbitmask'])) // Device Bitmaske entschl�sseln
$device[$k]['functionbitname'] = call_user_func(__FUNCTION__,'functionbit',$device[$k]['functionbitmask']);
if(isset($device[$k]['etsiunitinfo']) and $var = $device[$k]['etsiunitinfo']) { // HAN-FUN Unit/Ger�t
$units = array( 266 => 'DIMMER_SWITCH', 278 => 'DIMMABLE_COLOR_BULB',
281 => 'BLIND', 273 => 'SIMPLE_BUTTON', 519 => 'GLAS_BREAK_DETECTOR',
640 => 'SIREN', 518 => 'FLOOD_DETECTOR', 257 => 'SIMPLE_ON_OFF_SWITCH',
282 => 'LAMELLAR', 265 => 'DIMMABLE_LIGHT', 256 => 'SIMPLE_ON_OFF_SWITCHABLE',
262 => 'AC_OUTLET', 512 => 'SIMPLE_DETECTOR', 513 => 'DOOR_OPEN_CLOSE_DETECTOR',
277 => 'COLOR_BULB', 515 => 'MOTION_DETECTOR', 514 => 'WINDOW_OPEN_CLOSE_DETECTOR',
264 => 'SIMPLE_LIGHT', 520 => 'VIBRATION_DETECTOR', 263 => 'AC_OUTLET_SIMPLE_POWER_METERING');
$types = array( 277 => 'KEEP_ALIVE', 256 => 'ALERT', 512 => 'ON_OFF',
513 => 'LEVEL_CTRL', 514 => 'COLOR_CTRL', 516 => 'OPEN_CLOSE', 517 => 'OPEN_CLOSE_CONFIG',
772 => 'SIMPLE_BUTTON', 1024 => 'SUOTA-Update');
$hfu[$device[$k]['id']] = $var['etsideviceid'];
if(ifset($var['unittype']) and isset($units[$var['unittype']]))
$device[$k]['etsiunitinfo']['unittypename'] = $units[$var['unittype']];
if(ifset($var['interfaces']))
$device[$k]['etsiunitinfo']['interfacename'] = preg_array('/^('.str_replace(',','|',$var['interfaces']).')$/',$types,3);
}
if(isset($device[$k]['functionbitname'][2])) { // Einstellbare Vorgabe-Farben ermitteln
if($xml = request('GET',$link,$parm."getcolordefaults") and preg_match_all('/]*>.*?<\/hs>/s',$xml,$array)) // Farbwerte extrahieren
foreach($array[0] as $var)
if(is_array($val = xml2array($var,-1)) and $device[$k]['defaults']['hue'][$val['hs']['color'][0][-1]['hue']] = $val['hs']['name'][0])
foreach($val['hs']['color'] as $v)
$device[$k]['defaults']['color'][$val['hs']['name'][0]][$v[-1]['sat_index']] = array('hue' => $v[-1]['hue'], 'sat' => $v[-1]['sat'], 'val' => $v[-1]['val']);
if(preg_match_all('/]*(\d+)[^>]*\/>/s',$xml,$array)) // Farbtemperatur extrahieren
$device[$k]['defaults']['temperature'] = $array[1];
}
}
if($xml = request('GET',$link,$parm."gettemplatelistinfos") and preg_match_all('!<(template)\s([^>]+)>(.*?)\1>!s',preg_replace('/[\r\n]+/','',$xml),$list))
foreach($list[2] as $key => $var) // Templates durchgehen
if(preg_match_all('/(\w+)="([^"]*)"/',$var,$array)) {
$array = array_combine($array[1],$array[2]);
$array['name'] = preg_match('/(.*?)<\/name>/',$list[3][$key],$m) ? $m[1] : false;
$array['device'] = preg_match('/ /',$list[3][$key],$m) ? $m[1] : false;
if(isset($array['functionbitmask']))
$array['functionbitname'] = call_user_func(__FUNCTION__,'functionbit',$array['functionbitmask']);
foreach($device as $key => $var)
if($var['identifier'] == $array['device']) {
$device[$key]['template'][] = $array+array('key' => $key); // Eintragen
break;
}
}
$idx = array(); // ID-Index anlegen
foreach($device as $key => $var)
$idx[$var['id']] = $key;
foreach($hfu as $key => $var) { // Doppelte HAN-FUN Units/Ger�te zusammenlegen
if((float)$device[$idx[$key]]['fwversion'] == 0)
$device[$idx[$key]]['fwversion'] = $device[$idx[$var]]['fwversion'];
$device[$idx[$key]]['link'] = $device[$idx[$var]]; // Kopie sichern
unset($device[$idx[$var]]); // Device l�schen
unset($hfu[$key]); // Link zum Device l�schen
}
dbug($device,9);
$device = call_user_func(__FUNCTION__,$device,true);
if(!$ain and $cmd == 'array')
return $device;
if($ain) { // Einzelnen Aktor Schalten oder auslesen
foreach($device as $v)
if($ain == $v['id'] or preg_replace('/\W/','',strtoupper($ain)) == preg_replace('/\W/','',$v['identifier']) or strtolower($ain) == strtolower($v['name'])) {
dbug("Aktor/Gruppe '$ain' gefunden",9);
$ain = $v;
break;
}
if($cmd == 'array')
return $ain;
if(is_array($ain))
if($cmd == 'info') {
$out = "Hauptdaten|Name:|$ain[name]
|AIN:|$ain[identifier]
|ID:|$ain[id]
|Hersteller:|$ain[manufacturer]".((ifset($ain['productname'])) ? "\n|Modell:|$ain[productname]" : "")."
|Funktionen:|".implode(", ",$ain['functionbitname'])."
|Verbindung:|".(($ain['present']) ? "Online" : "Offline")
.((ifset($ain['fwversion']) and (float)$ain['fwversion']) ? "\n|Firmware:|$ain[fwversion]" : "")
.((isset($ain['txbusy'])) ? "\n|Besch�ftigt:|".(($ain['txbusy']) ? "Ja" : "Nein") : "")
.((ifset($ain['simpleonoff'])) ? "\n|Schaltzustand:|A".(($ain['simpleonoff']['state']) ? "n" : "us") : "")
.((ifset($ain['battery'])) ? "\n|Batterie:|$ain[battery]%".(($ain['batterylow']) ? " (Schwach)" : "") : "")."\n";
if(ifset($ain['template'])) {
$array = array();
foreach($ain['template'] as $var)
$array[] = $var['name'];
$out .= "|Template:|".implode(", ",$array)."\n";
}
if(ifset($ain['groupinfo'])) {
$array = explode(',',$ain['groupinfo']['members']);
foreach($array as $key => $var) {
$val = $device[$idx[intval($var)]];
$array[$key] = (ifset($val['name'])) ? $val['name'] : $val['identifier'];
}
$out .= "Gruppe|Mitglieder:|".implode(", ",$array)."\n";
if(ifset($ain['groupinfo']['masterdeviceid'])) {
$var = $device[$idx[$ain['groupinfo']['masterdeviceid']]];
$out .= "|Master:|".(($var['name']) ? $var['name'] : $var['identifier'])."\n";
}
}
if(ifset($ain['switch']) and $x = $ain['switch'] or ifset($ain['hkr']) and $x = $ain['hkr'])
$out .= "Schloss|Taster:|".(($x['devicelock']) ? "Gesperrt" : "Frei")."
|Fernsteuerung:|".(($x['lock']) ? "Gesperrt" : "Frei")."\n";
if(ifset($ain['powermeter']) and $x = $ain['powermeter'])
$out .= "Energie Messger�t|Spannung:|".number_format(intval($x['voltage'])/1e3,2,",",".")." Volt
|Leistung:|".number_format(intval($x['power'])/1e3,3,",",".")." Watt
|Stromz�hler:|".number_format(intval($x['energy'])/1e3,3,",",".")." KiloWattStunden\n";
if(ifset($ain['switch']) and $x = $ain['switch'])
$out .= "Schaltsteckdose|Schaltzustand:|".(($x['state']) ? "An" : "Aus")."
|Modus:|".ucfirst($x['mode'])."\n";
if(ifset($ain['temperature']) and $x = $ain['temperature'])
$out .= "Temperatur|Sensor:|".(intval($x['celsius'])/10)."�C".(($x['offset']) ? "\n|Offset:|".preg_replace('/^(?=\d)/','+',$x['offset']/10) : "")."\n";
if(ifset($ain['hkr']) and $x = $ain['hkr'])
$out .= "Heizregler|Aktuell:|".call_user_func(__FUNCTION__,'temp',$x['tist'])."
|Eingestellt:|".call_user_func(__FUNCTION__,'temp',$x['tsoll'])."
|Spar:|".call_user_func(__FUNCTION__,'temp',$x['absenk'])."
|Komfort:|".call_user_func(__FUNCTION__,'temp',$x['komfort'])."
|N�chste �nderung:|".date('d.m.Y H:i:s',$x['nextchange']['endperiod'])." Uhr auf ".call_user_func(__FUNCTION__,'temp',$x['nextchange']['tchange'])."
|Fenster:|".(($x['windowopenactiv']) ? "Offen" : "Geschlossen")."
|Sommerpause:|".(($x['summeractive']) ? "Aktiviert" : "Aus")."
|Urlaub:|".(($x['holidayactive']) ? "Aktiv" : "Aus")."
|Letzter Fehler:|".(($y = explode("\n","Kein Fehler
Keine Adaptierung m�glich
Ventilhub zu kurz oder Batterieleistung zu schwach
Keine Ventilbewegung m�glich
Die Installation wird gerade vorbereitet
Der Heizk�rperregler ist im Installationsmodus und kann auf das Heizungsventil montiert werden
Der Heizk�rperregler passt sich nun an den Hub des Heizungsventils an")) ? ((ifset($y[$x['errorcode']])) ? $y[$x['errorcode']] : "Unbekannt ($x[errorcode])") : "")."\n";
if(isset($ain['functionbitname'][2])) { // Lampe
$out .= "Lampe";
if(ifset($ain['levelcontrol']) and $x = $ain['levelcontrol'])
$out .= "|Helligkeit:|".($v = (isset($x['levelpercentage']) ? $x['levelpercentage'] : (isset($x['level']) ? floor($x['level']/2.55) : 'Unbekannt')))."%\n";
if(ifset($ain['colorcontrol']) and $x = $ain['colorcontrol']) {
if(isset($x['hue']) and $h = $x['hue'] and isset($ain['defaults']['hue'])) {
if(isset($ain['defaults']['hue'][$h]))
$hue = $ain['defaults']['hue'][$h];
else {
$var = array_values($ain['defaults']['hue']);
$hue = $var[round($h/30)%12];
}
$out .= "|Farbwinkel:|{$h}� ($hue)\n";
}
$var = array('Warm','Neutral','Kalt');
if(isset($x['saturation']))
$out .= "|Farbs�ttigung:|".floor($s = intval($x['saturation']) / 2.55)."%\n";
if(isset($x['temperature']) and $y = $x['temperature'])
$out .= "|Farbtemperatur:|$y K (".(($z = preg_array('/'.preg_quote($y,'/').'/',$ain['defaults']['temperature'],4)) ? $var[floor($z / 3)]." ".($z % 3 + 1)
: (($y >= 2700 and $y <= 3400) ? "Warm" : (($y >= 3800 and $y <= 4700) ? "Neutral" : (($y >= 5300 and $y <= 6500) ? "Kalt" : "Unbekannt")))).")\n";
if(isset($ain['defaults']['hue']))
$out .= "|Vorgabefarben:|".implode(', ',array_merge($var,$ain['defaults']['hue']))."\n";
if(isset($ain['defaults']['temperature']))
$out .= "|Temperaturwerte|".implode(", ",$ain['defaults']['temperature'])." (Kelvin)\n";
}
if(isset($h) and isset($s) and isset($v)) { // HSV in RGB umrechnen
for($c = array(0,0,0), $i = 0; $i < 4; $i++)
if(abs(intval($h) - $i * 120) < 120)
$c[$i % 3] = 1 - ((max(60,abs(intval($h) - $i * 120)) - 60) / 60);
for($h = max($c), $i = 0; $i < 3; $i++)
$c[$i] = round(($c[$i] + ($h - $c[$i]) * (1 - $s / 100)) * 255 * ($v / 100));
$out .= sprintf("|RGB-Farbwert:|#%02X%02X%02X\n",$c[0],$c[1],$c[2]);
}
}
if(ifset($ain['button'])) { // Taster
$array = (ifset($ain['button'][0])) ? $ain['button'] : array($ain['button']);
foreach($array as $k => $v)
$out .= "Schalter #".($k + 1)."|Name:|$v[name]
|AIN:|$v[identifier]
|ID:|$v[id]".((ifset($v['lastpressedtimestamp'])) ? "\n|Zuletzt bet�tigt:|".date('d.m.Y H:i:s',$v['lastpressedtimestamp'])." Uhr" : "")."\n";
}
if(ifset($ain['etsiunitinfo']) and $x = $ain['etsiunitinfo']) // HAN-FUN Unit/Ger�t
$out .= "HAN-FUN Unit|Type:|$x[unittypename]\n|Interfaces:|".implode(", ",$x['interfacename'])."\n";
if($cfg['dbug']) // Debug-Modus
foreach($ain as $key => $var)
if(is_null($ain[$key]))
unset($ain[$key]);
dbug($ain,9);
}
elseif($ain['present']) {
$do = array('on' => 'setswitchon', 'off' => 'setswitchoff', 'trip' => 'setswitchtoggle');
$d0 = array_flip(array('off','on','trip'));
$aid = str_replace(' ','',$ain['identifier']);
if(ifset($ain['txbusy'])) // Besch�ftigt
$out = "$ain[name] ist noch mit der letzten Aktion besch�ftigt!";
elseif(ifset($ain['simpleonoff']) and ifset($cmd,'/test/')) {// Universal Schnelltest f�r on / off
$out = "$ain[name] ist A".(($ain['simpleonoff']['state']) ? "N" : "US")." geschaltet!";
if($ain['simpleonoff']['state'])
errmsg("1:$out",__FUNCTION__);
}
elseif(ifset($ain['simpleonoff']) and ifset($cmd,'/on|off/'))// Universal an / aus
$out = request('GET',$link,$parm."setsimpleonoff&onoff=".$d0[$cmd]."&ain=$aid");
elseif(ifset($ain['functionbitname'][9])) { // Schaltsteckdosen
if(ifset($cmd,'/test/')) { // test
$out = "$ain[name] ist A".(($ain['switch']['state']) ? "N" : "US")." geschaltet!";
if($ain['switch']['state'])
errmsg("1:$out",__FUNCTION__);
}
elseif(ifset($ain['switch']['lock']))
$out = errmsg("8:Aktor ist f�r die Fernwartung gesperrt!",__FUNCTION__);
elseif(ifset($cmd,'/on|off|trip/')) // on / off / trip
$out = request('GET',$link,$parm.$do[$cmd]."&ain=$aid");
}
elseif(ifset($ain['functionbitname'][6])) { // Heizk�rperregler
if($cmd == 'test') {
$out = "$ain[name] ist ".preg_replace('/^(?=\d)/','auf ',call_user_func(__FUNCTION__,'temp',$ain['hkr']['tsoll']))." gestellt";
if(!$ain['hkr']['tsoll'] and $ain['hkr']['tsoll'] != 253)
errmsg("1:$out",__FUNCTION__);
}
elseif(ifset($ain['hkr']['lock']))
$out = errmsg("8:Aktor ist f�r die Fernwartung gesperrt!",__FUNCTION__);
elseif(ifset($cmd,'/on|off|trip|set/')) {
$var = (isset($set['hkr'])) ? $set['hkr'] : false;
$do = array('on' => 254, 'off' => 253, 'trip' => ($ain['hkr']['tsoll'] == 253) ? 254 : 253, 'set' => ($var == 'spar')
? $ain['hkr']['absenk'] : (($var == 'komfort') ? $ain['hkr']['komfort'] : (($var == 'an' or $var == 'on') ? 254
: ((!$var or $var == 'aus' or $var == 'off') ? 253 : floor(floatval($var)*2)))));
$out = request('GET',$link,$parm."sethkrtsoll¶m=".$do[$cmd]."&ain=".urlencode($ain['identifier']));
}
}
elseif(ifset($ain['functionbitname'][2]) and $cmd == 'set') { // Lampe
$hue = $sat = $val = $kel = $col = $a = 0;
$delay = "&duration=".((ifset($set['delay'])) ? $set['delay'] : 0);
if($hsv = ifset($set['hsv'],'/\d+/a')) // HSV-Angaben
foreach($xxx = array_combine(array('hue','sat','val'),array_pad($hsv[0],3,0)) as $key => $var)
$$key = round($var * (($a++) ? 2.55 : 1));
if($var = ifset($set['color'],'/^(?:(warm)|(neutral)|(cold|kalt)|([\w\s]*?))([1-3]?)($)/ui') or $var = ifset($set['color'],'/(^)()()([\w\s�������]+)([1-3]?)($)/'))
if($var[1] or $var[2] or $var[3])
$kel = $ain['defaults']['temperature'][(($var[1]) ? 0 : (($var[2]) ? 3 : (($var[3]) ? 6 : 0))) + ($var[5] ? $var[5]-1 : 0)];
elseif($var[4])
extract($ain['defaults']['color'][$col = preg_array('/^'.preg_quote(utf8($var[4],1),'/').'/i',array_combine(array_keys($ain['defaults']['color']),preg_replace('/\s+/','',array_keys($ain['defaults']['color']))),4)][$var[5] ? $var[5] : 1]);
if(ifset($set['dimm']))
$val = round($set['dimm'] * 2.55);
if(ifset($set['kelvin']))
$kel = (int)$set['kelvin'];
if(($hue and $sat or $hsv)) {
dbug("Setzte Farbe {$hue}� und S�ttigung $sat/255 auf $ain[name]");
if(request('GET',$link,$parm."setcolor&hue=$hue&saturation=$sat$delay&ain=$aid"))
$out = "$ain[name] wurde auf ".($col ? "die Farbe $col" : "den Farbwinkel {$hue}�")." mit ".round($sat/2.55)."% Farbs�ttigung eingestellt";
}
elseif($kel) {
dbug("Setzte $kel Kelvin auf $ain[name]");
$out = (trim(request('GET',$link,$parm."setcolortemperature&temperature=$kel$delay&ain=$aid")) == $kel) ? "$ain[name] wurde auf $kel Kelvin gestellt" : "";
}
if($val) {
while($var = call_user_func(__FUNCTION__,'array',$aid) and ifset($var['txbusy'])) { // Warten bis die Lampe fertig ist
dbug("Warte...");
sleep(1);
}
dbug("Setze Helligkeit $val auf $ain[name]");
if(request('GET',$link,$parm."setlevel&level=$val$delay&ain=$aid")) // Helligkeit setzen
$out = ($out ? "$out und" : "$ain[name] wurde")." auf ".round($val/2.55)."% Helligkeit gesetzt";
}
}
elseif(ifset($cmd,'/open|close|stop/i') and isset($ain['etsiunitinfo']['interfacename'][281])) // Rolll�den
$out = (request('GET',$link,$parm."setblind&target=".strtolower($cmd)."&ain=$aid")) ? "$ain[name] wurde geschaltet" : "";
if(!$out)
$out = errmsg("64:Aktor unterst�tzt diese Funktion nicht!",__FUNCTION__);
elseif(ifset($out,'/^\d+$/'))
$out = "$ain[name] wurde ".preg_replace('/^(?=\d)/','auf ',call_user_func(__FUNCTION__,'temp',$out))." geschaltet!";
}
else
$out = errmsg("8:Aktor ist nicht verbunden bzw. OFFLINE!",__FUNCTION__);
elseif($cmd == 'set' and $tmp = call_user_func(__FUNCTION__,'template',$ain,$device)) { // Template setzen
dbug("Setze Template: '$tmp[name]' von: '".$device[$tmp['key']]['name']."'");
request('GET',$link,$parm."applytemplate&ain=$tmp[identifier]");
}
elseif(ifset($cmd,'/on|off|trip/')) {
$do = array('on' => 'setswitchon', 'off' => 'setswitchoff', 'trip' => 'setswitchtoggle');
$out = request('GET',$link,$parm.$do[$cmd]."&ain=".urlencode($ain));
}
else
$out = errmsg("8:Aktor '$ain' nicht gefunden!",__FUNCTION__);
}
elseif($cmd == 'json')
$out = (function_exists('json_encode')) ? json_encode(utf8($device,1))."\n" : errmsg("64:JSON_Encode von PHP {$cfg['php'][0]} ist fehlgeschlagen",__FUNCTION__);
else { // Device-Liste zur�ckgeben
$list = array();
$spar = array(0,0);
foreach($device as $k => $v) {
$array = array('ID' => 'id', 'AIN' => 'identifier', 'Name' => 'name', 'Modell' => 'productname', 'OS' => 'fwversion');
foreach($array as $key => $var)
$list[$k][$key] = (ifset($v[$var])) ? $v[$var] : false;
if(!$list[$k]['Modell'] and ifset($v['groupinfo'])) {
$var = count(explode(',',$v['groupinfo']['members']));
$list[$k]['Modell'] = "Gruppe ($var Mitglied".(($var == 1) ? "" : "er").")";
}
$list[$k]['Batterie'] = (isset($v['battery'])) ? ($spar[0] = "$v[battery]%") : "-";
$val = "-";
if(ifset($v['temperature'])) { // Temperatur
$x = $v['temperature'];
if(isset($x['celsius']))
$val = (intval($x['celsius'])/10)."�C";
if(isset($x['offset']) and $x['offset'])
$val .= " (".preg_replace('/^(?=\d)/','+',$x['offset']/10).")";
$spar[1] = $val;
}
elseif(ifset($v['hkr']) and ifset($v['hkr']['tist'])) // Alternative M�glichkeit �ber HKR
$val = call_user_func(__FUNCTION__,'temp',$v['hkr']['tist']);
$list[$k]['Temperatur'] = $val;
$val = "offline"; // Status
if($v['present']) {
if(isset($v['switch']['state'])) { // Schaltsteckdose
if(($val = ($v['switch']['state']) ? "an" : "aus") == 'on' and isset($v['powermeter']['power']))
$val .= " (".($v['powermeter']['power']/1e3)."W)";
}
elseif(isset($v['hkr']['tsoll'])) // Heizk�rperregler
$val = call_user_func(__FUNCTION__,'temp',$v['hkr']['tsoll']);
elseif(isset($v['simpleonoff']['state'])) // Schaltlampe
$val = ($v['simpleonoff']['state']) ? "an" : "aus";
else
$val = "online"; // Unbekannt
}
$list[$k]['Status'] = $val;
if(isset($device[$k]['template'])) { // Templates
$array = array();
foreach($device[$k]['template'] as $key => $var) {
$array['ID'] = $var['id'];
$array['AIN'] = $var['identifier'];
$array['Name'] = $var['name'];
$array['Modell'] = 'Template';
$list["$k.$key"] = $array;
}
}
}
if(!array_sum($spar)) // Unn�tze Spalten einsparen
foreach($list as $key => $var) {
if(!$spar[0])
unset($list[$key]['Batterie']);
if(!$spar[1])
unset($list[$key]['Temperatur']);
}
if($cmd == 'csv') { // CSV-Ausgabe
$s = (ifset($set['csv'])) ? $set['csv'] : ";";
$out = implode($s,array_keys(reset($list)))."\n";
foreach($list as $var)
$out .= implode($s,preg_replace('/'.preg_quote($s,'/').'/','\\$0',$var))."\n";
}
elseif($cmd == 'list') { // Text-Ausgabe
$out = implode('|',array_keys(reset($list)))."\n";
foreach($list as $var)
$out .= implode('|',preg_replace('/'.preg_quote('|','/').'/','\\$0',$var))."\n";
}
else // RAW-Ausgabe
$out = $list;
}
}
else
$out = errmsg("8:Keine Aktoren gefunden!",__FUNCTION__);
}
return $out;
}
function init($ver,$x=0,$y=0) { // Fritz!Box Tools Initialisieren
global $cfg,$script,$self,$Self;
if((float)phpversion() > 4.3 and $ver = ifset($ver,'/^(\w+) ([\d.]+) \(c\) (?:GNU )?GPL (\d\d)\.(\d\d)\.(\d{4}) by ([\w ]+?) <(\w+:\/\/[\w.-]+)(.*?)>$/')) {
define($ver[1],1); // Feste Kennung f�r Plugins etc.
$ver[] = intval($ver[5].$ver[4].$ver[3]); // fb_tools Datum (9)
$ver[] = floatval($ver[2]); // fb_tools Version (10)
$var = $_SERVER['argv'][0];
$script = (ifset($var)) ? (($var = realpath($var)) ? $var : realpath($var.".bat")) : $_SERVER['PHP_SELF'];
$self = basename($var); // Exec-Script (Wie von der Konsole aufgerufen)
$Self = basename($script); // Script_Name
$cfg['dir'] = preg_replace(array('/\\\\/','/\/$/'),array('/',''),dirname($script));
$cfg['ver'] = $ver; // FB_Tools Versionsstring
$cfg['ext'] = strtolower(preg_replace('/\W+/','',pathinfo($script,PATHINFO_EXTENSION))); // Extension f�r Unix/Win32 unterscheidung
$cfg['php'] = array(phpversion(),php_uname(),php_sapi_name(),(float)phpversion(),(defined('PHP_INT_SIZE')) ? PHP_INT_SIZE * 8 : 32);
$cfg['ssl'] = (defined('OPENSSL_VERSION_TEXT')) ? OPENSSL_VERSION_TEXT : false;
$cfg['osn'] = ($var = ifset($cfg['ssl'],'/[\d.]+/')) ? (float)$var[0] : false;
$cfg['ptar'] = '/\.(?:(tar)|(t(?:ar\.)?gz)|(t(?:ar\.)?bz(?:ip)?2?)|(zip))($)/i'; // Tar-Ausdruck (1: .tar | 2: t?GZip | 3: tBZip2 | 4: ZIP)
$cfg['dbcd'] = realpath('.').'/'; // Current_Dir f�r Debug-Daten
$cfg['desc'] = '/['.preg_quote(preg_replace('!/.*$!','',$cfg['fesc']),'/').']+/';
$cfg['fesc'] = '/['.preg_quote($cfg['fesc'],'/').']+/';
$cfg['head'] = array('User-Agent' => "$Self $ver[2] {$cfg['php'][1]} PHP {$cfg['php'][0]}/{$cfg['php'][2]} ({$cfg['php'][4]} Bit) $cfg[ssl]"); // Fake UserAgent
$cfg['fail'] = array();
$cfg['uplink'] = array(
'host' => preg_replace('/^.*?(?=[\w.-]+$)/','',$ver[7]).":443,80",
'path' => "/Projekte/FritzBox-Tools;",
'fbts' => $ver[1],
'fbtp' => "fbt_plugins");
if(($cfg['os'] = strtolower(PHP_OS)) == 'winnt') // Sonderarten von Windows erkennen
$cfg['os'] .= (count(preg_array('/^(HOME|SYSTEM(DRIVE|ROOT)|APPDATA|WINDIR)$/',$_SERVER,3)) == 5) ? '-busybox'
: ((count(preg_array('/^(SystemDrive|SYSTEMROOT|APPDATA|windir|WINE(LOADER|SERVER)?)$/',$_SERVER,3)) == 7) ? '-wine' : '');
$cfg['cu'] = ($var = getenv('USER') or $var = getenv('USERNAME')) ? $var
: ((is_callable('posix_geteuid') and is_callable('posix_getpwuid') and $var = posix_getpwuid(posix_geteuid())) ? $var['name']
: (($var = getenv('windir') and file_exists("$var/system32/whoami.exe") or file_exists("/bin/whoami") or file_exists("/usr/bin/whoami"))
? basename(@exec('whoami')) : (($var = get_current_user()) ? $var : "UNKNOWN")));
$cfg['home'] = ($var = getenv('HOME') or $var = getenv('APPDATA') or $var = getenv('USERPROFILE')) ? $var : ".";
foreach(array('l' => $cfg['libs'], 'a' => $cfg['fbtp']) as $key => $var) // Verzeichnisliste f�r Libs/Plugins vorab berechnen in $cfg[fbtl/fbta]
$cfg["fbt$key"] = array(".","$cfg[dir]",$var,strtoupper($var),ucwords($var),"$cfg[dir]/$var","$cfg[dir]/".strtoupper($var),"$cfg[dir]/".ucwords($var));
if(ifset($_SERVER['argc']) and !preg_match('/cli/',$cfg['php'][2]) and function_exists('header_remove')) { // HTTP-Header l�schen wenn PHP-CGI eingesetzt wird
header('Content-type:');
header_remove('Content-type');
header_remove('X-Powered-By');
}
if(ifset($cfg['cron'])) // Verschiedene Funktionen einfach f�r Cron-Dienste abschalten
$cfg['wrap'] = $cfg['char'] = $cfg['uplink'] = 0;
if(function_exists('php_ini_loaded_file') and $var = php_ini_loaded_file()) // PHP.ini Location speichern
$cfg['php'][] = $var;
if(@ini_get('pcre.backtrack_limit') < $cfg['pcre']) // F�r Gro�e RegEx-Ergebnisse
@ini_set('pcre.backtrack_limit',$cfg['pcre']);
if(@ini_get('memory_limit') < $cfg['meli']) // Speicher-Buffer
@ini_set('memory_limit',$cfg['meli']);
if($cfg['time']) // Zeitzone festlegen
@ini_set('date.timezone',$cfg['time']);
if($cfg['slct']) // Zeitformat festlegen
@setlocale(LC_TIME,$cfg['slct']);
$gz = (function_exists("gzopen") or function_exists("gzopen64")) ? true : false; // ZLib Funktionen initialisieren
foreach(explode(',','open,close,eof,file,gets,puts,read,write,seek,tell,encode,decode,deflate,inflate') as $key)
$cfg['zlib'][$key] = $gz ? ((function_exists("gz$key")) ? "gz$key" : ((function_exists("gz{$key}64")) ? "gz{$key}64" : 'init'))
: ((function_exists($key)) ? $key : ((function_exists("f$key")) ? "f$key" : 'init'));
if(!file_exists($var = realpath($cfg['usrcfg']))) {
$file = basename($cfg['usrcfg']);
foreach(array(".",$cfg['home'],$cfg['dir']) as $dir) // Benutzerkonfig suchen
if(file_exists($var = realpath($dir)."/$file") or file_exists($var = realpath($dir)."/.$file")) // Benutzerkonfig gefunden
break;
}
if(file_exists($var)) {
dbug("Lade Benutzer-Konfig: $var"); // Debug-Meldung (dbug muss im Haupt-Quelltext aktiviert werden)
include_once $cfg['loadcfg'] = $var; // Benutzer-Konfig ausf�hren
}
foreach(array('preset','plugin') as $var)
if(!isset($cfg[$var]) or !is_array($cfg[$var])) // Sicherstellen dass preset/plugin ein Array ist
$cfg[$var] = array();
$cfg['a1st'] = (date('nj') == 41 and $x = $cfg['zlib']['inflate'](base64_decode( /* Test-Funktion */"
XZBBT8JAEIXv/IrxtpsICdFTNTRFIwejaZDogXBYu9N2adnW2SkiIf3ZnnpwC3LQ45s3+d68GczRIcfKuc+K9GF4eEHeM9iGQCsHkd1gqbFAa73PoJoU3pAK
h8Y6xrJsbIYW9g11SSHGcrAwSYE8Q4ukuCIPnCJhkltkyLqSTYZw2nGQdj7EIDwaq5GcSXIkzxNXl9eyPYgwvqV6Mhf9gTKMxe+NMpRHj7PJQhxJMpyJc6B3
22VKhvej92q3guWm0hj8LVlrP6+9Cu4xVU3JcLZW7Wn/fwvOepJKVPDQoy+m1Q6eorthpAmdw1X7Wjew7lRa+79R7gVtFSlY5+qD0E+/ezUewXOC2y+4Gcof"))) ? explode("~",$x) : false;
$cfg['time'] = (ifset($_SERVER['REQUEST_TIME_FLOAT'])) ? $_SERVER['REQUEST_TIME_FLOAT'] : array_sum(explode(' ',microtime())); // Startzeit sichern
foreach(explode(',','aes,arg,opt,argc,argk,args,opts,auth,mods') as $var) // Leeres Array setzen
$cfg[$var] = array();
if(!isset($cfg['bzip'])) { // BZip2 Funktionen initialisieren
$cfg['bzip'] = (function_exists("bzopen") or function_exists("bzopen64")) ? true : cfgdecrypt(0,'bzip2');
$cfg['bz'] = 0;
}
return true;
}
return false;
}
# Eigentlicher Programmstart
if(ifset($argc) and ifset($argv) and init($ver)) { ## CLI-Modus ##
$pmax = $argc; // Anzahl der Parameter
$pset = 1; // Argumentenz�hler
$opts = ""; // Kontext-Optionen
# Drag'n'Drop Modus
if(ifset($cfg['drag']) and $pset+1 == $pmax and file_exists($argv[$pset]) and is_file($argv[$pset])) {
if(is_array($cfg['drag'])) { // Ist es ein Array mit Dateitypen als Schl�ssel?
if(!preg_match('/\.([^.]+)(\.(gz|bz2?))?$/',$argv[$pset],$m) or !($drag = ifset($cfg['drag'][strtolower($m[1])],"")))
$drag = isset($cfg['drag']['*']) ? $cfg['drag']['*'] : 'info hash *';
}
else // Fallback zu String
$drag = $cfg['drag'];
dbug("Nutze Drag-Parameter: ".str_replace('*'," {$argv[$pset]} ",$drag)); // Debug-Meldung (Kann nicht mit -d angezeigt werden)
$drag = explode('*',$drag);
array_splice($argv,$pmax,0,explode(' ',trim($drag[1])));
array_splice($argv,$pset,0,explode(' ',trim($drag[0])));
$pmax = $argc = count($argv);
}
# Ersten Fritz!Box Parameter ermitteln und auswerten
if($pset < $pmax and @preg_match('/^(?!-) (?:(?Phttps?):\/\/)? (?:(["\']?)(?P.+)\2:)? (?:(["\']?)(?P.+)\4@)? (?P[\w.-]+\.[\w.-]+|(?<=@)[\w.-]+|\[[a-f\d:]+\]|'
.strtr(preg_quote(implode("\t",array_keys($cfg['preset'])),'/'),"\t",'|')
.'|[\w-]+::(["\']?)(?P.+)\7) (?::(?P\d{1,5}))? (?:\#(["\']?)(?P.+)\9)? ($)/ix',$argv[$pset],$m)) { // Fritz!Box Anmeldedaten holen
dbug("Presets: ".implode(', ',array_keys($cfg['preset'])),9);
if(ifset($m['cf']) and file_exists($m['cf'])) { // Kurzschreibweise: [name]::'[/path/fb_config.php]'
dbug("Lade Konfig-Datei: $m[cf]");
include_once $m['cf'];
$m['fb'] = preg_replace('/:.*$/','',$m['fb']);
}
$cfg['host'] = $m['fb']; // fb:Host
if(isset($cfg['preset'][$m['fb']])) { // Voreingestellte Fritz!Boxen Erkennen und Eintragen
dbug("�bernehme Preset: $m[fb]");
if(is_string($cfg['preset'][$m['fb']]) and $key = request($cfg['preset'][$m['fb']].'#'))
$cfg['preset'][$m['fb']] = $key;
if(is_array($cfg['preset'][$m['fb']]))
foreach($cfg['preset'][$m['fb']] as $key => $var)
$cfg[$key] = $var;
}
if($m['us']) { // us: Protokoll
$cfg['sock'] = $m['us'];
if($m['us'] == 'https')
$cfg['port'] = 443;
}
if($m['un']) // un:Username
$cfg['user'] = $m['un'];
if($m['pw']) // pw:Password
$cfg['pass'] = $m['pw'];
if($m['pt']) // pt:Port
$cfg['port'] = $m['pt'];
if($m['ui']) // ui:Password2
$cfg['uipw'] = $m['ui'];
$pset++;
}
unset($cfg['preset']); // Preset-Daten werden nicht mehr ben�tigt!
# Benannte / Nummerische Argumente und Optionen setzen
if($pset < $pmax) {
for($key=$pset; $key < $pmax; $key++)
if(preg_match("/^(?!$cfg[argn])(-?)(\w+)(?:(?:\[(.)\])?[:=]([\"']?)(.*?)\\4)?($)/i",$argv[$key],$var) and ($var[1] != "" or $var[5] != "")) { // Benanntes Argument
if($var[3] and preg_match_all('/(?:[^'.preg_quote($var[3],'/').'\\\\]+|\\\\'.preg_quote($var[3],'/').'?)+/',$var[5],$array)) // Ketten-Argumente (test[,]=foo,bar)
$var[5] = $array[0];
if($var[1]) { // Optionen
$val = 'opts';
if($var[5] == '')
$var[5] = true;
}
else // Argumente
$val = 'args';
if(isset($cfg[$val][$var[2]])) // Existiert schon?
if(is_array($cfg[$val][$var[2]])) // Ein Array?
if(is_array($var[5]))
$cfg[$val][$var[2]] = array_merge($cfg[$val][$var[2]],$var[5]);
else
$cfg[$val][$var[2]][] = $var[5]; // Array erweitern
else
$cfg[$val][$var[2]] = (is_array($var[5])) ? array_merge(array($cfg[$val][$var[2]]),$var[5]) : array($cfg[$val][$var[2]],$var[5]); // In Array umwandeln
else
$cfg[$val][$var[2]] = $var[5]; // Normal speichern
}
elseif(isset($argv[$key][0]) and $argv[$key][0] != '-')// Nummeriertes Argument
$cfg['arg'][$key] = $argv[$key];
$cfg['argc'] = array_keys($cfg['arg']);
if($cfg['args'])
$cfg['arg'] += $cfg['args']; // Alle Argumente zusammenf�hren
else
$cfg['argn'] = false; // Alten Parametermodus aktivieren
foreach($cfg['opts'] as $key => $var) {#=> // Optionen auswerten und setzen
$var = (is_array($var)) ? $var[0] : $var; // Bei mehreren Argumenten, nur das erste benutzen - entspreche getArg("-$key")
if($key == 'h') // help
$cfg['help'] = $var;
elseif($key == 'd') {// Debug
$cfg['dbug'] = ($val = ifset($var,'/^(\d+)(?:.(.+))?($)/')) ? intval($val[1]) : true;
if($val and $val[2] and (file_exists($val[2]) and is_dir($val[2]) or !file_exists($val[2]) and $val[2] = makedir($val[2],0)))
$cfg['dbcd'] = realpath($val[2]).'/'; // CD Setzen
}
elseif($key == 'w') // Wrap
$cfg['wrap'] = (ifset($var,'/^[1-9]\d+$/')) ? intval($var) : 80;
elseif($key == 'c') // Char
$cfg['char'] = strtolower($var);
elseif($key == 't') // Timeout
$cfg['tout'] = (ifset($var,'/^\d+$/')) ? intval($var) : 0;
elseif($key == 'b') // Buffer
$cfg['sbuf'] = (ifset($var,'/^[1-9]\d{2,}$/') ) ? intval($var) : 4096;
elseif($key == 'p') // Protokoll
$cfg['sock'] = ($v = ifset($var,'/^(auto|https?|ssl|tls)$/i') ) ? strtolower($v[0]) : 'auto';
elseif($key == 's') {// SID
if($val = ifset($var,'/^[\da-f]{16}$/i0')) // SID direkt �bernehmen
$cfg['sid'] = $val;
elseif(file_exists($var) and preg_match('/^\s*([\da-fA-F]{16}|(a:\d+:)?(\{.*\}))\s*($)/s',file_contents($var),$val)) {
if($val[3])
$cfg = array_replace($cfg,$val[2] ? unserialize($val[1]) : json2array($val[3])); // S�mtliche Variabeln aus der Datei in $cfg �bernehmen/�berschreiben
else
$cfg['sid'] = $val[1]; // NUR die SID �bernehmen
}
else
errmsg("2:Ung�ltige SID �bergeben");
if(ifset($cfg['sid']) and $sid = login(0,0,0,$cfg['sid'])) {// Sid best�tigen lassen
$cfg['bsid'] = $cfg['sid'] = $sid; // Festlegen, dass die Funktionen die Firmware-Abfragen und das Logout �berspringen sollen
dbug("Recycle Login-SID: $sid von $cfg[host]");
}
else
errmsg("20:SID ist ung�ltig");
}
elseif($key == 'gz') { // GZip Crunchlevel
$cfg['zlib']['mode'] = ($v = ifset($var,'/^-?(\d)[fhR]?$/')) ? $v[0] : -1;
$cfg['gz'] = $v ? $v[1] : 0;
}
elseif($key == 'zb') // ZIP-AES Bits
$cfg['zb'] = intval(ifset($var,'/^(128|192|256)$/0')) or $cfg['zb'] = 256;
elseif($key == 'zp') { // ZIP Kennwort
if(!is_array($var = $cfg['opts'][$key])) // Sicherstellen dass die ZIP-Kennw�rter ein Array sind
$var = array($var);
$cfg['zp'] = $var;
if(!ifset($cfg['zb'])) // Gleich noch die Bits pr�fen oder festlegen
$cfg['zb'] = 256;
}
elseif($key == 'bz') // BZip2 Crunchlevel
$cfg['bz'] = ifset($var,'/^\d$/0');
elseif($key == 'pe' and $var) // PHP-Extension nachladen
@dl($var);
elseif($key == 'fw' and $v = ifset($var,'/^(\d+\.0)?([1-9])\.?(\d{2})(-\d+)?$/')) // Fritz!Box Firmware-Version
$cfg['fiwa'] = (int)($v[2].$v[3]);
elseif($key == 'ua' and $v = ifset($var,'/^[[:print:]]+$/')) // UserAgent setzen
$cfg['head']['User-Agent'] = $v[0];
elseif($key == 'px' and ifset($var,'/^[\w.-]+:\d+$/')) // Proxy & Port
$cfg['proxy'] = $var;
elseif($key == 'pp' and is_dir($var)) // Plugin-Path setzen
$cfg['fbta'] = array(realpath($var));
elseif($key == 'nu') // Kein Update-Check
$cfg['upda'] = is_bool($var) ? -1 : intval($var);
elseif($key == 'cc' and file_exists($var)) { // Include BenutzerKonfig
$cfg['loadcfg'] = (ifset($cfg['loadcfg'])) ? "$cfg[loadcfg]|$var" : $var;
include_once $var;
}
elseif($key == 'cm') { // Cron-Modus: Einige Funktionen deaktivieren
$cfg['cron'] = true;
$cfg['wrap'] = $cfg['char'] = $cfg['upda'] = $cfg['uplink'] = 0;// Alles Ausschalten
}
elseif($key == 'ps' and isset($cfg['preset'][$var])) {
dbug("�bernehme Preset: $var");
if(is_string($cfg['preset'][$var]) and $key = request($cfg['preset'][$var].'#'))
$cfg['preset'][$var] = $key;
if(is_array($cfg['preset'][$var]))
foreach($cfg['preset'][$var] as $k => $v)
$cfg[$k] = $v;
}
else
foreach(array('o' => 'oput', 'un' => 'user', 'pw' => 'pass', 'ui' => 'uipw', 'fb' => 'host', 'pt' => 'port', 'tf' => 'totp') as $k => $v) // Optionen mit Zwangsparameter
if($key == $k and $var)
$cfg[$v] = $var;
}
}
if($cfg['dbug'] & 1<<8) // PHP-Fehler Protokollieren
set_error_handler('phperr');
else
error_reporting(0); // Fehler-Meldungen deaktivieren
# Consolen Breite automatisch ermitteln
if(ifset($cfg['wrap'],'auto')) {
if(ifset($cfg['os'],'/darwin|linux/')) // Linux/Mac
$cfg['wrap'] = (($var = (int)getenv('COLUMNS'))
or file_exists('/bin/stty') and $var = (int)preg_replace('/^\d+\D*/','',@exec('stty size'))
or file_exists('/bin/tput') and $var = (int)@exec('tput cols')
or file_exists('/bin/busybox') and @exec('busybox | grep ttysize') and $var = (int)preg_replace('/\D.*$/s','',@exec('busybox ttysize'))) ? $var : 0;
elseif((ifset($cfg['os'],'/^winnt(?!-wine)/') or file_exists(getenv('windir')."/system32/mode.com")) and (@exec('mode con',$var) or true) // Windows
and is_array($var) and preg_match_all('/(?:(zeilen|lines)|(spalten|columns)|(code\s?page)):\s*(\S+)/',strtolower(implode('',$var)),$val))
foreach($val[4] as $key => $var) {
if(ifset($val[2][$key])) // Breite sichern
$cfg['wrap'] = $var;
if(ifset($val[3][$key])) // Codepage merken
$char = "cp".(($var == 65001 and ifset(($cfg['php'][1]),'/Windows NT[\s\w_-]*(6\.[01])/i')) ? 850 : $var);
}
if($cfg['wrap'] == 'auto') // Auto fehlgeschlagen -> Wrap deaktiviert
$cfg['wrap'] = 0;
}
# Char ermitteln und festlegen
if(ifset($cfg['char'],'auto')) {
if(!ifset($cfg['cron']) and preg_match('/(13)[73]((\1)37)/',date('dnHi'),$var))
$cfg['char'] = $var[2];
elseif(ifset($char))
$cfg['char'] = $char;
elseif($var = ifset($_SERVER['LANG'],'/(UTF-?8)|((?:iso-)?8859-1)/i') and ($var[1] and !isset($cfg['utf8'])) or ifset($var[2])) // Linux/Ubuntu
$cfg['char'] = ($var[1]) ? 'utf-8' : 'iso-8859-1';
elseif(getenv('HOME') and getenv('USER') and getenv('TERM') and getenv('SHELL') // Unix/Linux/Mac
and file_exists('/usr/bin/locale') and preg_match('/(utf-?8)|(ansi|iso-?8859-?1|ascii)/i',@exec('locale charmap'),$var))
$cfg['char'] = (ifset($var[1]) and !isset($cfg['utf8'])) ? 'utf8' : ((ifset($var[2])) ? strtolower(str_replace('-','_',$var[2])) : 'utf7');
elseif(getenv('SystemDrive') and getenv('SystemRoot') and getenv('APPDATA')) // Windows
$cfg['char'] = 'oem';
else
$cfg['char'] = '7bit';
}
$cfg['char'] = ($var = '(?:c(?:odepage|p))?'
and $val = ifset($cfg['char'],"/^(?:(?P$var(437|85[08])|dos|oem)|(?P$var(1252|851|28591)|iso.?8859.?1|ansi)|(?P$var(?:1250|852|28952)|iso.?8859.?2)"
."|(?P{$var}65000|7bit|asc(ii)?|utf-?7)|(?P{$var}65001|utf-?8)|(?Px?html?)|(?P[1l][E3�]{2}[t\+7])|(?Prot13)|(?Pauto|none))$/i"))
? $val : array(0 => "char ($cfg[char])", 'c' => 1);
dbug(array('char' => $cfg['char']),4);
# Auto-Update (Check)
if(ifset($cfg['uplink']) and is_array($cfg['uplink']) and isset($cfg['uplink']['host'])) { // Links zum Updatecheck vorhanden?
if(!isset($cfg['uplink']['port']) and preg_match_all('/[:,](\d+)/',$cfg['uplink']['host'],$array)) { // Einen Speziellen Port benutzen?
$cfg['uplink']['port'] = $array[1];
$cfg['uplink']['host'] = preg_replace('/:.*$/','',$cfg['uplink']['host']);
}
else
$cfg['uplink']['port'] = array(80);
if($cfg['upda'] and ifset($cfg['uplink'],5)) {
$file = "$cfg[dir]/.touch-$cfg[cu]"; // Alternative Datei zum beschreiben
if($cfg['upda'] < 0) // Update-Pr�fung verhindern und Touch-Datei aktualisieren
mytouch(1);
elseif(mytouch()) // Pr�fung auf Touchdatei
if(mytouch(1)) { // Touch-Datei aktualisieren
dbug("Pr�fe auf Updates...");
foreach($cfg['uplink']['port'] as $var)
if($fbnet = request('GET-array',$cfg['uplink']['path'].$cfg['uplink']['fbts'].".md5",0,0,$cfg['uplink']['host'],$var)) {
if($var = ifset($fbnet['Location'],'/^(https?:)(\/\/.+)$/'))
$fbnet = request("$var[1][array]$var[2]");
break;
}
if($fbnet and ifset($fbnet['Content-MD5'],hash('md5',$fbnet[1])) and preg_match("/^#\s*(\w+)\s([\d\s.:]+)\((\w+)\s([\d.]+)\)/",$fbnet[1],$var)) {
if(floatval($var[4]) > $cfg['ver'][10]) {
out(errmsg("1:Ein Update ist verf�gbar ($var[3] $var[4]) - Bitte nutzen Sie die Update-Funktion!\n\nBeispiel:\n$self info update\n\n"));
if($var[1] == 'Emergency_Update' or $var[1] == 'Emergency_Exit' and errmsg("254:$var[1]"))
$cfg['args'] = array('mode' => 'info', 'func' => 'update');
}
if(ifset($fbnet['X-Cookie']))
dbug($fbnet['X-Cookie']);
}
else
dbug(errmsg("1:Fehlerhafte Update-Liste erhalten!")); // Eigentlich ein Fehler
}
else
errmsg("32:Keine Schreibberechtigung!\nBitte �ndern Sie das oder deaktivieren Sie die Auto-Update Funktion in der fb_config.php oder nutzen Sie die Option -nu!");
}
}
# Bei Fehlern jetzt abbrechen
if($var = errmsg())
out($var);
# Parameter auswerten
elseif($val = getArg('mode','/^
((?PBoxInfo|bi) |(?PPlugIns?|pi) |(?PG(et)?IP) |(?PLog(in(-?test)?|out)|l(o|it?))
|(?PReConnect|rc) |(?PSupportDaten|sd)|(?P(System)?S(tatu)?s) |(?PK(onfig)?) |(?PI(nfo)?|UpGrade|ug)
|(?PE(reignisse)?) |(?Pled) |(?PAnrufListe?|al) |(?PSmartHome?|sh) |(?PDial|d|WahlHilfe|wh)
|(?PKF|Komfort) |(?PT(raffic)?)'.($cfg['a1st'] ? $cfg['a1st'][1] : "").'|(?P[\w-]+))($)/ix')) {
dbug(array('mode' => $val, 'opts' => $cfg['opts'], 'argk' => $cfg['argk'], 'arg' => $cfg['arg'], 'argc' => $cfg['argc'], 'args' => $cfg['args']),3);
if(!$val['pi'] and !$val['pit']) // Plugin Voreinstellungen l�schen, wenn KEINE Plugins geladen werden
unset($cfg['plugin']);
if($val['i']) { // Info (Intern)
if($cfg['help']) {
$var = (ifset($cfg['uplink'])) ? array("\nUpDate |-|FB_Tools �ber das Internet aktualisieren","\n$self info update") : array ("","");
out("$self [mode:Info|i] \n
Funktionen (func):\n{{{tt}
AES|-|Verf�gbarkeit der AES-Entschl�sselung ausgeben
Arg |-|Geparste Argumente ausgeben
Cat [file]|-|Dateiinhalt mit Terminal-Charset ausgeben
CSV [file]|-|CSV-Datei als Tabelle ausgeben
Dir |-|Verzeichnis auflisten
Echo |-|Parameter ausgeben
ExTension|-|Verf�gbarkeit der PHP-Erweiterungen anzeigen
eXtrakt [file] |-|Dateien aus Archiv auflisten oder entpacken
Globals|-|Alle PHP-Variabeln ausgeben
Hash |-|Hashes von einer Datei oder einem String erstellen
JSON [file]|-|JSON-Datei geparst ausgeben
OpenSsl|-|Verf�gbarkeit der OpenSSL-Bibliotek ausgeben
OTPauth |-|TOTP Token-Generator (Google Authenticator)
PanGramm|-|Kodierungstest mit Umlauten und ASCII-Art
PHP|-|PHPInfo() ausgeben
PhpIni |-|Werte aus der PHP.ini ausgeben
StrfTime |-|Alle Zeit-Angaben von strftime ausgeben$var[0]
WebGet [url] |-|Datei herunterladen und HTTP-Header ausgeben}}".((ifset($cfg['help'],'/[ab]/i')) ? "\n
Beispiele:
$self info
$self info cat fb_config.php
$self info csv Anrufliste.csv -cs:';'
$self info dir
$self info echo \"Hello World!\"
$self info fb_config.php$var[1]
$self info hash file:'$script'
$self info json ./assets/meta.json
$self info otp secret:'ABCD EFGH IJKL MNOP QRST UVWX YZ23 4567'
$self info wg http://http.mengelke.de : -ua:Wget/1.10
$self info strftime '%d.%m.%y %H:%M:%S' @1234567890
$self i pg -c:ansi
$self i x -zp:password FRITZBox-assets.zip ./dir/" : ""));
if(!$cfg['help'] or $cfg['help'] === true)
$cfg['help'] = -1;
if(ifset($cfg['uplink']))
$opts .= "CSV:|-cs:|[Char]|CSV-Separator festlegen (;)
Extrakt:|-pa:|[TAR\|ZIP]|Archiv-Type festlegen
|-zp:|[Password]|ZIP-Kennwort festlegen
OTPauth:|-ft:|[strftime]|Eigenes Datumsformat
|-rp:|[count]|Anzahl der Token, die ausgegeben werden sollen
|-tf:|[Secret]|Secret f�r TOTP-Token
|-ts:|[time]|Zeit f�r die TOTP-Token
Update:|-f||Fehler Ignorieren
|-rd:|[dir]|RAW-Daten speichern
";
}
elseif($arg = getArg('func','/^(?: (?PPHP) |(?Ppi|phpini) |(?PG(?:LOBALS)?) |(?PP(?:anGramm|g))
|(?Pc|Cat) |(?Pe|Echo) |(?Pwg|W(eb)?Get) |(?Pst|StrfTime) |(?Ph(ash(er)?)?) |(?Pos|OpenSSL)
|(?Pd|Dir) |(?Pa|Arg) |(?Pt|Test) |(?Pet|ExTension) |(?PU(?:pdate|d)) |(?Potp(auth)?)
|(?Paes) |(?Pcsv) |(?Pjson) |(?Px|eXtra[ck]t) )($)/ix') or ifset($val['i'],'/upgrade|ug/'))
if($arg['pg'] and $var = "Welch fieser Katzentyp qu�lt da s��e V�gel blo� zum Jux?") // Pangramm mit Kitty
out(($vas = $cfg['zlib']['inflate'](base64_decode("VMqxCcQwEETR3OAefjYS7MjJZQJXIrxbiLnaD4X34sefd8GWEWE7Is/j23TDXZ3tihpWCcADpufci4sOjQXwxsfQ6Y4cYy4alKzzEA/AQ4FsSy0vW1DWys5v3pklJZUA")))
? wordwrap("$var\n",min((($cfg['wrap']) ? (int)$cfg['wrap'] : 80),42)).$vas : $var);
elseif($arg['c'] and $file = getArg('file','file_exists')) // Cat
out(preg_replace('/^\xef\xbb\xbf/','',file_contents($file)));
elseif($arg['js'] and $file = getArg('file','file_exists')) // JSON
out(json2array(file_contents($file)));
elseif($arg['os']) // OpenSSL
out(($var = cfgdecrypt(0,'openssl')) ? $var : errmsg("8:Nicht vorhanden - Kein SSL/HTTPS m�glich!"));
elseif($arg['aes']) // AES
out(($var = cfgdecrypt(0,'aes')) ? ($val = count($var))." Bibliothek".(($val > 1) ? "en" : "")." zur Entschl�sselung vorhanden" : errmsg("8:Nicht vorhanden - Keine Entschl�sselung m�glich!"));
elseif($arg['d']) // Dir
out(implode("\n",(array)listDir(getArg('dir'),false,(int)getArg('opt'))));
elseif($arg['t']) // Test{}
out(($str = getArg('str')) ? ifset($str,is_callable($var = getArg('test')) ? "" : $var) : ";-)");
elseif($arg['a']) { // Args
$array = array('system' => $argv, 'arguments' => $cfg['arg'], 'available keys' => $cfg['argc'], 'labeled' => $cfg['args'], 'options' => $cfg['opts']);
if($cfg['dbug'])
$array['consign'] = $cfg['argk'];
$var = getArg('arg','/^(?:(arg[cksv]?|'.implode('|',array_keys($array)).')|\w+)($)/i');
out(($var and isset($cfg['arg'][$var[0]])) ? getArg($var[0],is_callable($preg = getArg('preg')) ? "" : $preg) : (($var and isset($cfg[$var[1]])) ? $cfg[$var[1]] : (($var and isset($array[$var[1]])) ? $array[$var[1]] : $array)));
}
elseif($arg['php']) { // PHPInfo()
cfgdecrypt();
ob_start();
phpinfo();
$data = ob_get_contents();
ob_end_clean();
out(($cfg['php'][2] == 'cli') ? $data : preg_replace(array('/