From c464f9e3a36c05c7ad75d4b51dc922a99bf08fdd Mon Sep 17 00:00:00 2001 From: Gregor Schulte Date: Mon, 29 Nov 2021 15:23:19 +0100 Subject: [PATCH] Umbau der Statistik Ausgabe (each enfernt) Optimierungen --- .gitignore | 124 +++-- api/v1/statistic.php | 31 +- index.php | 8 +- .../templates/install_requirement.tpl.php | 6 +- .../resources/content/install_requirement.php | 10 +- install/resources/init.php | 2 +- public_html/templates/html_footer.tpl.php | 10 +- public_html/templates/statistic.tpl.php | 2 +- .../content/settings/troubleshooting.php | 4 +- resources/cron/5-coretemp.php | 3 +- resources/cron/init.php | 7 +- resources/init.php | 6 +- resources/library/api/api.class.php | 59 ++- resources/library/cache/cache.function.php | 7 +- resources/library/main/rpi.function.php | 142 +++--- resources/library/main/tpl.class.php | 434 +++++++++--------- .../library/statistic/statistic.class.php | 262 +++++------ resources/update/update_picontrol.php | 8 +- 18 files changed, 580 insertions(+), 545 deletions(-) diff --git a/.gitignore b/.gitignore index b24d71e..784e90c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,50 +1,100 @@ -# These are some examples of commonly ignored file patterns. -# You should customize this list as applicable to your project. -# Learn more about .gitignore: -# https://www.atlassian.com/git/tutorials/saving-changes/gitignore +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -# Node artifact files -node_modules/ -dist/ +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf +.idea -# Compiled Java class files -*.class +# Generated files +.idea/**/contentModel.xml -# Compiled Python bytecode -*.py[cod] +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml -# Log files -*.log +# Gradle +.idea/**/gradle.xml +.idea/**/libraries +Pi Control.iml +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr -# Package files -*.jar +# CMake +cmake-build-*/ -# Maven -target/ -dist/ +# Mongo Explorer plugin +.idea/**/mongoSettings.xml -# JetBrains IDE -.idea/ +# File-based project format +*.iws -# Unit test reports -TEST*.xml +# IntelliJ +out/ -# Generated by MacOS -.DS_Store +# mpeltonen/sbt-idea plugin +.idea_modules/ -# Generated by Windows -Thumbs.db +# JIRA plugin +atlassian-ide-plugin.xml -# Applications -*.app -*.exe -*.war +# Cursive Clojure plugin +.idea/replstate.xml -# Large media files -*.mp4 -*.tiff -*.avi -*.flv -*.mov -*.wmv +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### ZendFramework template +# Composer files +composer.phar +vendor/ + +# Local configs +config/autoload/*.local.php + +# Binary gettext files +*.mo + +# Data +data/logs/ +data/cache/ +data/sessions/ +data/tmp/ +temp/ + +#Doctrine 2 +data/DoctrineORMModule/Proxy/ +data/DoctrineORMModule/cache/ + +# Legacy ZF1 +demos/ +extras/documentation diff --git a/api/v1/statistic.php b/api/v1/statistic.php index 8de3923..23c17af 100644 --- a/api/v1/statistic.php +++ b/api/v1/statistic.php @@ -1,5 +1,5 @@ loadStatistics(); - + if (($name = $controller->getStatisticName($_POST['id'])) !== false) { if (isset($_POST['plugin']) && trim($_POST['plugin']) != '') pluginLanguage(trim($_POST['plugin'])); - + $builder = new StatisticBuilder(); $builder->loadFromFile($name, (isset($_POST['plugin']) && trim($_POST['plugin']) != '') ? $_POST['plugin'] : NULL); $statistic = $builder->getArray(); - + $log = new LogStatistic(); $log->setFile(LOG_PATH.$statistic['raw'].'.csv'); - + $arr = $info = array(); - + foreach ($statistic['columns'] as $column) $arr['cols'][] = array('id' => '', 'label' => _t($column['label']), 'type' => $column['type']); - + getRowsFromLog($arr, $info, $log->getAll(), $statistic['columns'], $statistic['cycle']); - + if (isset($arr['rows'])) { if (isset($_POST['type']) && $_POST['type'] == 'googleChart') $arr['rows'] = convertForGoogleChart($arr['rows']); - + $arr['rows'] = array_slice($arr['rows'], -2016); $arr['periods'] = $info['periods']; - + foreach (array('min', 'max') as $type) { if ($statistic['limits'][$type]['use'] == 'multiply') @@ -54,7 +54,7 @@ if (isset($_POST['id'])) $arr[$type] = round($info[$type]); } } - + $api->addData('statistic', $arr); } else @@ -67,23 +67,22 @@ else { $statistics = array(); $hiddenStatistics = unserialize(htmlspecialchars_decode(getConfig('main:statistic.hidden', 'a:0:{}'))); - + $controller = new StatisticController(); $controller->loadStatistics(); - + foreach ($controller->getStatistics() as $statistic) { $builder = new StatisticBuilder(); $builder->loadFromFile($statistic); - + $array = $builder->getArray(); if (!in_array($builder->getId(), $hiddenStatistics)) $statistics[] = array('array' => $array); } - + $api->addData('statistics', $statistics); $api->addData('hidden', $hiddenStatistics); } $api->display(); -?> \ No newline at end of file diff --git a/index.php b/index.php index a900e75..5c6d6eb 100644 --- a/index.php +++ b/index.php @@ -1,5 +1,5 @@ tplDraw === false) $tpl->draw(); } catch(Exception $e) { $errorHandler[] = 'Fehler [TPL]: '.$e->getFile().':'.$e->getLine().' => '.$e->getMessage(); - + echo ' @@ -91,4 +91,4 @@ catch(Exception $e) '; } -?> \ No newline at end of file +?> diff --git a/install/public_html/templates/install_requirement.tpl.php b/install/public_html/templates/install_requirement.tpl.php index e4f2699..5c8aeb3 100644 --- a/install/public_html/templates/install_requirement.tpl.php +++ b/install/public_html/templates/install_requirement.tpl.php @@ -41,12 +41,12 @@
- + - + @@ -58,7 +58,7 @@ - + diff --git a/install/resources/content/install_requirement.php b/install/resources/content/install_requirement.php index e64369a..99a87cf 100644 --- a/install/resources/content/install_requirement.php +++ b/install/resources/content/install_requirement.php @@ -19,7 +19,7 @@ $otherDistribution = array('version' => rpi_getDistribution(), 'status' => false $otherCookie = array('status' => false); $error = false; -if (version_compare(PHP_VERSION, '5.5.0') >= 0) +if (version_compare(PHP_VERSION, '7.0.0') >= 0) $phpVersion['status'] = true; if (extension_loaded('ssh2')) @@ -28,7 +28,7 @@ if (extension_loaded('ssh2')) //if (function_exists('mcrypt_encrypt') !== false) $phpMcrypt['status'] = true; -if (trim(exec('dpkg -s php5-cli | grep Status: ')) != '' || trim(exec('dpkg -s php7.0-cli | grep Status: ')) || trim(exec('dpkg -s php7.3-cli | grep Status: ')) != '') +if (trim(exec('dpkg -s php7.3-cli | grep Status: ')) != '' || trim(exec('dpkg -s php7.4-cli | grep Status: ')) != '') $phpCLI['status'] = true; if (function_exists('curl_init') !== false) @@ -52,7 +52,7 @@ foreach ($filesFolders as $file => $info) $filesFoldersExist['count'] += 1; $filesFoldersExist['status'] = false; } - + if ($info['permissionBool'] === false || $info['userGroupBool'] === false) { $filesFoldersPermission['count'] += 1; @@ -62,7 +62,7 @@ foreach ($filesFolders as $file => $info) } // Sonstiges -if ($otherDistribution['version'] == 'Raspbian GNU/Linux 7' || $otherDistribution['version'] == 'Raspbian GNU/Linux 8' || $otherDistribution['version'] == 'Raspbian GNU/Linux 9' || $otherDistribution['version'] == 'Raspbian GNU/Linux 10') +if ($otherDistribution['version'] == 'Raspbian GNU/Linux 10' || $otherDistribution['version'] == 'Raspbian GNU/Linux 11') $otherDistribution['status'] = true; if (isset($_COOKIE['_pi-control_install_language']) && $_COOKIE['_pi-control_install_language'] != '') @@ -90,4 +90,4 @@ $tpl->assign('langUrl', (isset($_GET['lang']) && $_GET['lang'] != '') ? '&la $tpl->assign('configHelp', $config['url']['help']); $tpl->draw('install_requirement'); -?> \ No newline at end of file +?> diff --git a/install/resources/init.php b/install/resources/init.php index e0ad5d7..827716c 100644 --- a/install/resources/init.php +++ b/install/resources/init.php @@ -16,7 +16,7 @@ if (!isset($config)) 'update' => 'https://pi-control.de/service/v1/update/', 'updateDownload' => 'https://pi-control.de/?service=update', 'updateNotification' => 'https://pi-control.de/?service=update_notification', - 'help' => 'https://pi-control.de/help/' + 'help' => 'https://www.die-schultes.eu/pi-control-hilfe/' ) ); } diff --git a/public_html/templates/html_footer.tpl.php b/public_html/templates/html_footer.tpl.php index 61b8762..bb1bab0 100644 --- a/public_html/templates/html_footer.tpl.php +++ b/public_html/templates/html_footer.tpl.php @@ -14,19 +14,17 @@


- - + +
= 5.5'); ?>= 7.0'); ?>
'._t('Anleitung zur Installation').''; ?>'._t('Anleitung zur Installation').''; ?>
'._t('Anleitung zur Installation').''; ?>'._t('Anleitung zur Installation').''; ?>

-
-

der %s.', 'Raspberry Pi Foundation'); ?>
- +
- \ No newline at end of file + diff --git a/public_html/templates/statistic.tpl.php b/public_html/templates/statistic.tpl.php index 10f7775..d53b5e0 100644 --- a/public_html/templates/statistic.tpl.php +++ b/public_html/templates/statistic.tpl.php @@ -74,4 +74,4 @@ statisticBuilder(, null); } - \ No newline at end of file + diff --git a/resources/content/settings/troubleshooting.php b/resources/content/settings/troubleshooting.php index 50b7143..07684e5 100644 --- a/resources/content/settings/troubleshooting.php +++ b/resources/content/settings/troubleshooting.php @@ -38,7 +38,7 @@ $tpl->assign('configHelpFilesFolders', $config['url']['help'].'?s=view&i=1'. $tpl->assign('configHelpCron', $config['url']['help'].'?s=view&i=10'.getURLLangParam()); $tpl->assign('cronEntry', $cronEntry); $tpl->assign('cronMatch', $cronMatch); -$tpl->assign('cronPHPCLI', ($cronPHPCLI = (trim(exec('dpkg -s php5-cli | grep Status: ')) != '' || trim(exec('dpkg -s php7.0-cli | grep Status: ')) != '') ? true : false)); +$tpl->assign('cronPHPCLI', ($cronPHPCLI = (trim(exec('dpkg -s php7.0-cli | grep Status: ')) != '' || trim(exec('dpkg -s php7.3-cli | grep Status: ')) != '') ? true : false)); $tpl->assign('cronLastExecution', formatTime(getConfig('cron:execution.cron', 0))); $tpl->assign('cronLastExecutionBool', ($cronLastExecutionBool = (getConfig('cron:execution.cron', 0) > time()-150) ? true : false)); $tpl->assign('cronLastExecutionLog', formatTime($lastExecutionLog[0])); @@ -52,4 +52,4 @@ $tpl->assign('cronCharacterEncodingBool', ($cronCharacterEncodingBool = trim(exe $tpl->assign('cronError', ($cronMatch !== 1) ? 1 : (($cronPHPCLI !== true || $cronLastExecutionBool !== true || $cronLastExecutionLogBool !== true || $cronPermissionBool !== true || $cronUserGroupBool !== true || $cronCharacterEncodingBool !== true ) ? 2 : 0)); $tpl->draw('settings/troubleshooting'); -?> \ No newline at end of file +?> diff --git a/resources/cron/5-coretemp.php b/resources/cron/5-coretemp.php index 736bfb8..61b85d5 100644 --- a/resources/cron/5-coretemp.php +++ b/resources/cron/5-coretemp.php @@ -1,6 +1,6 @@ setFile(LOG_PATH.'statistic/coretemp.csv'); $log->setLimit(2016); $log->add(array(time(), rpi_getCoreTemprature())); $log->close(); -?> \ No newline at end of file diff --git a/resources/cron/init.php b/resources/cron/init.php index fe48c24..2c3fdeb 100644 --- a/resources/cron/init.php +++ b/resources/cron/init.php @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/resources/init.php b/resources/init.php index 92d97da..48d8285 100644 --- a/resources/init.php +++ b/resources/init.php @@ -10,7 +10,7 @@ if (!isset($config)) 'ssh_ip' => '127.0.0.1' ), 'version' => array( - 'version' => '2.1.2', + 'version' => '2.2.0beta', 'versioncode' => 29, 'android_comp_level' => 25 ), @@ -63,7 +63,7 @@ function myErrorHandler($code, $msg, $file, $line) { global $errorHandler; $errorHandler[] = 'Fehler ['.$code.']: '.$msg.' in der Datei '.$file.', Zeile '.$line; - + if (isset($_COOKIE['debug']) && $_COOKIE['debug'] == 'debug_mode') return false; else @@ -81,4 +81,4 @@ if (isset($_COOKIE['debug'], $_GET['s']) && $_COOKIE['debug'] == 'debug_mode') if (!isset($doNotCheckForAuthentification)) (include LIBRARY_PATH.'main/authentification.php') or die('Nicht gefunden!'); -?> \ No newline at end of file +?> diff --git a/resources/library/api/api.class.php b/resources/library/api/api.class.php index e399348..62479f3 100644 --- a/resources/library/api/api.class.php +++ b/resources/library/api/api.class.php @@ -5,27 +5,27 @@ class API { // Startzeit private $startTime = 0; - + // Statuscode private $status = 200; - + // Daten private $dataArray = array(); - + // Fehler private $error = array(); - + /** * Konstrukter, welcher die Startzeit für die Lauftzeit festlegt. * * $api = new API; */ - + function __construct() { $this->startTime = microtime(true); } - + /** * Fügt ein Element hinzu. * @@ -35,20 +35,20 @@ class API * @param string|array|bool $value Wert * @return bool */ - + public function addData($key, $value) { if (!empty($this->error)) return false; - + $dummyStatus = $this->status; $this->status = 500; - + if (($key = trim($key)) == '') return false; - + $splits = explode('.', $key); - + switch (count($splits)) { case 1: @@ -69,12 +69,12 @@ class API default: return false; } - + $this->status = $dummyStatus; - + return true; } - + /** * Setzt den Statuscode. * @@ -83,17 +83,17 @@ class API * @param int $status Statuscode * @return bool */ - + public function setStatus($status) { if (!is_int($status)) return false; - + $this->status = $status; - + return true; } - + /** * Setzt eine Fehlermeldung. * @@ -104,26 +104,26 @@ class API * @param int $status Statuscode * @return bool */ - + public function setError($type, $message, $status = 500) { if (($type = trim($type)) == '') return false; - + if (($message = trim($message)) == '') return false; - + if (!is_int($status)) return false; - + header('HTTP/1.0 '.$status); - + $this->error = array('type' => $type, 'message' => $message); $this->status = $status; - + return true; } - + /** * Erzeugt das fertige JSON und gibt dieses anschließend aus. * @@ -132,19 +132,18 @@ class API * @param bool $prettyPrint Eingerückte Ausgabe des JSON * @return bool Ausgabe erfolgt mit "echo". */ - + public function display($prettyPrint = false) { header('Content-Type: application/json'); - + $executionTime = microtime(true) - $this->startTime; - + if (empty($this->error)) echo json_encode(array('data' => $this->dataArray, 'executionTime' => $executionTime, 'status' => $this->status), ($prettyPrint != false) ? JSON_PRETTY_PRINT : 0); else echo json_encode(array('error' => $this->error, 'executionTime' => $executionTime, 'status' => $this->status), ($prettyPrint != false) ? JSON_PRETTY_PRINT : 0); - + return true; } } -?> \ No newline at end of file diff --git a/resources/library/cache/cache.function.php b/resources/library/cache/cache.function.php index f1156a5..271e029 100644 --- a/resources/library/cache/cache.function.php +++ b/resources/library/cache/cache.function.php @@ -5,19 +5,19 @@ function getCacheList() { $fileSuffix = '.cache.php'; $cacheArray = array('usb_devices' => array(), 'users' => array(), 'weather' => array()); - + foreach ($cacheArray as $name => $info) { $cacheArray[$name]['active'] = (getConfig('cache:activation.'.$name, 'false') == 'true') ? true : false; $cacheArray[$name]['lifetime'] = getConfig('cache:lifetime.'.$name, 0); - + if (file_exists(CACHE_PATH.$name.$fileSuffix) && is_file(CACHE_PATH.$name.$fileSuffix)) { $cacheArray[$name]['filesize'] = filesize(CACHE_PATH.$name.$fileSuffix); $cacheArray[$name]['modification'] = filemtime(CACHE_PATH.$name.$fileSuffix); } } - + return $cacheArray; } @@ -35,4 +35,3 @@ function getCacheName($file) return $file; } } -?> \ No newline at end of file diff --git a/resources/library/main/rpi.function.php b/resources/library/main/rpi.function.php index 64e1d38..964da86 100644 --- a/resources/library/main/rpi.function.php +++ b/resources/library/main/rpi.function.php @@ -17,53 +17,53 @@ function rpi_getHostAddr() { if (!isset($_SERVER['SERVER_ADDR'])) return 'unknown'; - + if (!$ip = $_SERVER['SERVER_ADDR']) return gethostbyname($this->getHostname()); - + return $ip; } function rpi_getCoreTemprature() { $file = 85000; - + while ($file == 85000) $file = @shell_exec('cat /sys/class/thermal/thermal_zone0/temp'); - + if ($file != false) return round((trim($file)/1000), 2); - + return 0; } function rpi_getCpuClock() { $file = shell_exec('cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'); - + if ($file !== false) return (int) round(trim($file)/1000); - + return 0; } function rpi_getCpuMinClock() { $file = shell_exec('cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'); - + if ($file !== false) return (int) round(trim($file)/1000); - + return 0; } function rpi_getCpuMaxClock() { $file = shell_exec('cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq'); - + if ($file !== false) return (int) round(trim($file)/1000); - + return 0; } @@ -71,10 +71,10 @@ function rpi_getCPUType() { $file = shell_exec('cat /proc/cpuinfo'); preg_match('#Hardware\s*:\s*([^\s]+)#i', $file, $match); - + if (isset($match[1])) return $match[1]; - + return NULL; } @@ -87,69 +87,69 @@ function rpi_getCpuModel() function rpi_getCPULoad($accurate = false, $mulitcore = false) { $return = NULL; - + if ($accurate === true) $file = shell_exec('cat /proc/stat; sleep 2; echo "##--##"; cat /proc/stat'); else $file = shell_exec('cat /proc/stat; sleep 0.5; echo "##--##"; cat /proc/stat'); - + $file = explode('##--##', $file); - + if (!isset($file[0], $file[1])) return NULL; - + preg_match_all('/^cpu[0-9]?(.*)$/im', $file[0], $prevCPUStrings); preg_match_all('/^cpu[0-9]?(.*)$/im', $file[1], $curCPUStrings); - + for ($i = 0; $i < count($prevCPUStrings[0]); $i++) { $prevCPU = preg_split('/\s+/', $prevCPUStrings[0][$i]); $curCPU = preg_split('/\s+/', $curCPUStrings[0][$i]); - + if ($prevCPU[0] != 'cpu' && $mulitcore == false) break; - - + + if (!isset($prevCPU[0], $curCPU[1]) || count($prevCPU) != 11 || count($curCPU) != 11) return NULL; - + $prevIdle = $prevCPU[4] + $prevCPU[5]; $curIdle = $curCPU[4] + $curCPU[5]; - + $prevNonIdle = $prevCPU[1] + $prevCPU[2] + $prevCPU[3] + $prevCPU[6] + $prevCPU[7] + $prevCPU[8]; $curNonIdle = $curCPU[1] + $curCPU[2] + $curCPU[3] + $curCPU[6] + $curCPU[7] + $curCPU[8]; - + $prevTotal = $prevIdle + $prevNonIdle; $curTotal = $curIdle + $curNonIdle; - + $total = $curTotal - $prevTotal; $idle = $curIdle - $prevIdle; - + if ($mulitcore == true) $return[$prevCPU[0]] = (int) round(($total - $idle) / $total * 100); else $return = (int) round(($total - $idle) / $total * 100); } - + return $return; } function rpi_getDistribution() { $distribution = trim(@shell_exec('cat /etc/issue | cut -d " " -f 1-3')); - + if ($distribution == '') { $distributionString = @shell_exec('cat /etc/*-release | grep PRETTY_NAME'); - + preg_match('/.*="([\w\s\d\/]*).*"/i', $distributionString, $match); - + if (count($match) == 2) $distribution = trim($match[1]); else $distribution = _t('Unbekannt'); } - + return $distribution; } @@ -174,7 +174,7 @@ function rpi_getCountInstalledPackages() function rpi_getInstalledPackages() { @exec('dpkg -l | grep ^ii', $packages); - + $packages = array_map(function($package) { return preg_split('/[\s]+/', $package, 5); }, $packages); return $packages; } @@ -199,14 +199,14 @@ function rpi_getRpiRevision() $revision[19] = array('revision' => '0013', 'model' => 'B+', 'pcb' => '1.2', 'memory' => 512, 'manufacturer' => 'Embest'); $revision[20] = array('revision' => '0014', 'model' => 'Compute Module', 'pcb' => '1.0', 'memory' => 512, 'manufacturer' => 'Embest'); $revision[21] = array('revision' => '0015', 'model' => 'A+', 'pcb' => '1.1', 'memory' => 256, 'manufacturer' => 'Embest'); - + $revision_model = array(0 => 'A', 1 => 'B', 2 => 'A+', 3 => 'B+', 4 => 'Pi 2 B', 5 => 'Alpha', 6 => 'Compute Module', 7 => 'Zero', 8 => 'Pi 3 B', 9 => 'Zero', 10 => 'Compute Module 3', 12 => 'Zero W'); $revision_memory = array(0 => 256, 1 => 512, 2 => 1024); $revision_manufacturer = array(0 => 'Sony', 1 => 'Egoman', 2 => 'Embest', 3 => 'Sony Japan', 4 => 'Embest'); - + $file = shell_exec('cat /proc/cpuinfo'); preg_match('#\nRevision\s*:\s*([\da-f]+)#i', $file, $match); - + /* * ###### * |||||+- PCB @@ -216,12 +216,12 @@ function rpi_getRpiRevision() * |+- Manufacturer * +- Memory */ - + if (isset($match[1])) { if ($match[1][0] == '1' || $match[1][0] == '2') $match[1] = substr($match[1], 1); - + if (strlen($match[1]) == 4) return $revision[hexdec($match[1])]; elseif (strlen($match[1]) == 6 && $match[1][0] != 'a' && $match[1][0] != '9') @@ -235,7 +235,7 @@ function rpi_getRpiRevision() 'manufacturer' => $revision_manufacturer[hexdec(substr($match[1], 1, 1))]); } } - + return NULL; } @@ -243,7 +243,7 @@ function rpi_getRpiSerial() { $file = shell_exec('cat /proc/cpuinfo'); preg_match('#\nSerial\s*:\s*([\da-f]+)#i', $file, $match); - + return $match[1]; } @@ -256,7 +256,7 @@ function rpi_getMemorySplit() $config = @shell_exec('cat /boot/config.txt'); preg_match('#gpu_mem=([0-9]+)#i', $config, $match); $total = intval($match[1]); - + if ($total == 16) return array('system' => '496 MiB', 'video' => '16 MiB'); elseif ($total == 32) @@ -265,38 +265,38 @@ function rpi_getMemorySplit() return array('system' => '448 MiB', 'video' => '64 MiB'); elseif ($total == 128) return array('system' => '384 MiB', 'video' => '128 MiB'); - + return array('system' => '256 MiB', 'video' => '256 MiB'); } - + // 256 MB $mem = $this->getMemoryUsage(); $total = round($mem['total'] / 1024 / 1024, 0); - + if ($total <= 128) return array('system' => '128 MiB', 'video' => '128 MiB'); elseif ($total > 128 && $total <= 192) return array('system' => '192 MiB', 'video' => '64 MiB'); elseif ($total > 192 && $total <= 224) return array('system' => '224 MiB', 'video' => '32 MiB'); - + return array('system' => '240 MiB', 'video' => '16 MiB'); } function rpi_getMemoryUsage() { exec('free -bo 2>/dev/null || free -b', $data); - + if (strpos($data[0], 'available') !== false) { list($type, $total, $used, $free, $shared, $buffers, $available) = preg_split('#\s+#', $data[1]); $usage = (int) round(($total - $available) / $total * 100); - + return array('percent' => $usage, 'total' => $total, 'free' => $available, 'used' => ($total - $available)); } - + list($type, $total, $used, $free, $shared, $buffers, $cached) = preg_split('#\s+#', $data[1]); $usage = (int) round(($used - $buffers - $cached) / $total * 100); - + return array('percent' => $usage, 'total' => $total, 'free' => ($free + $buffers + $cached), 'used' => ($used - $buffers - $cached)); } @@ -305,7 +305,7 @@ function rpi_getSwapUsage() exec('free -bo 2>/dev/null || free -b', $data); list($type, $total, $used, $free) = preg_split('#\s+#', $data[2]); $usage = (int) round($used / $total * 100); - + return array('percent' => $usage, 'total' => $total, 'free' => $free, 'used' => $used); } @@ -314,28 +314,28 @@ function multiArraySearch($array, $key, $value) foreach ($array as $item) if (isset($item[$key]) && $item[$key] == $value) return true; - + return false; } function rpi_getMemoryInfo() { exec('df -lT | grep -vE "tmpfs|rootfs|Filesystem|Dateisystem"', $data); - + $devices = array(); $totalSize = 0; $usedSize = 0; - + foreach ($data as $row) { list($device, $type, $blocks, $use, $available, $used, $mountpoint) = preg_split('#[\s%]+#i', $row); - + if (multiArraySearch($devices, 'device', $device) === false) { $totalSize += $blocks * 1024; $usedSize += $use * 1024; } - + $devices[] = array( 'device' => $device, 'type' => $type, @@ -346,14 +346,14 @@ function rpi_getMemoryInfo() 'mountpoint' => $mountpoint ); } - + usort($devices, function($a, $b) { return strcasecmp($a['device'], $b['device']); }); - + $devices[] = array('total' => $totalSize, 'used' => $usedSize, 'free' => $totalSize - $usedSize, 'percent' => (int) round(($usedSize * 100 / $totalSize))); - + return $devices; } @@ -361,17 +361,17 @@ function rpi_getUsbDevices() { exec('lsusb', $data); $devices = array(); - + foreach ($data as $row) { preg_match('#[0-9a-f]{4}:[0-9a-f]{4}\s+(.+)#i', $row, $match); - + if (count($match) == 2) $devices[] = trim($match[1]); else $devices[] = '<'._t('Unbekannt').'>'; } - + return $devices; } @@ -393,33 +393,33 @@ function rpi_getAllUsers() call_user_func_array('array_multisort', $args); return array_pop($args); } - + exec('/usr/bin/who --ips', $dataLoggedIn); exec('/usr/bin/lastlog | grep -vE "Benutzername|Username" | cut -f 1 -d " "', $dataAllUsers); - + $usersLoggedIn = array(); $usersAll = array(); - + foreach ($dataLoggedIn as $row) { $split = preg_split('/\s+/i', $row); - + if (count($split) == 6) $usersLoggedIn[$split[0]][] = array('port' => $split[1], 'lastLogin' => strtotime($split[2].' '.$split[3].' '.$split[4]), 'lastLoginAddress' => $split[5]); } - + foreach ($dataAllUsers as $row) { $userLastLoginInformation = ''; $userLastLoginInformation = shell_exec('/usr/bin/last -i -f /var/log/wtmp | grep -m 1 "^'.$row.' "'); - + if ($userLastLoginInformation == '') $userLastLoginInformation = shell_exec('/usr/bin/last -i -f /var/log/wtmp.1 | grep -m 1 "^'.$row.' "'); - + if ($userLastLoginInformation != '') { $split = preg_split('/\s+/i', $userLastLoginInformation); - + $usersAll[] = array('username' => $row, 'userId' => exec('id -u '.escapeshellarg($row)), 'groupId' => exec('id -g '.escapeshellarg($row)), @@ -440,9 +440,9 @@ function rpi_getAllUsers() 'isLoggedIn' => isset($usersLoggedIn[$row]) ? true : false); } } - + $usersAll = array_orderby($usersAll, 'isLoggedIn', SORT_DESC, 'username', SORT_ASC); - + return $usersAll; } -?> \ No newline at end of file +?> diff --git a/resources/library/main/tpl.class.php b/resources/library/main/tpl.class.php index c861a27..4bf13f0 100644 --- a/resources/library/main/tpl.class.php +++ b/resources/library/main/tpl.class.php @@ -12,7 +12,7 @@ class PiTpl // Sprache private $tplLanguage = 'de'; private $tplLanguageFileArray = array(); - + // Pfade private $tplFolderPath = 'public_html/templates/'; private $tplFileSuffix = '.tpl.php'; @@ -20,62 +20,62 @@ class PiTpl private $tplConfigSuffix = '.config.ini.php'; private $tplLanguagePath = 'resources/languages/'; private $tplFolderPathPlugin = ''; - + // Laufzeit private $runtimeStart = 0; - + // Template Variablen private $tplVariables = array(); - + // Geladene Elemente private $tplLoaded = false; private $tplLoadedHeader = false; private $tplLoadedFooter = false; - + // Lade Elemente? private $tplLoadHeader = false; private $tplLoadFooter = false; - + // Fehler / Nachrichten private $ifError = false; private $tplMsg = array(); - + private $tpl = NULL; private $tplConfigArray = array(); public $tplDraw = false; - + // Headertitel private $tplHeaderTitle = ''; private $tplHeaderTitleFormat = '%s | Pi Control'; - + // Footer private $tplFooterConfig = array(); - + // SSH private $tplSSH = NULL; - + function __construct() { global $globalLanguage, $globalLanguageArray; - + $this->runtimeStart = microtime(true); - + $lang = $globalLanguage; $langFile = LANGUAGE_PATH.$lang.'.php'; - + if (empty($globalLanguageArray) && file_exists($langFile) === true && is_file($langFile) === true) { include $langFile; $globalLanguageArray = $langArray; } - + foreach ($this->tplConfigs as $configFile) { if (file_exists(CONFIG_PATH.$configFile.$this->tplConfigSuffix) === true && is_file(CONFIG_PATH.$configFile.$this->tplConfigSuffix) === true) $this->tplConfigArray[$configFile] = parse_ini_file(CONFIG_PATH.$configFile.$this->tplConfigSuffix, true); } } - + /** * Übergibt der Klasse die eigene Klassenvariable. * @@ -84,14 +84,14 @@ class PiTpl * @param class $tpl Klasse * @return bool */ - + public function setTpl($tpl) { $this->tpl = $tpl; - + return true; } - + /** * Setzt Sprache. * @@ -100,20 +100,20 @@ class PiTpl * @param string $lang Sprache * @return bool */ - + public function setLanguage($lang = 'de') { global $globalLanguage; - + if (strlen($lang) != 2 || !is_string($lang)) return false; - + $this->tplLanguage = $lang; $globalLanguage = $lang; - + return true; } - + /** * Übersetzt Text in andere Sprache. * @@ -123,18 +123,18 @@ class PiTpl * @param string|int|float $args[] Argumente * @return string */ - + public function _t() { $args = func_get_args(); - + $checksum = substr(md5($args[0]), 0, 8); if (isset($this->tplLanguageFileArray[$checksum]) && $this->tplLanguage != 'de') $args[0] = $this->tplLanguageFileArray[$checksum]; - + return call_user_func_array('sprintf', $args); } - + /** * Übersetzt Text in andere Sprache und gibt ihn anschließend aus. * @@ -144,20 +144,20 @@ class PiTpl * @param string|int|float $args[] Argumente * @return bool Ausgabe erfolgt mit "echo". */ - + public function _e() { $args = func_get_args(); - + $checksum = substr(md5($args[0]), 0, 8); if (isset($this->tplLanguageFileArray[$checksum]) && $this->tplLanguage != 'de') $args[0] = $this->tplLanguageFileArray[$checksum]; - + echo call_user_func_array('sprintf', $args); - + return true; } - + /** * Setzt Konfigurationswert für config.ini.php. * @@ -167,25 +167,25 @@ class PiTpl * @param string $value Konfigwert * @return bool */ - + public function setConfig($config, $value, $customFile = NULL) { $configPath = CONFIG_PATH; - + if ($this->tplFolderPathPlugin != '') $configPath = $this->tplFolderPathPlugin.'/resources/config/'; - + if ($customFile !== NULL) $configPath = $customFile; - + $file = explode(':', $config); - + if (count($file) != 2) return false; - + $configFile = $configPath.$file[0].$this->tplConfigSuffix; $md5 = substr(md5($configFile), 0, 6); - + if (!isset($this->tplConfigArray[$md5])) { if (file_exists($configFile) === true && is_file($configFile) === true) @@ -193,20 +193,20 @@ class PiTpl else return false; } - + if (!strlen($config) > 0 || !is_string($config)) return false; - + $var = explode('.', $file[1]); - + if (count($var) != 2) return false; - + $this->tplConfigArray[$md5][$var[0]][$var[1]] = $value; - + return writeConfig($this->tplConfigArray[$md5], $configFile); } - + /** * Ermittelt Konfigurationswert aus config.ini.php. * @@ -216,25 +216,25 @@ class PiTpl * @param string $default Standardwert * @return string|int Im Fehlerfall der Standardwert, ansonsten den Konfigwert. */ - + public function getConfig($config, $default = NULL, $customFile = NULL) { $configPath = CONFIG_PATH; - + if ($this->tplFolderPathPlugin != '') $configPath = $this->tplFolderPathPlugin.'/resources/config/'; - + if ($customFile !== NULL) $configPath = $customFile; - + $file = explode(':', $config); - + if (count($file) != 2) return $default; - + $configFile = $configPath.$file[0].$this->tplConfigSuffix; $md5 = substr(md5($configFile), 0, 6); - + if (!isset($this->tplConfigArray[$md5])) { if (file_exists($configFile) === true && is_file($configFile) === true) @@ -242,15 +242,15 @@ class PiTpl else return false; } - + if (!strlen($config) > 0 || !is_string($config)) return $default; - + if (!count($this->tplConfigArray) > 0) return $default; - + $var = explode('.', $file[1]); - + if (count($var) == 1 && isset($this->tplConfigArray[$md5][$var[0]])) return $this->tplConfigArray[$md5][$var[0]]; elseif (count($var) == 2 && isset($this->tplConfigArray[$md5][$var[0]][$var[1]])) @@ -258,29 +258,29 @@ class PiTpl else return $default; } - + public function removeConfig($config) { if (!strlen($config) > 0 || !is_string($config)) return false; - + $file = explode(':', $config); - + if (count($file) != 2) return false; - + $var = explode('.', $file[1]); - + if (count($var) == 1) unset($this->tplConfigArray[$file[0]][$var[0]]); elseif (count($var) == 2) unset($this->tplConfigArray[$file[0]][$var[0]][$var[1]]); else return false; - + return writeConfig($this->tplConfigArray[$file[0]], CONFIG_PATH.$file[0].$this->tplConfigSuffix); } - + /** * Übergibt dem TPL-System eine Variable * @@ -290,21 +290,21 @@ class PiTpl * @param string $value Wert der Variable. * @return bool */ - + public function assign($name, $value = NULL, $merge = false) { if (!strlen($name) > 0 || !is_string($name)) return false; - + if ($merge === true) $this->tplVariables[$name] = array_merge((isset($this->tplVariables[$name])) ? $this->tplVariables[$name] : array(), $value); else $this->tplVariables[$name] = $value; - - + + return true; } - + /** * Setzt den Ordner mit den Template-Dateien. * @@ -313,20 +313,20 @@ class PiTpl * @param string $path Pfad zum Ordner. * @return bool */ - + public function setTplFolder($path) { if (!strlen($path) > 0 || !is_string($path)) return false; - + if (file_exists($path) !== true || is_dir($path) !== true) return false; - + $this->tplFolderPath = $path; - + return true; } - + /** * Setzt den Ordner mit den Template-Dateien für Plugins. * @@ -335,20 +335,20 @@ class PiTpl * @param string $path Pfad zum Ordner. * @return bool */ - + public function setTplFolderPlugin($path) { if (!strlen($path) > 0 || !is_string($path)) return false; - + if (file_exists($path) !== true || is_dir($path) !== true) return false; - + $this->tplFolderPathPlugin = $path; - + return true; } - + /** * Setzt den title-Tag. * @@ -357,17 +357,17 @@ class PiTpl * @param string $title Titel * @return bool */ - + public function setHeaderTitle($title) { if (!strlen($title) > 0 || !is_string($title)) return false; - + $this->tplHeaderTitle = $title; - + return true; } - + /** * Setzt das Format für den title-Tag. * @@ -376,17 +376,17 @@ class PiTpl * @param string $format Format für den Titel. * @return bool */ - + public function setHeaderTitleFormat($format) { if (!strlen($format) > 0 || !is_string($format)) return false; - + $this->tplHeaderTitleFormat = $format; - + return true; } - + /** * Setzt den Wert, ob der Header angezeigt werden soll oder nicht. * @@ -395,14 +395,14 @@ class PiTpl * @param bool $draw * @return bool */ - + public function setDrawHeader($draw = true) { $this->tplLoadHeader = $draw; - + return true; } - + /** * Zeigt Header an. * @@ -410,32 +410,32 @@ class PiTpl * * @return bool */ - + private function drawHeader() { if ($this->tplLoadHeader !== true) return false; - + $fileName = CONTENT_PATH.'html_header.php'; - + $this->tplLoadedHeader = true; - + if (file_exists($fileName) !== true || is_file($fileName) !== true) throw new FileException(self::_t('Datei "%s" existiert nicht oder ist keine gültige Datei.', $fileName)); - + $tplMain = $this->tpl; - + // Übergebe Titel $data['title'] = sprintf($this->tplHeaderTitleFormat, $this->tplHeaderTitle); - + // Uebergebe Uebersetzung $data['jsTranslations'] = isset($this->tplVariables['jsTranslations']) ? $this->tplVariables['jsTranslations'] : array(); - + (include_once $fileName) or self::tplError(self::_t('Konnte Datei "%s" nicht öffnen und auslesen.', $fileName), __LINE__); - + return true; } - + /** * Setzt den Wert, ob der Footer angezeigt werden soll oder nicht. * @@ -446,15 +446,15 @@ class PiTpl * @param array $errorHandler * @return bool */ - + public function setDrawFooter($draw = true, $mainConfig = NULL) { $this->tplLoadFooter = $draw; $this->tplFooterConfig = $mainConfig; - + return true; } - + /** * Zeigt Footer an. * @@ -462,30 +462,30 @@ class PiTpl * * @return bool */ - + private function drawFooter() { global $errorHandler; - + if ($this->tplLoadFooter !== true) return false; - + $fileName = CONTENT_PATH.'html_footer.php'; - + $this->tplLoadedFooter = true; - + if (file_exists($fileName) !== true || is_file($fileName) !== true) throw new FileException(self::_t('Datei "%s" existiert nicht oder ist keine gültige Datei.', $fileName)); - + $tplMain = $this->tpl; $tplConfig = $this->tplFooterConfig; $tplErrorHandler = $errorHandler; - + (include_once $fileName) or self::tplError(self::_t('Konnte Datei "%s" nicht öffnen und auslesen.', $fileName), __LINE__); - + return true; } - + /** * Öffnet Template-Datei und zeigt Inhalt anschließend an. * @@ -494,41 +494,41 @@ class PiTpl * @param string $tplFileName Template-Datei * @return bool */ - + public function draw($tplFileName = '') { self::drawHeader(); - + if ($this->ifError === true) return false; - + $this->tplDraw = true; $folderPath = $this->tplFolderPath; - + if ($this->tplFolderPathPlugin != '') $folderPath = $this->tplFolderPathPlugin.'/public_html/templates/'; - + if (strlen($tplFileName) >= 1 && is_string($tplFileName)) { if (file_exists($folderPath.$tplFileName.$this->tplFileSuffix) !== true || is_file($folderPath.$tplFileName.$this->tplFileSuffix) !== true) return self::tplError(self::_t('Datei "%s" existiert nicht oder ist keine gültige Datei.', $tplFileName), __LINE__-1); } - + self::drawMsg(); - + $data = $this->tplVariables; - + if (strlen($tplFileName) >= 1 && is_string($tplFileName)) (include_once $folderPath.$tplFileName.$this->tplFileSuffix) or self::error(self::_t('Konnte Datei "%s" nicht öffnen und auslesen.', $tplFileName), __LINE__); - + // Optisch schöner echo PHP_EOL; - + self::drawFooter(); - + return true; } - + /** * Öffnet Error-Template-Datei und zeigt Inhalt + Fehler anschließend an * @@ -539,31 +539,31 @@ class PiTpl * @param bool $errorCancel Soll nur die Fehlermeldung angezeigt werden? * @return bool */ - + private function drawError($errorTitle, $errorMsg, $errorCancel) { if (!strlen($errorMsg) > 0 || !is_string($errorMsg)) return false; - + if (file_exists($this->tplFolderPath.'error'.$this->tplFileSuffix) !== true || is_file($this->tplFolderPath.'error'.$this->tplFileSuffix) !== true) return false; - + if ($errorCancel === true) if (self::drawHeader() === false) return false; - + $data['title'] = $errorTitle; $data['msg'] = $errorMsg; - + include $this->tplFolderPath.'error'.$this->tplFileSuffix; - + if ($errorCancel === true) if (self::drawFooter() === false) return false; - + return true; } - + /** * Fehler anzeigen. * @@ -576,20 +576,20 @@ class PiTpl * * @TODO Wenn $errorCancel auf false steht, wird der Fehler falsch angezeigt. */ - + public function error($errorTitle, $errorMsg, $errorCancel = true) { $this->ifError = $errorCancel; - + // Prüfe, ob Error-Template-Datei existiert if (self::drawError($errorTitle, $errorMsg, $errorCancel) === true) return false; - + printf('

%s

%s', $errorTitle, $errorMsg); - + return true; } - + /** * Fehler anzeigen. * @@ -599,15 +599,15 @@ class PiTpl * @param int $errorLine Zeilennummer des Fehlers. * @return bool */ - + private function tplError($errorMsg, $errorLine = 0) { self::error('Fehler im TPL-System', sprintf('%s Zeile: %s', $errorMsg, $errorLine), true); - + // Rückgabewert für andere Funktion return false; } - + /** * Leitet auf eine andere Seite weiter. * @@ -616,12 +616,12 @@ class PiTpl * @param string $url URL auf die weitergeleitet werden soll. * @return bool */ - + public function redirect($url) { if (!strlen($url) > 0 || !is_string($url)) return false; - + if (!headers_sent($filename, $linenum)) exit(header('Location: '.$url)); else @@ -630,10 +630,10 @@ class PiTpl ''.self::_t('Header bereits gesendet. Redirect nicht möglich, klicke daher stattdessen diesen Link an.', $url).'', true); } - + return true; } - + /** * Zeigt Debugmeldungen an. * @@ -641,14 +641,14 @@ class PiTpl * * @return bool */ - + public function showDebug() { printf(PHP_EOL.''.PHP_EOL.'

Ladezeit: %f
Fehler: %s

'.PHP_EOL.''.PHP_EOL, round(microtime(true)-$this->runtimeStart, 5), ($this->ifError) ? 'true' : 'false'); - + return true; } - + /** * Fügt Infomeldung hinzu. * @@ -660,32 +660,32 @@ class PiTpl * @param bool $cancelable Soll die Meldung geschlossen werden können? * @return bool */ - + public function msg($type, $title = NULL, $msg, $cancelable = true, $id = 0) { if (!strlen($type) > 0 || !is_string($type) || !strlen($msg) > 0 || !is_string($msg) ) return false; - + if ($id > 0) { $this->tplMsg[$id + 100] = array($type, $title, $msg, $cancelable); } else $this->tplMsg[] = array($type, $title, $msg, $cancelable); - + return true; } - + public function msgExists($id) { if (isset($this->tplMsg[$id + 100])) return true; - + return false; } - + /** * Zeigt Infomeldung(en) an. * @@ -693,15 +693,15 @@ class PiTpl * * @return bool */ - + private function drawMsg() { if (is_array($this->tplMsg) !== true || count($this->tplMsg) == 0) return false; - + if (file_exists($this->tplFolderPath.'msg'.$this->tplFileSuffix) !== true || is_file($this->tplFolderPath.'msg'.$this->tplFileSuffix) !== true) return false; - + foreach ($this->tplMsg as $key => $msg) { $data['id'] = $key; @@ -709,13 +709,13 @@ class PiTpl $data['title'] = $msg[1]; $data['msg'] = $msg[2]; $data['cancelable'] = $msg[3]; - + (include $this->tplFolderPath.'msg'.$this->tplFileSuffix) or self::tplError(self::_t('Konnte Datei "%s" nicht öffnen und auslesen.', $this->tplFolderPath.'msg'.$this->tplFileSuffix), __LINE__); } - + return false; } - + /** * Verbindet sich mit SSH. * @@ -723,65 +723,67 @@ class PiTpl * * @return bool */ - + private function loadSSH() { set_include_path(LIBRARY_PATH.'terminal'); - + if (!class_exists('Net_SSH2')) { include(LIBRARY_PATH.'terminal/Net/SSH2.php'); include(LIBRARY_PATH.'terminal/File/ANSI.php'); include(LIBRARY_PATH.'terminal/Crypt/RSA.php'); } - + $ssh = NULL; - + if (!(isset($_COOKIE['_pi-control_ssh']) && $_COOKIE['_pi-control_ssh'] != '')) return false; - + $token = $_COOKIE['_pi-control_ssh']; $token2 = $_COOKIE['_pi-control_ssh_'.$token]; - + $sshType = getConfig('ssh:token_'.$token.'.type', 'password'); $sshPort = getConfig('ssh:token_'.$token.'.port', 22); $sshUsername = getConfig('ssh:token_'.$token.'.username', 'root'); $sshPassword = getConfig('ssh:token_'.$token.'.password', ''); $sshPrivateKey = base64_decode(getConfig('ssh:token_'.$token.'.privateKey', '')); - - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - $sshPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $token2, base64_decode($sshPassword), MCRYPT_MODE_ECB, $iv); + + #$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); + #$sshPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $token2, base64_decode($sshPassword), MCRYPT_MODE_ECB, $iv); + $sshPassword = openssl_encrypt(base64_decode($sshPassword), 'aes-256-cbc', $token2, 0, $iv); $sshPassword = rtrim($sshPassword, "\0"); - + $ssh = new Net_SSH2('127.0.0.1', $sshPort); - + if ($sshType == 'password') { if (!$ssh->login($sshUsername, $sshPassword)) return false; } - + if ($sshType == 'publickey') { $sshKey = new Crypt_RSA(); - + if ($sshPassword != '') $sshKey->setPassword($sshPassword); - + $sshKey->loadKey($sshPrivateKey); - + if (!$ssh->login($sshUsername, $sshKey)) return false; } - + if ($ssh === NULL) return false; - + $this->tplSSH = $ssh; - + return true; } - + /** * Führt einen SSH-Befehl aus. * $canelIfError: 0 = Keine Auswirkung @@ -795,30 +797,30 @@ class PiTpl * @param int $cancelIfError Verhalten im Fehlerfall. * @return bool|array */ - + public function executeSSH($command, $timeout = NULL, $cancelIfError = 1) { if ($this->tplSSH === NULL) if (self::loadSSH() !== true) if ($cancelIfError !== 0) return self::error(_t('SSH-Zugriffsfehler'), _t('Kein SSH-Zugriff, bitte anmelden! Jetzt anmelden.', '?s=ssh_login'), ($cancelIfError === 1) ? true : false); - + if ($timeout != NULL) $this->tplSSH->setTimeout($timeout); else $this->tplSSH->setTimeout(10); - + $this->tplSSH->enableQuietMode(); - + if ($this->tplSSH === NULL || ($output = $this->tplSSH->exec($command)) === false) return false; - + $error = $this->tplSSH->getStdError(); $exitStatus = $this->tplSSH->getExitStatus(); - + return array($output, $error, $exitStatus); } - + /** * Rückgabe der SSH-Ressource. * @@ -826,7 +828,7 @@ class PiTpl * * @return bool|resource */ - + public function getSSHResource($cancelIfError = 0) { if ($this->tplSSH === NULL) @@ -834,13 +836,13 @@ class PiTpl { if ($cancelIfError !== 0) self::error(_t('SSH-Zugriffsfehler'), _t('Kein SSH-Zugriff, bitte anmelden! Jetzt anmelden.', '?s=ssh_login'), ($cancelIfError === 1) ? true : false); - + return false; } - + return $this->tplSSH; } - + /** * Ermittelt Informationen der gespeicherten SSH-Informationen. * @@ -848,25 +850,25 @@ class PiTpl * * @return bool|array */ - + public function getSSHInfo() { $sshType = getConfig('ssh:latest.type', 'password'); $sshPort = getConfig('ssh:latest.port', 22); $sshUsername = getConfig('ssh:latest.username', ''); - + if (isset($_COOKIE['_pi-control_ssh']) && $_COOKIE['_pi-control_ssh'] != '') { $token = $_COOKIE['_pi-control_ssh']; - + $sshType = getConfig('ssh:token_'.$token.'.type', $sshType); $sshPort = getConfig('ssh:token_'.$token.'.port', $sshPort); $sshUsername = getConfig('ssh:token_'.$token.'.username', $sshUsername); } - + return array('type' => $sshType, 'port' => $sshPort, 'username' => $sshUsername); } - + /** * Setzt SSH-Informationen. * @@ -878,48 +880,50 @@ class PiTpl * @param bool $saveInFile Langer Login (true) oder nur aktuelle Sitzung (false)? * @return bool */ - + public function setSSHInfo($type, $port, $username, $password, $privateKey, $rememberMe = false) { if (!is_array($SSHInfo = self::getSSHInfo())) return false; - + if ($type != '' && is_string($type)) $SSHInfo['type'] = $type; - + if ($port != '' && is_numeric($port)) $SSHInfo['port'] = $port; - + if ($username != '' && is_string($username)) $SSHInfo['username'] = $username; - + if ($privateKey != '' && is_string($privateKey)) $SSHInfo['privateKey'] = $privateKey; - + if ($password != '') { if (isset($_COOKIE['_pi-control_ssh']) && $_COOKIE['_pi-control_ssh'] != '') $this->logoutSSH(); - + $uniqid = generateUniqId(16, false); $uniqid2 = generateUniqId(32, false); - - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - $SSHInfo['password'] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $uniqid2, $password, MCRYPT_MODE_ECB, $iv)); - + + #$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); + #$SSHInfo['password'] = base64_encode(openssl_encrypt(MCRYPT_RIJNDAEL_256, $uniqid2, $password, MCRYPT_MODE_ECB, $iv)); + $SSHInfo['password'] = openssl_encrypt($password, 'aes-256-cbc', $uniqid, 0, $iv); + $SSHInfo['privateKey'] = $privateKey; - + if (setConfig('ssh:token_'.$uniqid.'.created', time()) !== true) return false; if (setConfig('ssh:token_'.$uniqid.'.type', $SSHInfo['type']) !== true) return false; if (setConfig('ssh:token_'.$uniqid.'.port', $SSHInfo['port']) !== true) return false; if (setConfig('ssh:token_'.$uniqid.'.username', $SSHInfo['username']) !== true) return false; if (setConfig('ssh:token_'.$uniqid.'.password', $SSHInfo['password']) !== true) return false; if (setConfig('ssh:token_'.$uniqid.'.privateKey', base64_encode($SSHInfo['privateKey'])) !== true) return false; - + setConfig('ssh:latest.type', $SSHInfo['type']); setConfig('ssh:latest.port', $SSHInfo['port']); setConfig('ssh:latest.username', $SSHInfo['username']); - + if ($rememberMe == false) { setcookie('_pi-control_ssh', $uniqid, time()+60*60*12); @@ -930,14 +934,14 @@ class PiTpl setcookie('_pi-control_ssh', $uniqid, time()+60*60*24*30); setcookie('_pi-control_ssh_'.$uniqid, $uniqid2, time()+60*60*24*30); } - + $_COOKIE['_pi-control_ssh'] = $uniqid; $_COOKIE['_pi-control_ssh_'.$uniqid] = $uniqid2; } - + return true; } - + /** * Löscht SSH-Login. * @@ -945,21 +949,21 @@ class PiTpl * * @return bool */ - + public function logoutSSH() { if (isset($_COOKIE['_pi-control_ssh']) && $_COOKIE['_pi-control_ssh'] != '') { $token = $_COOKIE['_pi-control_ssh']; - + removeConfig('ssh:token_'.$token); setcookie('_pi-control_ssh', '', time()-60); setcookie('_pi-control_ssh_'.$token, '', time()-60); $_COOKIE['_pi-control_ssh'] = ''; $_COOKIE['_pi-control_ssh_'.$token] = ''; } - + return true; } } -?> \ No newline at end of file +?> diff --git a/resources/library/statistic/statistic.class.php b/resources/library/statistic/statistic.class.php index 69d7eff..bcd9e29 100644 --- a/resources/library/statistic/statistic.class.php +++ b/resources/library/statistic/statistic.class.php @@ -4,133 +4,129 @@ if (!defined('PICONTROL')) exit(); class LogStatistic { private $file, $stream, $limit = -1, $length = 100; - + function __destruct() { if (is_resource($this->stream)) fclose($this->stream); } - + public function setFile($pFile = '') { $this->file = $pFile; } - + public function setLimit($pLimit = -1) { $this->limit = $pLimit; } - + public function setLength($pLength = 100) { $this->length = $pLength; } - + public function add($entry, $moreThanOne = false) { if (!is_array($entry) || empty($entry)) return false; - + if (!is_resource($this->stream)) $this->open(); - + if ($this->limit > -1) $this->shortLog(); - + fseek($this->stream, 0, SEEK_END); - + if ($moreThanOne === false) fputcsv($this->stream, $entry); - else - { + else { foreach ($entry as $item) fputcsv($this->stream, $item); } - + return true; } - + public function getAll() { if (!is_resource($this->stream)) $this->open(); - + $entries = array(); - + fseek($this->stream, 0); - + while (($entry = fgetcsv($this->stream, $this->length)) !== false) $entries[] = $entry; - + return $entries; } - + public function getLast() { if (!is_resource($this->stream)) $this->open(); - + $entries = $this->getAll(); - + if (is_array($entries)) return end($entries); } - + private function shortLog() { if ($this->limit == -1) return false; - + if (!is_array(($entries = $this->getAll()))) return false; - - if (count($entries) >= $this->limit) - { + + if (count($entries) >= $this->limit) { $unsetLineCount = count($entries) - $this->limit; - + for ($i = 0; $i <= $unsetLineCount; $i++) unset($entries[$i]); - + fseek($this->stream, 0); ftruncate($this->stream, 0); - + foreach ($entries as $entry) fputcsv($this->stream, $entry); } - + return true; } - + public function deleteLog() { - if (is_file($this->file)) - { + if (is_file($this->file)) { if (unlink($this->file) or exit(_t('Konnte Log-Datei nicht löschen: %s', $this->file))) return true; - } - else + } else return false; } - + public function clearLog() { if (!is_resource($this->stream)) $this->open(); - + fseek($this->stream, 0); ftruncate($this->stream, 0); } - + public function close() { fclose($this->stream); } - + private function open() { if (!file_exists($this->file) || !is_file($this->file)) touch($this->file); - + $this->stream = fopen($this->file, 'r+') or exit(_t('Konnte Log-Datei nicht öffnen: %s', $this->file)); } } @@ -138,107 +134,104 @@ class LogStatistic class StatisticController { private $statistics = array(); - + public function __construct($tpl = NULL) { if (!isset($tpl)) return; - + $jsTranslations = array(); $jsTranslations[] = 'Es sind noch keine Werte verfügbar. Werte werden alle %%s Minuten eingetragen.'; $jsTranslations[] = 'Es ist ein Fehler aufgetreten! Fehler: %%s'; $jsTranslations[] = 'Zeit'; $jsTranslations[] = 'Es ist ein Fehler aufgetreten! Fehlercode: %%s'; - + $tpl->assign('jsTranslations', $jsTranslations, true); } - + public function loadStatistics($folder = NULL) { - $files = array(); - if ($folder == NULL) $possibleFolders = array(LOG_PATH); else - $possibleFolders = array(LOG_PATH.$folder); - - while (list($key, $folder) = each($possibleFolders)) - { - foreach (@scandir($folder) as $file) - { - if ($file[0] != '.') - { - if (is_file($folder.'/'.$file) && substr($file, -4) == '.csv') - { - $fileName = str_replace(LOG_PATH, '', $folder).substr($file, 0, -4); - $this->statistics[substr(md5($fileName), 0, 8)] = $fileName; - } - elseif (is_dir($folder.$file)) - $possibleFolders[] = $folder.$file.'/'; - } - } + $possibleFolders = array(LOG_PATH . $folder); + + foreach ($possibleFolders as $folder) { + $this->statistics = array_merge($this->statistics, $this->loadStatisticsIterator($folder)); } } - + + private function loadStatisticsIterator($folder) + { + $fileNames = array(); + $files = array_diff(@scandir($folder), array('..', '.')); + foreach ($files as $file) { + $absolutePath = $folder . '/' . $file; + if (is_file($absolutePath) && substr($file, -4) == '.csv') { + $fileName = str_replace(LOG_PATH, '', $folder) . substr($file, 0, -4); + $fileNames[substr(md5($fileName), 0, 8)] = $fileName; + } elseif (is_dir($absolutePath)) + $fileNames = array_merge($fileNames, $this->loadStatisticsIterator($folder . $file . '/')); + } + return $fileNames; + } + public function getStatisticID($name) { if (empty($this->statistics)) $this->loadStatistics(); - + if (!is_string($name)) return false; - + if (($id = array_search($name, $this->statistics)) !== false) return $id; - + return false; } - + public function getStatisticName($id) { if (empty($this->statistics)) $this->loadStatistics(); - + if (!is_string($id)) return false; - + if (isset($this->statistics[$id])) return $this->statistics[$id]; - + return false; } - + public function checkStatistic($value, $isID = false) { if (!is_string($value)) return false; - + if (!is_bool($isID)) return false; - - if ($isID === true) - { + + if ($isID === true) { if ($this->getStatisticName($value) !== false) return true; else return false; - } - elseif ($isID === false) - { + } elseif ($isID === false) { if ($this->getStatisticID($value) !== false) return true; else return false; } - + return false; } - + public function getStatistics() { if (empty($this->statistics)) $this->loadStatistics(); - + return $this->statistics; } } @@ -246,46 +239,43 @@ class StatisticController class StatisticBuilder { private $name, $columns, $title, $prefix, $suffix, $raw, $label, $unit, $cycle, $limits; - + public function loadFromFile($name, $plugin = NULL) { - $source = LIBRARY_PATH.'statistic/statistic.config.php'; - + $source = LIBRARY_PATH . 'statistic/statistic.config.php'; + if ($plugin != NULL && is_string($plugin)) - $source = PLUGINS_PATH.$plugin.'/plugin.statistic.config.php'; - + $source = PLUGINS_PATH . $plugin . '/plugin.statistic.config.php'; + if (!file_exists($source) || !is_file($source)) return false; - + include $source; - + if (!isset($statisticConfig) || !is_array($statisticConfig)) return false; - + $this->raw = $name; - - if (strpos($name, '/') !== false) - { + + if (strpos($name, '/') !== false) { $explodes = explode('/', strrev($name), 2); $name = strrev($explodes[0]); - $prefix = strrev($explodes[1]).'/'; + $prefix = strrev($explodes[1]) . '/'; } - - if (!isset($statisticConfig[$name]) && isset($statisticConfig[substr($name, 0, strpos($name, '_'))])) - { - if (strpos($name, '_') !== false) - { + + if (!isset($statisticConfig[$name]) && isset($statisticConfig[substr($name, 0, strpos($name, '_'))])) { + if (strpos($name, '_') !== false) { $explodes = explode('_', strrev($name), 2); $suffix = strrev($explodes[0]); $name = strrev($explodes[1]); } } - + if (!isset($statisticConfig[$name])) return false; - + $statistic = $statisticConfig[$name]; - + $this->name = $name; $this->title = _t($statistic['title']); $this->prefix = isset($prefix) ? $prefix : ''; @@ -294,70 +284,68 @@ class StatisticBuilder $this->unit = $statistic['unit']; $this->cycle = $statistic['cycle']; $this->limits = $statistic['limits']; - - foreach ($statistic['columns'] as $column) - { - foreach ($column as &$values) - { + + foreach ($statistic['columns'] as $column) { + foreach ($column as &$values) { if (is_string($values)) $values = _t($values); } - + $this->columns[] = $column; } - + if (substr_count($this->title, '%s') == 1) { $this->title = sprintf($this->title, $this->suffix); } - + if ($this->title == '') $this->title = $this->suffix; - + return true; } - + public function setTitle($title) { if (!is_string($title)) return false; - + $this->title = $title; } - + public function getId() { return substr(md5($this->raw), 0, 8); } - + public function getArray() { return array( - 'id' => $this->getId(), - 'name' => $this->name, - 'title' => $this->title, - 'prefix' => $this->prefix, - 'suffix' => $this->suffix, - 'raw' => $this->raw, - 'label' => $this->label, - 'unit' => $this->unit, - 'cycle' => $this->cycle, - 'columns' => $this->columns, - 'limits' => $this->limits - ); + 'id' => $this->getId(), + 'name' => $this->name, + 'title' => $this->title, + 'prefix' => $this->prefix, + 'suffix' => $this->suffix, + 'raw' => $this->raw, + 'label' => $this->label, + 'unit' => $this->unit, + 'cycle' => $this->cycle, + 'columns' => $this->columns, + 'limits' => $this->limits + ); } - + public function getJSON() { - $json = json_encode(array( - 'id' => $this->getId(), - 'label' => $this->label, - 'unit' => $this->unit, - 'cycle' => $this->cycle, - 'columns' => $this->columns - ) - ); - + $json = json_encode( + array( + 'id' => $this->getId(), + 'label' => $this->label, + 'unit' => $this->unit, + 'cycle' => $this->cycle, + 'columns' => $this->columns + ) + ); + return $json; } } -?> \ No newline at end of file diff --git a/resources/update/update_picontrol.php b/resources/update/update_picontrol.php index c2dbe39..341b736 100644 --- a/resources/update/update_picontrol.php +++ b/resources/update/update_picontrol.php @@ -1,5 +1,5 @@ fetchData(); if ($updateStatus === true) { $nextUpdate = $updateController->getNextUpdate(); - + if ($nextUpdate instanceof Update) { $downloadStatus = $updateController->download($nextUpdate); - + if ($downloadStatus === true) { $tpl->redirect('?s=settings&do=update&complete'); } elseif ($downloadStatus === 10) { @@ -41,4 +41,4 @@ if ($updateStatus === true) { if (isset($errorMsg)) { $tpl->assign('content', '
'._t('Aktualisierung').'
'.$errorMsg.'
'._t('Zurück zur Aktualisierung').'
'); $tpl->draw('single_box'); -} \ No newline at end of file +}