From c8ce77259db36cdac463e5e1e9511926d1a25722 Mon Sep 17 00:00:00 2001 From: Brian Read Date: Wed, 14 May 2025 16:14:01 +0100 Subject: [PATCH] * Mon May 12 2025 Brian Read 11.0.0-1.sme - Adding SM2 panel [SME: 13004] - Upgrade to phpsysinfo 3.4.4 - Add code to delete inline styles and add css to make it look better. - version saved / built uses the static version, which means no drops downs and choices. --- .gitignore | 1 + .../httpd/conf/httpd.conf/86PhpsysinfoAlias | 12 +- root/opt/phpsysinfo/.browserslistrc-bootstrap | 6 + root/opt/phpsysinfo/.browserslistrc-dynamic | 6 + root/opt/phpsysinfo/.browserslistrc-static | 1 + .../opt/phpsysinfo/.github/CODE_OF_CONDUCT.md | 46 + root/opt/phpsysinfo/.github/CONTRIBUTING.md | 7 + root/opt/phpsysinfo/.github/FUNDING.yml | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 41 + .../.github/ISSUE_TEMPLATE/custom.md | 10 + .../.github/ISSUE_TEMPLATE/feature_request.md | 20 + .../.github/PULL_REQUEST_TEMPLATE.md | 25 + .../phpsysinfo/.github/workflows/phplint.yml | 38 + root/opt/phpsysinfo/.gitignore | 1 + root/opt/phpsysinfo/.htaccess | 26 +- root/opt/phpsysinfo/.travis.yml | 18 - root/opt/phpsysinfo/CHANGELOG.md | 242 +- root/opt/phpsysinfo/COPYING | 25 +- root/opt/phpsysinfo/Dockerfile | 22 +- root/opt/phpsysinfo/README.md | 67 +- root/opt/phpsysinfo/README_PLUGIN.md | 28 +- root/opt/phpsysinfo/SECURITY.md | 12 + root/opt/phpsysinfo/composer.json | 9 +- root/opt/phpsysinfo/data/.htaccess | 9 + root/opt/phpsysinfo/data/ModelTranslation.txt | 81 +- root/opt/phpsysinfo/data/cpus.ini | 229 + root/opt/phpsysinfo/data/distros.ini | 1272 +- root/opt/phpsysinfo/data/languages.ini | 2 +- root/opt/phpsysinfo/data/osnames.ini | 35 +- root/opt/phpsysinfo/data/raspberry.ini | 46 + root/opt/phpsysinfo/gfx/attention.gif | Bin 0 -> 1044 bytes root/opt/phpsysinfo/gfx/attention.png | Bin 1500 -> 0 bytes root/opt/phpsysinfo/gfx/blank.gif | Bin 0 -> 49 bytes root/opt/phpsysinfo/gfx/body.gif | Bin 0 -> 551 bytes root/opt/phpsysinfo/gfx/body.png | Bin 443 -> 0 bytes .../phpsysinfo/gfx/bullet_toggle_minus.gif | Bin 0 -> 877 bytes .../phpsysinfo/gfx/bullet_toggle_minus.png | Bin 207 -> 0 bytes .../opt/phpsysinfo/gfx/bullet_toggle_plus.gif | Bin 0 -> 879 bytes .../opt/phpsysinfo/gfx/bullet_toggle_plus.png | Bin 209 -> 0 bytes root/opt/phpsysinfo/gfx/down_black.gif | Bin 0 -> 65 bytes root/opt/phpsysinfo/gfx/down_gray.gif | Bin 0 -> 65 bytes root/opt/phpsysinfo/gfx/favicon.gif | Bin 0 -> 925 bytes root/opt/phpsysinfo/gfx/favicon.png | Bin 479 -> 0 bytes root/opt/phpsysinfo/gfx/htmlrest.gif | Bin 0 -> 120 bytes root/opt/phpsysinfo/gfx/images/4MLinux.png | Bin 3211 -> 754 bytes root/opt/phpsysinfo/gfx/images/AIX.png | Bin 4346 -> 1910 bytes root/opt/phpsysinfo/gfx/images/ALT.png | Bin 4217 -> 1779 bytes root/opt/phpsysinfo/gfx/images/Absolute.png | Bin 0 -> 834 bytes root/opt/phpsysinfo/gfx/images/Alma.png | Bin 0 -> 1208 bytes root/opt/phpsysinfo/gfx/images/Amazon.png | Bin 2193 -> 1227 bytes root/opt/phpsysinfo/gfx/images/Android.png | Bin 4217 -> 761 bytes root/opt/phpsysinfo/gfx/images/Apple.png | Bin 380 -> 511 bytes root/opt/phpsysinfo/gfx/images/Archcraft.png | Bin 0 -> 1442 bytes root/opt/phpsysinfo/gfx/images/Archman.png | Bin 0 -> 1831 bytes root/opt/phpsysinfo/gfx/images/Arco.png | Bin 0 -> 870 bytes root/opt/phpsysinfo/gfx/images/Armbian.png | Bin 0 -> 1581 bytes root/opt/phpsysinfo/gfx/images/Artix.png | Bin 0 -> 1510 bytes root/opt/phpsysinfo/gfx/images/BOSS.png | Bin 3211 -> 2640 bytes root/opt/phpsysinfo/gfx/images/BigLinux.png | Bin 0 -> 1436 bytes root/opt/phpsysinfo/gfx/images/Bluestar.png | Bin 0 -> 1933 bytes root/opt/phpsysinfo/gfx/images/Bodhi.png | Bin 0 -> 2824 bytes root/opt/phpsysinfo/gfx/images/CachyOS.png | Bin 0 -> 1588 bytes root/opt/phpsysinfo/gfx/images/Calculate.png | Bin 3211 -> 1104 bytes root/opt/phpsysinfo/gfx/images/Canaima.png | Bin 2193 -> 858 bytes root/opt/phpsysinfo/gfx/images/CentOS.png | Bin 1212 -> 1326 bytes root/opt/phpsysinfo/gfx/images/Chakra.png | Bin 2193 -> 1124 bytes root/opt/phpsysinfo/gfx/images/Clear.png | Bin 0 -> 1665 bytes root/opt/phpsysinfo/gfx/images/ClearOS.png | Bin 4217 -> 2901 bytes root/opt/phpsysinfo/gfx/images/Cloud.png | Bin 4196 -> 845 bytes root/opt/phpsysinfo/gfx/images/Cobalt.png | Bin 1943 -> 1957 bytes root/opt/phpsysinfo/gfx/images/Container.png | Bin 0 -> 822 bytes root/opt/phpsysinfo/gfx/images/CoreOS.png | Bin 2193 -> 992 bytes root/opt/phpsysinfo/gfx/images/Crux.png | Bin 4217 -> 1938 bytes root/opt/phpsysinfo/gfx/images/Darwin.png | Bin 851 -> 1136 bytes root/opt/phpsysinfo/gfx/images/Debian.png | Bin 1276 -> 1119 bytes root/opt/phpsysinfo/gfx/images/Deepin.png | Bin 3211 -> 2457 bytes root/opt/phpsysinfo/gfx/images/Devuan.png | Bin 0 -> 657 bytes root/opt/phpsysinfo/gfx/images/DragonFly.png | Bin 1805 -> 1826 bytes root/opt/phpsysinfo/gfx/images/DrayOS.png | Bin 0 -> 2210 bytes root/opt/phpsysinfo/gfx/images/EasyOS.png | Bin 0 -> 2134 bytes root/opt/phpsysinfo/gfx/images/Eisfair.png | Bin 3827 -> 2426 bytes root/opt/phpsysinfo/gfx/images/Elive.png | Bin 0 -> 2415 bytes .../opt/phpsysinfo/gfx/images/EndeavourOS.png | Bin 0 -> 1121 bytes root/opt/phpsysinfo/gfx/images/Endless.png | Bin 0 -> 901 bytes root/opt/phpsysinfo/gfx/images/EuroLinux.png | Bin 0 -> 1932 bytes root/opt/phpsysinfo/gfx/images/ExTiX.png | Bin 0 -> 1094 bytes root/opt/phpsysinfo/gfx/images/Exherbo.png | Bin 0 -> 2090 bytes root/opt/phpsysinfo/gfx/images/Fatdog.png | Bin 0 -> 2778 bytes root/opt/phpsysinfo/gfx/images/Fedora.png | Bin 742 -> 1030 bytes root/opt/phpsysinfo/gfx/images/Feren.png | Bin 0 -> 905 bytes root/opt/phpsysinfo/gfx/images/Foresight.png | Bin 4196 -> 1376 bytes root/opt/phpsysinfo/gfx/images/FortiOS.png | Bin 0 -> 848 bytes root/opt/phpsysinfo/gfx/images/FreeEOS.png | Bin 0 -> 1891 bytes root/opt/phpsysinfo/gfx/images/FreeNAS.png | Bin 0 -> 2349 bytes root/opt/phpsysinfo/gfx/images/Frugalware.png | Bin 3190 -> 1553 bytes root/opt/phpsysinfo/gfx/images/Fuduntu.png | Bin 4196 -> 1795 bytes root/opt/phpsysinfo/gfx/images/Garuda.png | Bin 0 -> 1858 bytes .../opt/phpsysinfo/gfx/images/Generations.png | Bin 3193 -> 2007 bytes root/opt/phpsysinfo/gfx/images/Gentoo.png | Bin 1890 -> 2160 bytes root/opt/phpsysinfo/gfx/images/Gnoppix.png | Bin 0 -> 1205 bytes root/opt/phpsysinfo/gfx/images/Gobo.png | Bin 2193 -> 1050 bytes root/opt/phpsysinfo/gfx/images/Guix.png | Bin 0 -> 907 bytes root/opt/phpsysinfo/gfx/images/HPUX.png | Bin 2411 -> 1152 bytes root/opt/phpsysinfo/gfx/images/Haiku.png | Bin 4217 -> 2240 bytes root/opt/phpsysinfo/gfx/images/HipServ.png | Bin 0 -> 811 bytes root/opt/phpsysinfo/gfx/images/Hurd.png | Bin 0 -> 930 bytes root/opt/phpsysinfo/gfx/images/IPFire.png | Bin 2763 -> 2717 bytes root/opt/phpsysinfo/gfx/images/IYCC.png | Bin 0 -> 1164 bytes root/opt/phpsysinfo/gfx/images/JingOS.png | Bin 0 -> 1649 bytes root/opt/phpsysinfo/gfx/images/KDEneon.png | Bin 0 -> 2746 bytes root/opt/phpsysinfo/gfx/images/KaOS.png | Bin 4217 -> 2257 bytes root/opt/phpsysinfo/gfx/images/Kaisen.png | Bin 0 -> 969 bytes root/opt/phpsysinfo/gfx/images/Kali.png | Bin 0 -> 829 bytes root/opt/phpsysinfo/gfx/images/Kodachi.png | Bin 0 -> 1945 bytes root/opt/phpsysinfo/gfx/images/Korora.png | Bin 2193 -> 1043 bytes root/opt/phpsysinfo/gfx/images/LFS.png | Bin 2193 -> 876 bytes root/opt/phpsysinfo/gfx/images/LXLE.png | Bin 0 -> 1115 bytes root/opt/phpsysinfo/gfx/images/Laclin.png | Bin 0 -> 1538 bytes root/opt/phpsysinfo/gfx/images/Lakka.png | Bin 0 -> 1345 bytes root/opt/phpsysinfo/gfx/images/LibreELEC.png | Bin 0 -> 1425 bytes root/opt/phpsysinfo/gfx/images/Linaro.png | Bin 4217 -> 975 bytes root/opt/phpsysinfo/gfx/images/Linspire.png | Bin 0 -> 1161 bytes root/opt/phpsysinfo/gfx/images/Linux.png | Bin 0 -> 1979 bytes root/opt/phpsysinfo/gfx/images/LinuxLite.png | Bin 0 -> 1068 bytes root/opt/phpsysinfo/gfx/images/Linuxfx.png | Bin 0 -> 2544 bytes root/opt/phpsysinfo/gfx/images/Lunar.png | Bin 3211 -> 981 bytes root/opt/phpsysinfo/gfx/images/MX.png | Bin 0 -> 963 bytes root/opt/phpsysinfo/gfx/images/Mabox.png | Bin 0 -> 1426 bytes root/opt/phpsysinfo/gfx/images/Mageia.png | Bin 3065 -> 1911 bytes root/opt/phpsysinfo/gfx/images/Makulu.png | Bin 0 -> 2182 bytes root/opt/phpsysinfo/gfx/images/Mandrake.png | Bin 451 -> 683 bytes root/opt/phpsysinfo/gfx/images/Manjaro.png | Bin 4196 -> 722 bytes root/opt/phpsysinfo/gfx/images/Mer.png | Bin 1458 -> 1411 bytes root/opt/phpsysinfo/gfx/images/Milis.png | Bin 0 -> 1391 bytes root/opt/phpsysinfo/gfx/images/Minix.png | Bin 3701 -> 2325 bytes root/opt/phpsysinfo/gfx/images/Mint.png | Bin 1268 -> 1014 bytes root/opt/phpsysinfo/gfx/images/NeoKylin.png | Bin 0 -> 2207 bytes root/opt/phpsysinfo/gfx/images/Neptune.png | Bin 0 -> 1157 bytes root/opt/phpsysinfo/gfx/images/NetBSD.png | Bin 2723 -> 1584 bytes root/opt/phpsysinfo/gfx/images/NethServer.png | Bin 0 -> 1019 bytes root/opt/phpsysinfo/gfx/images/Netrunner.png | Bin 4217 -> 2847 bytes .../opt/phpsysinfo/gfx/images/NexentaStor.png | Bin 0 -> 1451 bytes root/opt/phpsysinfo/gfx/images/Nitrux.png | Bin 0 -> 917 bytes root/opt/phpsysinfo/gfx/images/NixOS.png | Bin 3211 -> 605 bytes root/opt/phpsysinfo/gfx/images/Nobara.png | Bin 0 -> 700 bytes root/opt/phpsysinfo/gfx/images/NuTyX.png | Bin 0 -> 2325 bytes root/opt/phpsysinfo/gfx/images/Omarine.png | Bin 0 -> 756 bytes root/opt/phpsysinfo/gfx/images/OmniOS.png | Bin 0 -> 1568 bytes root/opt/phpsysinfo/gfx/images/OpenBSD.png | Bin 1876 -> 1689 bytes root/opt/phpsysinfo/gfx/images/OpenELEC.png | Bin 0 -> 1678 bytes .../opt/phpsysinfo/gfx/images/OpenIndiana.png | Bin 0 -> 1436 bytes root/opt/phpsysinfo/gfx/images/OpenMamba.png | Bin 0 -> 933 bytes .../phpsysinfo/gfx/images/OpenMandriva.png | Bin 2193 -> 1117 bytes .../opt/phpsysinfo/gfx/images/OpenSolaris.png | Bin 0 -> 1612 bytes root/opt/phpsysinfo/gfx/images/OpenWRT.png | Bin 0 -> 1521 bytes root/opt/phpsysinfo/gfx/images/PCLinuxOS.png | Bin 3959 -> 2224 bytes root/opt/phpsysinfo/gfx/images/PLD.png | Bin 952 -> 1002 bytes root/opt/phpsysinfo/gfx/images/Parrot.png | Bin 0 -> 1335 bytes root/opt/phpsysinfo/gfx/images/Parsix.png | Bin 2193 -> 1389 bytes root/opt/phpsysinfo/gfx/images/Pear.png | Bin 2193 -> 931 bytes root/opt/phpsysinfo/gfx/images/Peppermint.png | Bin 4217 -> 2045 bytes root/opt/phpsysinfo/gfx/images/Photon.png | Bin 0 -> 2624 bytes root/opt/phpsysinfo/gfx/images/Pisi.png | Bin 2193 -> 1468 bytes root/opt/phpsysinfo/gfx/images/Plop.png | Bin 0 -> 2199 bytes root/opt/phpsysinfo/gfx/images/Pop.png | Bin 0 -> 1233 bytes root/opt/phpsysinfo/gfx/images/Porteus.png | Bin 4217 -> 1305 bytes root/opt/phpsysinfo/gfx/images/Proxmox.png | Bin 0 -> 1243 bytes root/opt/phpsysinfo/gfx/images/Puppy.png | Bin 4196 -> 3149 bytes root/opt/phpsysinfo/gfx/images/PureOS.png | Bin 0 -> 273 bytes root/opt/phpsysinfo/gfx/images/Q4OS.png | Bin 0 -> 2123 bytes root/opt/phpsysinfo/gfx/images/QNX.png | Bin 4217 -> 1146 bytes root/opt/phpsysinfo/gfx/images/QTS.png | Bin 0 -> 1769 bytes root/opt/phpsysinfo/gfx/images/QuemOS.png | Bin 0 -> 1473 bytes root/opt/phpsysinfo/gfx/images/ROSA.png | Bin 4217 -> 3129 bytes root/opt/phpsysinfo/gfx/images/Raspbian.png | Bin 1911 -> 2158 bytes .../phpsysinfo/gfx/images/RebeccaBlackOS.png | Bin 0 -> 2744 bytes root/opt/phpsysinfo/gfx/images/RebornOS.png | Bin 0 -> 1473 bytes root/opt/phpsysinfo/gfx/images/RedFlag.png | Bin 2193 -> 1222 bytes root/opt/phpsysinfo/gfx/images/RedHat.png | Bin 469 -> 923 bytes root/opt/phpsysinfo/gfx/images/Redcore.png | Bin 0 -> 1151 bytes root/opt/phpsysinfo/gfx/images/Regata.png | Bin 0 -> 2222 bytes root/opt/phpsysinfo/gfx/images/RoboLinux.png | Bin 0 -> 2196 bytes root/opt/phpsysinfo/gfx/images/Rocky.png | Bin 0 -> 743 bytes root/opt/phpsysinfo/gfx/images/Runtu.png | Bin 0 -> 1704 bytes root/opt/phpsysinfo/gfx/images/SMEServer.png | Bin 3211 -> 935 bytes root/opt/phpsysinfo/gfx/images/SMS.png | Bin 2193 -> 1691 bytes root/opt/phpsysinfo/gfx/images/SUSE.png | Bin 3211 -> 2574 bytes root/opt/phpsysinfo/gfx/images/Sabayon.png | Bin 3211 -> 1301 bytes root/opt/phpsysinfo/gfx/images/SalentOS.png | Bin 0 -> 2197 bytes root/opt/phpsysinfo/gfx/images/Salix.png | Bin 2193 -> 808 bytes root/opt/phpsysinfo/gfx/images/Scientific.png | Bin 3925 -> 2104 bytes root/opt/phpsysinfo/gfx/images/Semplice.png | Bin 1925 -> 1398 bytes root/opt/phpsysinfo/gfx/images/Septor.png | Bin 0 -> 788 bytes root/opt/phpsysinfo/gfx/images/Siduction.png | Bin 0 -> 1816 bytes root/opt/phpsysinfo/gfx/images/Slax.png | Bin 4217 -> 1882 bytes root/opt/phpsysinfo/gfx/images/SliTaz.png | Bin 2193 -> 1615 bytes root/opt/phpsysinfo/gfx/images/SmartOS.png | Bin 0 -> 498 bytes root/opt/phpsysinfo/gfx/images/Snal.png | Bin 0 -> 1070 bytes root/opt/phpsysinfo/gfx/images/Solaris.png | Bin 0 -> 1038 bytes root/opt/phpsysinfo/gfx/images/Solus.png | Bin 0 -> 1911 bytes root/opt/phpsysinfo/gfx/images/SolusOS.png | Bin 4217 -> 2345 bytes root/opt/phpsysinfo/gfx/images/SolydXK.png | Bin 2193 -> 1618 bytes root/opt/phpsysinfo/gfx/images/Sparky.png | Bin 0 -> 2312 bytes root/opt/phpsysinfo/gfx/images/Springdale.png | Bin 0 -> 1854 bytes root/opt/phpsysinfo/gfx/images/StartOS.png | Bin 1510 -> 1541 bytes root/opt/phpsysinfo/gfx/images/SteamOS.png | Bin 2225 -> 1591 bytes root/opt/phpsysinfo/gfx/images/Synology.png | Bin 4196 -> 1185 bytes root/opt/phpsysinfo/gfx/images/Tails.png | Bin 2193 -> 1169 bytes root/opt/phpsysinfo/gfx/images/Tanglu.png | Bin 2193 -> 1357 bytes root/opt/phpsysinfo/gfx/images/TinyCore.png | Bin 3943 -> 1193 bytes root/opt/phpsysinfo/gfx/images/Trisquel.png | Bin 4217 -> 2059 bytes root/opt/phpsysinfo/gfx/images/TrueNAS.png | Bin 0 -> 1039 bytes root/opt/phpsysinfo/gfx/images/Turbo.png | Bin 4217 -> 946 bytes root/opt/phpsysinfo/gfx/images/Tuxedo.png | Bin 0 -> 793 bytes root/opt/phpsysinfo/gfx/images/UOS.png | Bin 0 -> 929 bytes root/opt/phpsysinfo/gfx/images/Ubuntu.png | Bin 1164 -> 1258 bytes .../phpsysinfo/gfx/images/UltimateEdition.png | Bin 2193 -> 1549 bytes .../opt/phpsysinfo/gfx/images/Ultramarine.png | Bin 0 -> 1049 bytes root/opt/phpsysinfo/gfx/images/Uruk.png | Bin 0 -> 1411 bytes root/opt/phpsysinfo/gfx/images/Vanilla.png | Bin 0 -> 1246 bytes root/opt/phpsysinfo/gfx/images/Vector.png | Bin 3599 -> 2292 bytes root/opt/phpsysinfo/gfx/images/Venom.png | Bin 0 -> 672 bytes root/opt/phpsysinfo/gfx/images/Virtuozzo.png | Bin 0 -> 762 bytes root/opt/phpsysinfo/gfx/images/Void.png | Bin 0 -> 1202 bytes root/opt/phpsysinfo/gfx/images/VortexBox.png | Bin 3193 -> 1165 bytes root/opt/phpsysinfo/gfx/images/WINNT.png | Bin 0 -> 1794 bytes root/opt/phpsysinfo/gfx/images/Win11.png | Bin 0 -> 216 bytes root/opt/phpsysinfo/gfx/images/Win2000.png | Bin 4196 -> 1107 bytes root/opt/phpsysinfo/gfx/images/Win8.png | Bin 903 -> 817 bytes root/opt/phpsysinfo/gfx/images/XeroLinux.png | Bin 0 -> 1578 bytes root/opt/phpsysinfo/gfx/images/Zenwalk.png | Bin 3211 -> 854 bytes root/opt/phpsysinfo/gfx/images/Zorin.png | Bin 4217 -> 766 bytes root/opt/phpsysinfo/gfx/images/antiX.png | Bin 4857 -> 1718 bytes root/opt/phpsysinfo/gfx/images/dahliaOS.png | Bin 0 -> 777 bytes .../phpsysinfo/gfx/images/elementaryOS.png | Bin 987 -> 1183 bytes root/opt/phpsysinfo/gfx/images/free-eos.png | Bin 1676 -> 0 bytes root/opt/phpsysinfo/gfx/images/gNewSense.png | Bin 6137 -> 776 bytes root/opt/phpsysinfo/gfx/images/iycc.png | Bin 1636 -> 0 bytes root/opt/phpsysinfo/gfx/images/openEuler.png | Bin 0 -> 1037 bytes root/opt/phpsysinfo/gfx/images/pfSense.png | Bin 1169 -> 541 bytes root/opt/phpsysinfo/gfx/images/risiOS.png | Bin 0 -> 1605 bytes root/opt/phpsysinfo/gfx/images/unknown.png | Bin 31826 -> 2014 bytes root/opt/phpsysinfo/gfx/logo_32.gif | Bin 0 -> 1285 bytes root/opt/phpsysinfo/gfx/logo_48.png | Bin 1819 -> 0 bytes root/opt/phpsysinfo/gfx/next.gif | Bin 0 -> 893 bytes root/opt/phpsysinfo/gfx/next.png | Bin 169 -> 0 bytes root/opt/phpsysinfo/gfx/prev.gif | Bin 0 -> 893 bytes root/opt/phpsysinfo/gfx/prev.png | Bin 173 -> 0 bytes root/opt/phpsysinfo/gfx/reload.gif | Bin 0 -> 935 bytes root/opt/phpsysinfo/gfx/reload.png | Bin 685 -> 0 bytes root/opt/phpsysinfo/gfx/right_black.gif | Bin 0 -> 65 bytes root/opt/phpsysinfo/gfx/right_gray.gif | Bin 0 -> 65 bytes root/opt/phpsysinfo/gfx/sort_asc.gif | Bin 0 -> 131 bytes root/opt/phpsysinfo/gfx/sort_asc.png | Bin 217 -> 0 bytes root/opt/phpsysinfo/gfx/sort_both.gif | Bin 0 -> 150 bytes root/opt/phpsysinfo/gfx/sort_both.png | Bin 246 -> 0 bytes root/opt/phpsysinfo/gfx/sort_desc.gif | Bin 0 -> 129 bytes root/opt/phpsysinfo/gfx/sort_desc.png | Bin 215 -> 0 bytes .../phpsysinfo/includes/autoloader.inc.php | 24 +- .../includes/class.CommonFunctions.inc.php | 669 +- .../phpsysinfo/includes/class.Parser.inc.php | 250 +- ....Error.inc.php => class.PSI_Error.inc.php} | 36 +- .../interface/class.PSI_Interface_OS.inc.php | 11 +- .../class.PSI_Interface_Output.inc.php | 4 +- .../class.PSI_Interface_Plugin.inc.php | 6 +- .../class.PSI_Interface_Sensor.inc.php | 4 +- .../interface/class.PSI_Interface_UPS.inc.php | 4 +- .../js/class.JavaScriptPacker.inc.php | 13 +- .../includes/mb/class.coretemp.inc.php | 62 - .../includes/mb/class.cpumem.inc.php | 96 + .../includes/mb/class.fortisensor.inc.php | 122 + .../includes/mb/class.freeipmi.inc.php | 57 +- .../includes/mb/class.hddtemp.inc.php | 32 +- .../includes/mb/class.healthd.inc.php | 171 +- .../includes/mb/class.hwmon.inc.php | 267 + .../includes/mb/class.hwsensors.inc.php | 29 +- .../phpsysinfo/includes/mb/class.ipmi.inc.php | 197 - .../includes/mb/class.ipmicfg.inc.php | 321 + .../includes/mb/class.ipmitool.inc.php | 320 + .../includes/mb/class.ipmiutil.inc.php | 102 +- .../includes/mb/class.k8temp.inc.php | 28 +- .../includes/mb/class.lmsensors.inc.php | 536 +- .../phpsysinfo/includes/mb/class.mbm5.inc.php | 31 +- .../includes/mb/class.mbmon.inc.php | 32 +- .../includes/mb/class.nvidiasmi.inc.php | 136 + .../phpsysinfo/includes/mb/class.ohm.inc.php | 96 +- .../includes/mb/class.pitemp.inc.php | 28 +- .../includes/mb/class.qtssnmp.inc.php | 93 + .../includes/mb/class.sensors.inc.php | 8 +- .../includes/mb/class.speedfan.inc.php | 125 + .../includes/mb/class.thermalzone.inc.php | 134 +- .../includes/mb/class.thinkpad.inc.php | 41 + .../phpsysinfo/includes/os/class.AIX.inc.php | 100 +- .../includes/os/class.Android.inc.php | 141 +- .../includes/os/class.BSDCommon.inc.php | 498 +- .../includes/os/class.Darwin.inc.php | 247 +- .../includes/os/class.DragonFly.inc.php | 54 +- .../includes/os/class.FreeBSD.inc.php | 90 +- .../phpsysinfo/includes/os/class.GNU.inc.php | 118 + .../phpsysinfo/includes/os/class.HPUX.inc.php | 129 +- .../includes/os/class.Haiku.inc.php | 155 +- .../includes/os/class.Linux.inc.php | 2205 +++- .../includes/os/class.Minix.inc.php | 150 +- .../includes/os/class.NetBSD.inc.php | 175 +- .../phpsysinfo/includes/os/class.OS.inc.php | 200 +- .../includes/os/class.OpenBSD.inc.php | 170 +- .../phpsysinfo/includes/os/class.QNX.inc.php | 107 +- .../phpsysinfo/includes/os/class.SSH.inc.php | 857 ++ .../includes/os/class.SunOS.inc.php | 302 +- .../includes/os/class.WINNT.inc.php | 1836 ++- .../includes/output/class.Output.inc.php | 12 +- .../includes/output/class.Template.inc.php | 14 +- .../includes/output/class.Webpage.inc.php | 122 +- .../includes/output/class.WebpageXML.inc.php | 263 +- .../includes/output/class.WebpageXSLT.inc.php | 7 +- .../includes/plugin/class.PSI_Plugin.inc.php | 33 +- .../includes/to/class.MBInfo.inc.php | 102 +- .../includes/to/class.System.inc.php | 344 +- .../includes/to/class.UPSInfo.inc.php | 10 +- .../to/device/class.CpuDevice.inc.php | 322 +- .../to/device/class.DiskDevice.inc.php | 101 +- .../includes/to/device/class.HWDevice.inc.php | 242 +- .../to/device/class.NetDevice.inc.php | 143 +- .../to/device/class.SensorDevice.inc.php | 69 +- .../to/device/class.UPSDevice.inc.php | 127 +- .../includes/ups/class.apcupsd.inc.php | 68 +- .../phpsysinfo/includes/ups/class.nut.inc.php | 88 +- .../includes/ups/class.pmset.inc.php | 67 +- .../includes/ups/class.powersoftplus.inc.php | 33 +- .../includes/ups/class.snmpups.inc.php | 292 + .../phpsysinfo/includes/ups/class.ups.inc.php | 10 +- .../xml/class.SimpleXMLExtended.inc.php | 59 +- .../phpsysinfo/includes/xml/class.XML.inc.php | 696 +- root/opt/phpsysinfo/index.php | 56 +- root/opt/phpsysinfo/js.php | 71 +- root/opt/phpsysinfo/js/jQuery/README | 30 +- .../opt/phpsysinfo/js/jQuery/README_bootstrap | 10 +- root/opt/phpsysinfo/js/jQuery/jquery-1.js | 10351 ---------------- .../phpsysinfo/js/jQuery/jquery.dataTables.js | 59 +- .../phpsysinfo/js/jQuery/jquery.ifixpng.js | 143 + .../opt/phpsysinfo/js/jQuery/jquery.jgrowl.js | 34 +- root/opt/phpsysinfo/js/jQuery/jquery.js | 7157 +++++++---- .../phpsysinfo/js/jQuery/jquery.nyroModal.js | 42 +- .../{jquery.timers.js => jquery.timer.js} | 5 +- .../phpsysinfo/js/jQuery/jquery.treeTable.js | 40 +- .../phpsysinfo/js/phpSysInfo/phpsysinfo.js | 1539 ++- .../js/phpSysInfo/phpsysinfo_bootstrap.js | 1654 ++- root/opt/phpsysinfo/js/vendor/README | 43 +- .../opt/phpsysinfo/js/vendor/bootstrap-ie8.js | 707 ++ .../opt/phpsysinfo/js/vendor/bootstrap-ie9.js | 135 + .../phpsysinfo/js/vendor/bootstrap-modal.js | 649 + .../phpsysinfo/js/vendor/bootstrap-util.js | 171 + .../opt/phpsysinfo/js/vendor/bootstrap.min.js | 7 - .../js/vendor/html5shiv-printshiv.js | 10 +- root/opt/phpsysinfo/js/vendor/sorttable.js | 128 +- .../opt/phpsysinfo/js/vendor/sorttable_org.js | 495 - root/opt/phpsysinfo/js/vendor/transparency.js | 5 + root/opt/phpsysinfo/language/ar.xml | 411 + root/opt/phpsysinfo/language/ast.xml | 48 + root/opt/phpsysinfo/language/bg.xml | 48 + root/opt/phpsysinfo/language/ca.xml | 48 + root/opt/phpsysinfo/language/cz.xml | 82 +- root/opt/phpsysinfo/language/da.xml | 48 + root/opt/phpsysinfo/language/de.xml | 50 +- root/opt/phpsysinfo/language/en.xml | 48 + root/opt/phpsysinfo/language/es.xml | 48 + root/opt/phpsysinfo/language/et.xml | 48 + root/opt/phpsysinfo/language/fa.xml | 411 + root/opt/phpsysinfo/language/fi.xml | 48 + root/opt/phpsysinfo/language/fr.xml | 60 +- root/opt/phpsysinfo/language/gl.xml | 48 + root/opt/phpsysinfo/language/gr.xml | 104 +- root/opt/phpsysinfo/language/he.xml | 48 + root/opt/phpsysinfo/language/hr.xml | 411 + root/opt/phpsysinfo/language/hu.xml | 50 +- root/opt/phpsysinfo/language/id.xml | 411 + root/opt/phpsysinfo/language/is.xml | 48 + root/opt/phpsysinfo/language/it.xml | 48 + root/opt/phpsysinfo/language/ja.xml | 48 + root/opt/phpsysinfo/language/ko.xml | 166 +- root/opt/phpsysinfo/language/language.php | 39 +- root/opt/phpsysinfo/language/nl.xml | 48 + root/opt/phpsysinfo/language/no.xml | 120 +- root/opt/phpsysinfo/language/pl.xml | 50 +- root/opt/phpsysinfo/language/pt-br.xml | 48 + root/opt/phpsysinfo/language/pt-pt.xml | 48 + root/opt/phpsysinfo/language/ro.xml | 48 + root/opt/phpsysinfo/language/ru.xml | 48 + root/opt/phpsysinfo/language/sk.xml | 48 + root/opt/phpsysinfo/language/sl.xml | 48 + root/opt/phpsysinfo/language/sv.xml | 144 +- root/opt/phpsysinfo/language/th.xml | 48 + root/opt/phpsysinfo/language/tr.xml | 120 +- root/opt/phpsysinfo/language/translation.xsd | 2 +- root/opt/phpsysinfo/language/tw.xml | 48 + root/opt/phpsysinfo/language/uk.xml | 108 +- root/opt/phpsysinfo/language/zh.xml | 66 +- root/opt/phpsysinfo/phpsysinfo.ini.new | 767 +- root/opt/phpsysinfo/phpsysinfo.xslt | 2253 ++-- root/opt/phpsysinfo/phpsysinfo3.xsd | 781 +- .../phpsysinfo/plugins/bat/bat_bootstrap.html | 78 +- .../phpsysinfo/plugins/bat/class.bat.inc.php | 996 +- root/opt/phpsysinfo/plugins/bat/js/bat.js | 212 +- .../plugins/bat/js/bat_bootstrap.js | 148 +- root/opt/phpsysinfo/plugins/bat/lang/cz.xml | 41 +- root/opt/phpsysinfo/plugins/bat/lang/de.xml | 41 +- root/opt/phpsysinfo/plugins/bat/lang/en.xml | 41 +- root/opt/phpsysinfo/plugins/bat/lang/fr.xml | 39 +- root/opt/phpsysinfo/plugins/bat/lang/gr.xml | 57 + root/opt/phpsysinfo/plugins/bat/lang/pl.xml | 41 +- root/opt/phpsysinfo/plugins/bat/lang/ro.xml | 41 +- root/opt/phpsysinfo/plugins/bat/lang/ru.xml | 41 +- .../plugins/diskload/class.diskload.inc.php | 76 + .../plugins/diskload/diskload_bootstrap.html | 26 + .../plugins/diskload/js/diskload.js | 115 + .../plugins/diskload/js/diskload_bootstrap.js | 28 + .../phpsysinfo/plugins/diskload/lang/en.xml | 18 + .../phpsysinfo/plugins/diskload/lang/pl.xml | 18 + .../plugins/dmraid/class.dmraid.inc.php | 176 - .../phpsysinfo/plugins/dmraid/css/dmraid.css | 14 - .../plugins/dmraid/dmraid_bootstrap.html | 9 - .../plugins/dmraid/gfx/harddrivespare.png | Bin 1749 -> 0 bytes .../plugins/dmraid/gfx/harddrivewarn.png | Bin 10979 -> 0 bytes .../phpsysinfo/plugins/dmraid/js/dmraid.js | 176 - .../plugins/dmraid/js/dmraid_bootstrap.js | 95 - .../opt/phpsysinfo/plugins/dmraid/lang/en.xml | 42 - .../opt/phpsysinfo/plugins/dmraid/lang/fr.xml | 41 - .../opt/phpsysinfo/plugins/dmraid/lang/ro.xml | 42 - .../opt/phpsysinfo/plugins/dmraid/lang/ru.xml | 41 - .../plugins/docker/class.docker.inc.php | 134 + .../plugins/docker/docker_bootstrap.html | 38 + .../phpsysinfo/plugins/docker/js/docker.js | 155 + .../plugins/docker/js/docker_bootstrap.js | 46 + .../opt/phpsysinfo/plugins/docker/lang/en.xml | 36 + .../opt/phpsysinfo/plugins/docker/lang/gr.xml | 36 + .../opt/phpsysinfo/plugins/docker/lang/pl.xml | 36 + .../plugins/hyperv/class.hyperv.inc.php | 99 + .../phpsysinfo/plugins/hyperv/css/hyperv.css | 6 + .../phpsysinfo/plugins/hyperv/gfx/offline.gif | Bin 0 -> 992 bytes .../phpsysinfo/plugins/hyperv/gfx/online.gif | Bin 0 -> 988 bytes .../plugins/hyperv/hyperv_bootstrap.html | 26 + .../phpsysinfo/plugins/hyperv/js/hyperv.js | 132 + .../plugins/hyperv/js/hyperv_bootstrap.js | 32 + .../opt/phpsysinfo/plugins/hyperv/lang/en.xml | 18 + .../opt/phpsysinfo/plugins/hyperv/lang/gr.xml | 18 + .../opt/phpsysinfo/plugins/hyperv/lang/pl.xml | 18 + .../plugins/ipmiinfo/class.ipmiinfo.inc.php | 269 - .../plugins/ipmiinfo/ipmiinfo_bootstrap.html | 15 - .../plugins/ipmiinfo/js/ipmiinfo.js | 153 - .../plugins/ipmiinfo/js/ipmiinfo_bootstrap.js | 36 - .../phpsysinfo/plugins/ipmiinfo/lang/cz.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/de.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/en.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/fr.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/pl.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/ro.xml | 33 - .../phpsysinfo/plugins/ipmiinfo/lang/ru.xml | 33 - .../plugins/mdstatus/class.mdstatus.inc.php | 236 - .../plugins/mdstatus/css/mdstatus.css | 14 - .../phpsysinfo/plugins/mdstatus/gfx/error.png | Bin 3617 -> 0 bytes .../plugins/mdstatus/gfx/harddrivefail.png | Bin 3920 -> 0 bytes .../plugins/mdstatus/gfx/harddriveok.png | Bin 3675 -> 0 bytes .../plugins/mdstatus/gfx/harddrivespare.png | Bin 1749 -> 0 bytes .../plugins/mdstatus/js/mdstatus.js | 225 - .../plugins/mdstatus/js/mdstatus_bootstrap.js | 146 - .../phpsysinfo/plugins/mdstatus/lang/cz.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/de.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/en.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/fr.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/gr.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/ro.xml | 57 - .../phpsysinfo/plugins/mdstatus/lang/ru.xml | 57 - .../plugins/mdstatus/mdstatus_bootstrap.html | 9 - .../plugins/pingtest/class.pingtest.inc.php | 143 + .../plugins/pingtest/css/pingtest.css | 6 + .../plugins/pingtest/js/pingtest.js | 131 + .../plugins/pingtest/js/pingtest_bootstrap.js | 27 + .../phpsysinfo/plugins/pingtest/lang/cz.xml | 20 + .../phpsysinfo/plugins/pingtest/lang/de.xml | 21 + .../phpsysinfo/plugins/pingtest/lang/en.xml | 21 + .../phpsysinfo/plugins/pingtest/lang/gr.xml | 21 + .../phpsysinfo/plugins/pingtest/lang/pl.xml | 21 + .../plugins/pingtest/pingtest_bootstrap.html | 26 + .../phpsysinfo/plugins/ps/class.ps.inc.php | 125 +- root/opt/phpsysinfo/plugins/ps/js/ps.js | 63 +- .../phpsysinfo/plugins/ps/js/ps_bootstrap.js | 73 +- root/opt/phpsysinfo/plugins/ps/lang/cz.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/de.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/en.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/fr.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/gr.xml | 16 +- root/opt/phpsysinfo/plugins/ps/lang/pl.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/ro.xml | 14 +- root/opt/phpsysinfo/plugins/ps/lang/ru.xml | 16 +- root/opt/phpsysinfo/plugins/ps/lang/uk.xml | 27 + .../phpsysinfo/plugins/ps/ps_bootstrap.html | 46 +- .../plugins/psstatus/class.psstatus.inc.php | 175 +- .../plugins/psstatus/css/psstatus.css | 2 +- .../plugins/psstatus/gfx/offline.gif | Bin 0 -> 992 bytes .../plugins/psstatus/gfx/offline.png | Bin 993 -> 0 bytes .../plugins/psstatus/gfx/online.gif | Bin 0 -> 988 bytes .../plugins/psstatus/gfx/online.png | Bin 755 -> 0 bytes .../plugins/psstatus/js/psstatus.js | 38 +- .../plugins/psstatus/js/psstatus_bootstrap.js | 13 +- .../phpsysinfo/plugins/psstatus/lang/cz.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/de.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/en.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/fr.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/gr.xml | 11 +- .../phpsysinfo/plugins/psstatus/lang/pl.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/ro.xml | 9 +- .../phpsysinfo/plugins/psstatus/lang/ru.xml | 11 +- .../phpsysinfo/plugins/psstatus/lang/uk.xml | 18 + .../plugins/psstatus/psstatus_bootstrap.html | 41 +- .../plugins/quotas/class.quotas.inc.php | 53 +- .../phpsysinfo/plugins/quotas/css/quotas.css | 2 +- .../phpsysinfo/plugins/quotas/js/quotas.js | 48 +- .../plugins/quotas/js/quotas_bootstrap.js | 24 +- .../opt/phpsysinfo/plugins/quotas/lang/cz.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/de.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/en.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/fr.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/gr.xml | 39 + .../opt/phpsysinfo/plugins/quotas/lang/pl.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/ro.xml | 23 +- .../opt/phpsysinfo/plugins/quotas/lang/ru.xml | 25 +- .../plugins/quotas/quotas_bootstrap.html | 69 +- .../plugins/raid/class.raid.inc.php | 2553 ++++ root/opt/phpsysinfo/plugins/raid/css/raid.css | 27 + .../plugins/{dmraid => raid}/gfx/error.png | Bin .../{dmraid => raid}/gfx/harddrivefail.png | Bin .../{dmraid => raid}/gfx/harddriveok.png | Bin .../plugins/raid/gfx/harddrivespare.png | Bin 0 -> 3210 bytes .../plugins/raid/gfx/harddriveunc.png | Bin 0 -> 4146 bytes .../plugins/raid/gfx/harddrivewarn.png | Bin 0 -> 3593 bytes .../plugins/raid/gfx/soliddrivefail.png | Bin 0 -> 4785 bytes .../plugins/raid/gfx/soliddriveok.png | Bin 0 -> 4578 bytes .../plugins/raid/gfx/soliddrivespare.png | Bin 0 -> 3439 bytes .../plugins/raid/gfx/soliddriveunc.png | Bin 0 -> 4610 bytes .../plugins/raid/gfx/soliddrivewarn.png | Bin 0 -> 3921 bytes root/opt/phpsysinfo/plugins/raid/js/raid.js | 313 + .../plugins/raid/js/raid_bootstrap.js | 191 + root/opt/phpsysinfo/plugins/raid/lang/cz.xml | 108 + root/opt/phpsysinfo/plugins/raid/lang/de.xml | 108 + root/opt/phpsysinfo/plugins/raid/lang/en.xml | 108 + root/opt/phpsysinfo/plugins/raid/lang/fr.xml | 107 + root/opt/phpsysinfo/plugins/raid/lang/gr.xml | 108 + root/opt/phpsysinfo/plugins/raid/lang/ro.xml | 108 + root/opt/phpsysinfo/plugins/raid/lang/ru.xml | 107 + .../plugins/raid/raid_bootstrap.html | 16 + .../plugins/smart/class.smart.inc.php | 550 +- .../phpsysinfo/plugins/smart/css/smart.css | 4 + root/opt/phpsysinfo/plugins/smart/js/smart.js | 85 +- .../plugins/smart/js/smart_bootstrap.js | 80 +- root/opt/phpsysinfo/plugins/smart/lang/cz.xml | 83 +- root/opt/phpsysinfo/plugins/smart/lang/en.xml | 83 +- root/opt/phpsysinfo/plugins/smart/lang/fr.xml | 83 +- root/opt/phpsysinfo/plugins/smart/lang/gr.xml | 85 +- root/opt/phpsysinfo/plugins/smart/lang/pl.xml | 83 +- root/opt/phpsysinfo/plugins/smart/lang/ro.xml | 83 +- root/opt/phpsysinfo/plugins/smart/lang/ru.xml | 42 - .../plugins/smart/smart_bootstrap.html | 16 +- .../plugins/snmppinfo/class.snmppinfo.inc.php | 173 +- .../plugins/snmppinfo/js/snmppinfo.js | 64 +- .../snmppinfo/js/snmppinfo_bootstrap.js | 83 +- .../phpsysinfo/plugins/snmppinfo/lang/cz.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/de.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/en.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/fr.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/gr.xml | 36 + .../phpsysinfo/plugins/snmppinfo/lang/pl.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/ro.xml | 22 +- .../phpsysinfo/plugins/snmppinfo/lang/ru.xml | 22 +- .../snmppinfo/snmppinfo_bootstrap.html | 26 +- .../plugins/stablebit/class.stablebit.inc.php | 74 + .../phpsysinfo/plugins/stablebit/gfx/off.gif | Bin 0 -> 988 bytes .../phpsysinfo/plugins/stablebit/gfx/on.gif | Bin 0 -> 992 bytes .../plugins/stablebit/js/stablebit.js | 213 + .../stablebit/js/stablebit_bootstrap.js | 102 + .../phpsysinfo/plugins/stablebit/lang/en.xml | 51 + .../phpsysinfo/plugins/stablebit/lang/gr.xml | 51 + .../stablebit/stablebit_bootstrap.html | 22 + .../class.updatenotifier.inc.php | 69 +- .../updatenotifier/js/updatenotifier.js | 77 +- .../js/updatenotifier_bootstrap.js | 14 +- .../plugins/updatenotifier/lang/cz.xml | 6 + .../plugins/updatenotifier/lang/de.xml | 8 +- .../plugins/updatenotifier/lang/en.xml | 6 + .../plugins/updatenotifier/lang/fr.xml | 6 + .../plugins/updatenotifier/lang/gr.xml | 30 + .../plugins/updatenotifier/lang/pl.xml | 6 + .../plugins/updatenotifier/lang/ro.xml | 6 + .../plugins/updatenotifier/lang/ru.xml | 8 +- .../updatenotifier_bootstrap.html | 17 +- .../plugins/uprecords/class.uprecords.inc.php | 71 +- .../plugins/uprecords/js/uprecords.js | 94 +- .../uprecords/js/uprecords_bootstrap.js | 17 +- .../phpsysinfo/plugins/uprecords/lang/en.xml | 3 - .../phpsysinfo/plugins/uprecords/lang/fr.xml | 3 - .../phpsysinfo/plugins/uprecords/lang/gr.xml | 24 + .../phpsysinfo/plugins/uprecords/lang/hu.xml | 5 +- .../phpsysinfo/plugins/uprecords/lang/pl.xml | 5 +- .../phpsysinfo/plugins/uprecords/lang/ro.xml | 3 - .../phpsysinfo/plugins/uprecords/lang/ru.xml | 5 +- .../uprecords/uprecords_bootstrap.html | 49 +- .../plugins/viewer/class.viewer.inc.php | 96 + .../phpsysinfo/plugins/viewer/js/viewer.js | 115 + .../plugins/viewer/js/viewer_bootstrap.js | 32 + .../opt/phpsysinfo/plugins/viewer/lang/en.xml | 12 + .../opt/phpsysinfo/plugins/viewer/lang/gr.xml | 12 + .../opt/phpsysinfo/plugins/viewer/lang/pl.xml | 12 + .../plugins/viewer/viewer_bootstrap.html | 24 + root/opt/phpsysinfo/read_config.php | 280 +- root/opt/phpsysinfo/sample/aix/prtconf1.txt | 65 + root/opt/phpsysinfo/sample/aix/prtconf2.txt | 86 + .../sample/distrotest/Absolute/15.0.txt | 12 + .../phpsysinfo/sample/distrotest/Alma/8.3.txt | 30 + .../sample/distrotest/Amazon/2016.09.txt | 18 + .../sample/distrotest/Arch/2013.11.01.txt | 1 - .../sample/distrotest/Arch/2014.01.05.txt | 1 - .../sample/distrotest/Arch/2017.03.07-ARM.txt | 10 + .../distrotest/Archcraft/2023.01.01.txt | 26 + .../sample/distrotest/Archman/2022-07.txt | 24 + .../sample/distrotest/Arco/22.01.10_l.txt | 30 + .../sample/distrotest/Armbian/23.02.2.txt | 45 + .../sample/distrotest/Artix/20210726.txt | 28 + .../sample/distrotest/BigLinux/19.04.txt | 23 + .../sample/distrotest/BigLinux/20.04_RC1.txt | 23 + .../distrotest/BigLinux/2023-04-11_15-10.txt | 32 + .../sample/distrotest/BigLinux/7.10.txt | 28 + .../sample/distrotest/Bluestar/5.16.15.txt | 17 + .../sample/distrotest/Bodhi/6.0.0.txt | 25 + .../sample/distrotest/CachyOS/221230.txt | 30 + .../sample/distrotest/CentOS/Stream-8.txt | 26 + .../sample/distrotest/Clear/35000.txt | 13 + .../sample/distrotest/Cloud/7.2.txt | 24 + .../sample/distrotest/Container/1409.2.0.txt | 16 + .../sample/distrotest/Deepin/20.08.txt | 42 + .../sample/distrotest/Deepin/23-alpha2.txt | 44 + .../sample/distrotest/Devuan/1.0.txt | 18 + .../sample/distrotest/EasyOS/0.6.8.txt | 38 + .../sample/distrotest/EasyOS/0.9.4.txt | 37 + .../sample/distrotest/EasyOS/1.2.9.1.txt | 40 + .../sample/distrotest/EasyOS/2.1.11.txt | 40 + .../sample/distrotest/Eisfair/1-2.6.5.txt | 10 + .../sample/distrotest/Eisfair/64-2.8.25.txt | 15 + .../sample/distrotest/Elive/3.8.30.txt | 37 + .../sample/distrotest/EndeavourOS/21.4.txt | 27 + .../sample/distrotest/Endless/3.3.16.txt | 21 + .../sample/distrotest/EuroLinux/8.4.txt | 26 + .../sample/distrotest/ExTiX/22.12.txt | 42 + .../sample/distrotest/Exherbo/2019.09.08.txt | 64 + .../sample/distrotest/Fatdog/813.txt | 31 + .../sample/distrotest/Feren/2020.07.txt | 25 + .../sample/distrotest/FreeEOS/1.3.3.txt | 2 + .../sample/distrotest/Garuda/220106.txt | 26 + .../sample/distrotest/Gnoppix/22.txt | 25 + .../sample/distrotest/Guix/1.4.0.txt | 9 + .../sample/distrotest/HipServ/2.6.txt | 2 + .../sample/distrotest/JingOS/0.8.1.txt | 27 + .../sample/distrotest/KDEneon/5.21.txt | 27 + .../sample/distrotest/Kaisen/2.2.txt | 18 + .../sample/distrotest/Kali/2018.1.txt | 23 + .../sample/distrotest/Kodachi/18.04.txt | 25 + .../sample/distrotest/LXLE/20.04.txt | 25 + .../phpsysinfo/sample/distrotest/Laclin/1.txt | 21 + .../sample/distrotest/Lakka/2.0.txt | 16 + .../sample/distrotest/LibreELEC/8.0.1.txt | 16 + .../sample/distrotest/Linspire/12.0.1.txt | 25 + .../sample/distrotest/LinuxLite/6.2.txt | 25 + .../sample/distrotest/Linuxfx/11.1.1103.txt | 27 + .../phpsysinfo/sample/distrotest/MX/17.1.txt | 35 + .../sample/distrotest/Mabox/21.02.txt | 27 + .../sample/distrotest/Makulu/2021.12.15.txt | 26 + .../sample/distrotest/Manjaro/21.12-arm.txt | 23 + .../sample/distrotest/Milis/2.0.txt | 16 + .../sample/distrotest/Mint/20.3.txt | 25 + .../sample/distrotest/Mint/LMDE_5.txt | 25 + .../sample/distrotest/NeoKylin/6.0.txt | 22 + .../sample/distrotest/Neptune/7.5.txt | 23 + .../sample/distrotest/NethServer/7.9.2009.txt | 40 + .../sample/distrotest/Nitrux/2.0.0-280122.txt | 24 + .../sample/distrotest/Nobara/37.txt | 33 + .../sample/distrotest/NuTyX/10.0.txt | 12 + .../sample/distrotest/Omarine/7.0.txt | 14 + .../sample/distrotest/OpenELEC/8.0.3.txt | 14 + .../sample/distrotest/OpenMamba/3.0.1.txt | 31 + .../sample/distrotest/OpenWRT/22.03.2.txt | 29 + .../sample/distrotest/Parrot/5.0.txt | 18 + .../sample/distrotest/Parsix/8.15.txt | 19 + .../sample/distrotest/Pear/11.1.0.txt | 27 + .../sample/distrotest/Photon/5.0.txt | 22 + .../sample/distrotest/Plop/23.1.txt | 3 + .../sample/distrotest/Pop/21.10.txt | 26 + .../sample/distrotest/Proxmox/8.0.3.txt | 14 + .../sample/distrotest/Puppy/22.12.txt | 38 + .../sample/distrotest/PureOS/10.0.txt | 25 + .../sample/distrotest/PureOS/3.0beta1.txt | 14 + .../sample/distrotest/Q4OS/3.16.txt | 19 + .../sample/distrotest/QTS/3.1.2.txt | 284 + .../sample/distrotest/QuemOS/1.3.txt | 17 + .../distrotest/RebeccaBlackOS/20230116.txt | 19 + .../sample/distrotest/RebornOS/2022.04.10.txt | 26 + .../sample/distrotest/RedHat/7.5.txt | 20 + .../sample/distrotest/Redcore/1803.txt | 10 + .../sample/distrotest/Regata/22.txt | 17 + .../sample/distrotest/RoboLinux/20.04.txt | 25 + .../sample/distrotest/Rocky/8.3-RC1.txt | 26 + .../sample/distrotest/Rocky/8.4.txt | 20 + .../sample/distrotest/Runtu/22.04.txt | 25 + .../sample/distrotest/SMEServer/10.1.txt | 34 + .../sample/distrotest/SUSE/12.0.txt | 19 + .../sample/distrotest/SalentOS/1.0.1.txt | 20 + .../sample/distrotest/Septor/2021.txt | 19 + .../sample/distrotest/Siduction/22.1.txt | 17 + .../sample/distrotest/Slackware/8.1.txt | 2 + .../sample/distrotest/SliTaz/5.0-RC4.txt | 4 + .../sample/distrotest/Snal/1.24.txt | 25 + .../sample/distrotest/Solus/1.0-rc1.txt | 26 + .../sample/distrotest/Solus/2017.01.01.0.txt | 26 + .../sample/distrotest/Sparky/6.5.txt | 22 + .../sample/distrotest/Springdale/6.9.txt | 16 + .../sample/distrotest/Springdale/7.3.txt | 28 + .../sample/distrotest/Tuxedo/22.04.2.txt | 27 + .../phpsysinfo/sample/distrotest/UOS/20.txt | 30 + .../sample/distrotest/Ubuntu/20.04.txt | 27 + .../sample/distrotest/Ultramarine/36.0.txt | 33 + .../phpsysinfo/sample/distrotest/Uruk/3.0.txt | 26 + .../sample/distrotest/Vanilla/22.10.txt | 25 + .../sample/distrotest/Venom/4.0.txt | 13 + .../sample/distrotest/Virtuozzo/8.3.txt | 24 + .../sample/distrotest/Void/1.0-20160420.txt | 11 + .../sample/distrotest/XeroLinux/2022.12.txt | 27 + .../sample/distrotest/dahliaOS/220222.txt | 6 + .../sample/distrotest/elementaryOS/0.4.txt | 23 + .../sample/distrotest/elementaryOS/6.0.txt | 28 + .../sample/distrotest/openEuler/22.09.txt | 18 + .../sample/distrotest/openSUSE/20211111.txt | 13 + .../sample/distrotest/openSUSE/42.3.txt | 16 + .../sample/distrotest/risiOS/37.txt | 29 + .../sample/forti/execute_sensor_list0.txt | 4 + .../sample/forti/execute_sensor_list1.txt | 55 + .../phpsysinfo/sample/freebsd/netstat1.txt | 8 + .../phpsysinfo/sample/freebsd/netstat2.txt | 7 + .../phpsysinfo/sample/freebsd/netstat3.txt | 7 + .../phpsysinfo/sample/logs/log_android21.txt | 270 - .../phpsysinfo/sample/logs/log_android412.txt | 443 - .../phpsysinfo/sample/logs/log_bluestacks.txt | 202 - .../phpsysinfo/sample/logs/log_debian7.txt | 153 - root/opt/phpsysinfo/sample/logs/log_sf.txt | 697 -- root/opt/phpsysinfo/sample/main/1-cpuinfo.txt | 21 - root/opt/phpsysinfo/sample/main/README | 6 +- root/opt/phpsysinfo/sample/main/cpuinfo10.txt | 24 + root/opt/phpsysinfo/sample/main/cpuinfo11.txt | 74 + root/opt/phpsysinfo/sample/main/cpuinfo12.txt | 15 + root/opt/phpsysinfo/sample/main/cpuinfo13.txt | 13 + root/opt/phpsysinfo/sample/main/cpuinfo14.txt | 43 + root/opt/phpsysinfo/sample/main/cpuinfo15.txt | 32 + root/opt/phpsysinfo/sample/main/cpuinfo16.txt | 6 + .../sample/main/{df1.txt => dfP1.txt} | 0 .../sample/main/{1-dfiP.txt => dfiP1.txt} | 0 root/opt/phpsysinfo/sample/main/dfk1.txt | 7 + .../sample/main/{1-dfkP.txt => dfkP1.txt} | 0 .../sample/main/{1-mount.txt => mount2.txt} | 0 root/opt/phpsysinfo/sample/main/nvme1.txt | 3 + root/opt/phpsysinfo/sample/main/nvme2.txt | 3 + .../freeipmi1.txt} | 0 .../sample/motherboard/freeipmi/freeipmi2.txt | 28 + .../sample/motherboard/healthd/healthd1.txt | 1 + .../sample/motherboard/ipmicfg/ipmicfg1.txt | 82 + .../sample/motherboard/ipmicfg/ipmicfg2.txt | 68 + .../sample/motherboard/ipmicfg/ipmicfg3.txt | 47 + .../sample/motherboard/ipmicfg/ipmicfg4.txt | 108 + .../sample/motherboard/ipmitool/ipmitool2.txt | 356 + .../sample/motherboard/ipmitool/ipmitool3.txt | 350 + .../sample/motherboard/ipmiutil/ipmiutil1.txt | 321 +- .../motherboard/lmsensors/lmsensors11.txt | 20 + .../motherboard/lmsensors/lmsensors12.txt | 50 + .../motherboard/lmsensors/lmsensors13.txt | 39 + .../motherboard/lmsensors/lmsensors14.txt | 18 + .../motherboard/nvidiasmi/nvidiasmi0.txt | 267 + .../motherboard/nvidiasmi/nvidiasmi1.txt | 176 + .../motherboard/nvidiasmi/nvidiasmi2.txt | 277 + .../sample/openbsd/netstat_nbdi1.txt | 9 + .../sample/openbsd/netstat_nbdi2.txt | 9 + .../sample/openbsd/netstat_ndi1.txt | 9 + .../sample/openbsd/netstat_ndi2.txt | 9 + .../sample/plugin_bat/log_LenovoT530.txt | 8 + .../sample/plugin_bat/log_android233.txt | 2 + .../sample/plugin_bat/log_android412.txt | 2 + .../sample/plugin_bat/log_android422.txt | 2 + .../{log_vbox.txt => log_virtualbox.txt} | 2 + .../phpsysinfo/sample/plugin_bat/upower1.txt | 56 + .../phpsysinfo/sample/plugin_bat/upower2.txt | 83 + .../phpsysinfo/sample/plugin_bat/upower3.txt | 76 + .../phpsysinfo/sample/plugin_bat/upower4.txt | 21 + .../phpsysinfo/sample/plugin_bat/upower5.txt | 26 + .../phpsysinfo/sample/plugin_mdstat/README | 2 - .../sample/plugin_quotas/quotas2.txt | 8 + .../sample/plugin_quotas/quotas3.txt | 11 + .../sample/plugin_raid/raid3ware-status0.txt | 12 + .../sample/plugin_raid/raid3ware-status1.txt | 19 + .../raiddmraid1.txt} | 0 .../raiddmraid2.txt} | 0 .../raiddmraid3.txt} | 0 .../raiddmraid4.txt} | 0 .../raiddmraid5.txt} | 0 .../sample/plugin_raid/raidgraid1.txt | 37 + .../sample/plugin_raid/raidgraid2.txt | 41 + .../sample/plugin_raid/raididrac1.txt | 184 + .../raid1.txt => plugin_raid/raidmdstat1.txt} | 0 .../raidmdstat10.txt} | 0 .../raidmdstat11.txt} | 0 .../raidmdstat12.txt} | 0 .../sample/plugin_raid/raidmdstat13.txt | 17 + .../sample/plugin_raid/raidmdstat14.txt | 6 + .../sample/plugin_raid/raidmdstat15.txt | 9 + .../raid2.txt => plugin_raid/raidmdstat2.txt} | 0 .../raid3.txt => plugin_raid/raidmdstat3.txt} | 0 .../raid4.txt => plugin_raid/raidmdstat4.txt} | 0 .../raid5.txt => plugin_raid/raidmdstat5.txt} | 0 .../raid6.txt => plugin_raid/raidmdstat6.txt} | 0 .../raid7.txt => plugin_raid/raidmdstat7.txt} | 0 .../raid8.txt => plugin_raid/raidmdstat8.txt} | 2 +- .../raid9.txt => plugin_raid/raidmdstat9.txt} | 0 .../plugin_raid/raidmegaclisas-status1.txt | 20 + .../plugin_raid/raidmegaclisas-status2.txt | 17 + .../plugin_raid/raidmegaclisas-status3.txt | 15 + .../plugin_raid/raidmegaclisas-status4.txt | 13 + .../plugin_raid/raidmegaclisas-status5.txt | 19 + .../sample/plugin_raid/raidmegactl1.txt | 5 + .../sample/plugin_raid/raidmegactl2.txt | 9 + .../sample/plugin_raid/raidmegactl3.txt | 6 + .../sample/plugin_raid/raidmegactl4.txt | 28 + .../sample/plugin_raid/raidmegasasctl1.txt | 5 + .../sample/plugin_raid/raidmegasasctl2.txt | 4 + .../sample/plugin_raid/raidmegasasctl3.txt | 9 + .../sample/plugin_raid/raidmegasasctl4.txt | 8 + .../sample/plugin_raid/raidmegasasctl5.txt | 6 + .../sample/plugin_raid/raidmegasasctl6.txt | 9 + .../sample/plugin_raid/raidmegasasctl7.txt | 9 + .../sample/plugin_raid/raidmegasasctl8.txt | 10 + .../sample/plugin_raid/raidperccli0.txt | 569 + .../sample/plugin_raid/raidstorcli0.txt | 410 + .../sample/plugin_raid/raidstorcli1.txt | 534 + .../sample/plugin_raid/raidstorcli2.txt | 504 + .../sample/plugin_raid/raidzpool1.txt | 16 + .../sample/plugin_raid/raidzpool10.txt | 11 + .../sample/plugin_raid/raidzpool11.txt | 15 + .../sample/plugin_raid/raidzpool12.txt | 20 + .../sample/plugin_raid/raidzpool13.txt | 10 + .../sample/plugin_raid/raidzpool2.txt | 19 + .../sample/plugin_raid/raidzpool3.txt | 21 + .../sample/plugin_raid/raidzpool4.txt | 21 + .../sample/plugin_raid/raidzpool5.txt | 15 + .../sample/plugin_raid/raidzpool6.txt | 14 + .../sample/plugin_raid/raidzpool7.txt | 16 + .../sample/plugin_raid/raidzpool8.txt | 16 + .../sample/plugin_raid/raidzpool9.txt | 32 + .../phpsysinfo/sample/plugin_smart/smart1.txt | 36 +- .../phpsysinfo/sample/plugin_smart/smart2.txt | 55 + .../phpsysinfo/sample/plugin_smart/smart3.txt | 192 + .../phpsysinfo/sample/plugin_smart/smart4.txt | 42 + ...ubuntu-landscape => ubuntu-landscape1.txt} | 0 .../ubuntu-landscape2.txt | 2 + .../ubuntu-landscape3.txt | 3 + .../ubuntu-landscape4.txt | 6 + .../ubuntu-landscape5.txt | 6 + .../ubuntu-landscape6.txt | 6 + .../ubuntu-landscape7.txt | 8 + ...{universal-format => universal-format.txt} | 0 root/opt/phpsysinfo/sample/ups/1-upscl.txt | 1 - .../ups/{apcaccess1.txt => apcupsd.txt} | 0 .../{1-upscDell2700.txt => nutDell2700.txt} | 0 .../ups/{1-upscPW5110.txt => nutPW5110.txt} | 0 .../sample/{main => ups}/pmset1.txt | 0 .../sample/{main => ups}/pmset2.txt | 0 .../sample/{main => ups}/pmset3.txt | 0 .../sample/{main => ups}/pmset4.txt | 0 root/opt/phpsysinfo/sample/ups/pmset5.txt | 2 + root/opt/phpsysinfo/sample/ups/pmset6.txt | 2 + root/opt/phpsysinfo/sample/ups/pmset7.txt | 2 + .../{powersoftplus1.txt => powersoftplus.txt} | 0 root/opt/phpsysinfo/sample/ups/snmpups.txt | 16 + root/opt/phpsysinfo/templates/aqua.css | 183 +- root/opt/phpsysinfo/templates/blue.css | 108 +- root/opt/phpsysinfo/templates/blue/bar.png | Bin 1067 -> 441 bytes .../opt/phpsysinfo/templates/blue/barrest.png | Bin 0 -> 905 bytes .../opt/phpsysinfo/templates/blue/barwarn.png | Bin 974 -> 404 bytes root/opt/phpsysinfo/templates/blue/bg.png | Bin 9687 -> 9018 bytes root/opt/phpsysinfo/templates/blue/title.png | Bin 1169 -> 544 bytes root/opt/phpsysinfo/templates/clean.css | 156 +- root/opt/phpsysinfo/templates/cleansyn.css | 152 +- root/opt/phpsysinfo/templates/cream.css | 172 +- root/opt/phpsysinfo/templates/css.php | 51 + .../phpsysinfo/templates/dark_bootstrap.css | 225 + .../phpsysinfo/templates/green_bootstrap.css | 224 + .../templates/html/error_config.html | 4 +- .../phpsysinfo/templates/html/index_all.html | 20 +- .../templates/html/index_bootstrap.html | 710 +- .../templates/html/index_dynamic.html | 367 +- root/opt/phpsysinfo/templates/idash.css | 170 +- root/opt/phpsysinfo/templates/idash/bg.png | Bin 30344 -> 596 bytes .../phpsysinfo/templates/idash/htmlrest.gif | Bin 0 -> 120 bytes root/opt/phpsysinfo/templates/jstyle_blue.css | 152 +- .../opt/phpsysinfo/templates/jstyle_green.css | 212 +- root/opt/phpsysinfo/templates/lingruby.css | 169 + .../templates/lingruby/background.png | Bin 0 -> 23204 bytes .../phpsysinfo/templates/misc/emptyfile.css | 0 root/opt/phpsysinfo/templates/nextgen.css | 165 +- .../templates/nextgen/nextgen_bg.png | Bin 30250 -> 600 bytes root/opt/phpsysinfo/templates/phpsysinfo.css | 158 +- .../templates/phpsysinfo_bootstrap.css | 194 +- .../templates/plugin/jquery.dataTables.css | 6 +- .../templates/plugin/nyroModal.full.css | 5 +- root/opt/phpsysinfo/templates/schabau.css | 183 + .../templates/schabau_bootstrap.css | 233 + root/opt/phpsysinfo/templates/two.css | 132 +- .../templates/vendor/bootstrap-chrome25.css | 73 + .../templates/vendor/bootstrap-chrome28.css | 70 + .../templates/vendor/bootstrap-firefox15.css | 76 + .../templates/vendor/bootstrap-firefox20.css | 73 + .../templates/vendor/bootstrap-firefox27.css | 78 + .../templates/vendor/bootstrap-firefox28.css | 3 + .../templates/vendor/bootstrap-ie8.css | 481 + .../templates/vendor/bootstrap-ie9.css | 244 + .../templates/vendor/bootstrap-midori04.css | 73 + .../templates/vendor/bootstrap-midori05.css | 70 + .../templates/vendor/bootstrap-opera11.css | 70 + .../templates/vendor/bootstrap-safari5.css | 73 + .../templates/vendor/bootstrap-safari8.css | 70 + .../templates/vendor/bootstrap-webapp.css | 15 + .../templates/vendor/bootstrap.min.css | 7 +- root/opt/phpsysinfo/tools/MakeRelease.sh | 32 - root/opt/phpsysinfo/tools/README | 9 +- root/opt/phpsysinfo/tools/aptana/js.xml | 43 - root/opt/phpsysinfo/tools/aptana/php.xml | 90 - root/opt/phpsysinfo/tools/check.sh | 15 - root/opt/phpsysinfo/tools/checkdistro.php | 237 +- root/opt/phpsysinfo/tools/checkpng.php | 79 + root/opt/phpsysinfo/tools/cputest.php | 12 + root/opt/phpsysinfo/tools/distrotest.php | 16 +- root/opt/phpsysinfo/tools/lint.bat | 10 - root/opt/phpsysinfo/tools/phptest.php | 72 + .../tools/speedfan/SpeedFanGet_bin.zip | Bin 0 -> 2649 bytes .../tools/speedfan/SpeedFanGet_src.zip | Bin 0 -> 1242 bytes root/opt/phpsysinfo/xml.php | 53 +- .../lib/SrvMngr/Controller/Phpsysinfo.pm | 52 + .../I18N/Modules/Phpsysinfo/phpsysinfo_en.lex | 2 + .../default/templates/phpsysinfo.html.ep | 24 + smeserver-phpsysinfo-3.2.3.tar.xz | Bin 634556 -> 0 bytes smeserver-phpsysinfo.spec | 11 +- 952 files changed, 51341 insertions(+), 28699 deletions(-) create mode 100644 root/opt/phpsysinfo/.browserslistrc-bootstrap create mode 100644 root/opt/phpsysinfo/.browserslistrc-dynamic create mode 100644 root/opt/phpsysinfo/.browserslistrc-static create mode 100644 root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md create mode 100644 root/opt/phpsysinfo/.github/CONTRIBUTING.md create mode 100644 root/opt/phpsysinfo/.github/FUNDING.yml create mode 100644 root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md create mode 100644 root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 root/opt/phpsysinfo/.github/workflows/phplint.yml delete mode 100644 root/opt/phpsysinfo/.travis.yml create mode 100644 root/opt/phpsysinfo/SECURITY.md create mode 100644 root/opt/phpsysinfo/data/.htaccess create mode 100644 root/opt/phpsysinfo/data/cpus.ini create mode 100644 root/opt/phpsysinfo/data/raspberry.ini create mode 100644 root/opt/phpsysinfo/gfx/attention.gif delete mode 100644 root/opt/phpsysinfo/gfx/attention.png create mode 100644 root/opt/phpsysinfo/gfx/blank.gif create mode 100644 root/opt/phpsysinfo/gfx/body.gif delete mode 100644 root/opt/phpsysinfo/gfx/body.png create mode 100644 root/opt/phpsysinfo/gfx/bullet_toggle_minus.gif delete mode 100644 root/opt/phpsysinfo/gfx/bullet_toggle_minus.png create mode 100644 root/opt/phpsysinfo/gfx/bullet_toggle_plus.gif delete mode 100644 root/opt/phpsysinfo/gfx/bullet_toggle_plus.png create mode 100644 root/opt/phpsysinfo/gfx/down_black.gif create mode 100644 root/opt/phpsysinfo/gfx/down_gray.gif create mode 100644 root/opt/phpsysinfo/gfx/favicon.gif delete mode 100644 root/opt/phpsysinfo/gfx/favicon.png create mode 100644 root/opt/phpsysinfo/gfx/htmlrest.gif create mode 100644 root/opt/phpsysinfo/gfx/images/Absolute.png create mode 100644 root/opt/phpsysinfo/gfx/images/Alma.png create mode 100644 root/opt/phpsysinfo/gfx/images/Archcraft.png create mode 100644 root/opt/phpsysinfo/gfx/images/Archman.png create mode 100644 root/opt/phpsysinfo/gfx/images/Arco.png create mode 100644 root/opt/phpsysinfo/gfx/images/Armbian.png create mode 100644 root/opt/phpsysinfo/gfx/images/Artix.png create mode 100644 root/opt/phpsysinfo/gfx/images/BigLinux.png create mode 100644 root/opt/phpsysinfo/gfx/images/Bluestar.png create mode 100644 root/opt/phpsysinfo/gfx/images/Bodhi.png create mode 100644 root/opt/phpsysinfo/gfx/images/CachyOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Clear.png create mode 100644 root/opt/phpsysinfo/gfx/images/Container.png create mode 100644 root/opt/phpsysinfo/gfx/images/Devuan.png create mode 100644 root/opt/phpsysinfo/gfx/images/DrayOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/EasyOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Elive.png create mode 100644 root/opt/phpsysinfo/gfx/images/EndeavourOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Endless.png create mode 100644 root/opt/phpsysinfo/gfx/images/EuroLinux.png create mode 100644 root/opt/phpsysinfo/gfx/images/ExTiX.png create mode 100644 root/opt/phpsysinfo/gfx/images/Exherbo.png create mode 100644 root/opt/phpsysinfo/gfx/images/Fatdog.png create mode 100644 root/opt/phpsysinfo/gfx/images/Feren.png create mode 100644 root/opt/phpsysinfo/gfx/images/FortiOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/FreeEOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/FreeNAS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Garuda.png create mode 100644 root/opt/phpsysinfo/gfx/images/Gnoppix.png create mode 100644 root/opt/phpsysinfo/gfx/images/Guix.png create mode 100644 root/opt/phpsysinfo/gfx/images/HipServ.png create mode 100644 root/opt/phpsysinfo/gfx/images/Hurd.png create mode 100644 root/opt/phpsysinfo/gfx/images/IYCC.png create mode 100644 root/opt/phpsysinfo/gfx/images/JingOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/KDEneon.png create mode 100644 root/opt/phpsysinfo/gfx/images/Kaisen.png create mode 100644 root/opt/phpsysinfo/gfx/images/Kali.png create mode 100644 root/opt/phpsysinfo/gfx/images/Kodachi.png create mode 100644 root/opt/phpsysinfo/gfx/images/LXLE.png create mode 100644 root/opt/phpsysinfo/gfx/images/Laclin.png create mode 100644 root/opt/phpsysinfo/gfx/images/Lakka.png create mode 100644 root/opt/phpsysinfo/gfx/images/LibreELEC.png create mode 100644 root/opt/phpsysinfo/gfx/images/Linspire.png create mode 100644 root/opt/phpsysinfo/gfx/images/Linux.png create mode 100644 root/opt/phpsysinfo/gfx/images/LinuxLite.png create mode 100644 root/opt/phpsysinfo/gfx/images/Linuxfx.png create mode 100644 root/opt/phpsysinfo/gfx/images/MX.png create mode 100644 root/opt/phpsysinfo/gfx/images/Mabox.png create mode 100644 root/opt/phpsysinfo/gfx/images/Makulu.png create mode 100644 root/opt/phpsysinfo/gfx/images/Milis.png create mode 100644 root/opt/phpsysinfo/gfx/images/NeoKylin.png create mode 100644 root/opt/phpsysinfo/gfx/images/Neptune.png create mode 100644 root/opt/phpsysinfo/gfx/images/NethServer.png create mode 100644 root/opt/phpsysinfo/gfx/images/NexentaStor.png create mode 100644 root/opt/phpsysinfo/gfx/images/Nitrux.png create mode 100644 root/opt/phpsysinfo/gfx/images/Nobara.png create mode 100644 root/opt/phpsysinfo/gfx/images/NuTyX.png create mode 100644 root/opt/phpsysinfo/gfx/images/Omarine.png create mode 100644 root/opt/phpsysinfo/gfx/images/OmniOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/OpenELEC.png create mode 100644 root/opt/phpsysinfo/gfx/images/OpenIndiana.png create mode 100644 root/opt/phpsysinfo/gfx/images/OpenMamba.png create mode 100644 root/opt/phpsysinfo/gfx/images/OpenSolaris.png create mode 100644 root/opt/phpsysinfo/gfx/images/OpenWRT.png create mode 100644 root/opt/phpsysinfo/gfx/images/Parrot.png create mode 100644 root/opt/phpsysinfo/gfx/images/Photon.png create mode 100644 root/opt/phpsysinfo/gfx/images/Plop.png create mode 100644 root/opt/phpsysinfo/gfx/images/Pop.png create mode 100644 root/opt/phpsysinfo/gfx/images/Proxmox.png create mode 100644 root/opt/phpsysinfo/gfx/images/PureOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Q4OS.png create mode 100644 root/opt/phpsysinfo/gfx/images/QTS.png create mode 100644 root/opt/phpsysinfo/gfx/images/QuemOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/RebeccaBlackOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/RebornOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Redcore.png create mode 100644 root/opt/phpsysinfo/gfx/images/Regata.png create mode 100644 root/opt/phpsysinfo/gfx/images/RoboLinux.png create mode 100644 root/opt/phpsysinfo/gfx/images/Rocky.png create mode 100644 root/opt/phpsysinfo/gfx/images/Runtu.png create mode 100644 root/opt/phpsysinfo/gfx/images/SalentOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Septor.png create mode 100644 root/opt/phpsysinfo/gfx/images/Siduction.png create mode 100644 root/opt/phpsysinfo/gfx/images/SmartOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Snal.png create mode 100644 root/opt/phpsysinfo/gfx/images/Solaris.png create mode 100644 root/opt/phpsysinfo/gfx/images/Solus.png create mode 100644 root/opt/phpsysinfo/gfx/images/Sparky.png create mode 100644 root/opt/phpsysinfo/gfx/images/Springdale.png create mode 100644 root/opt/phpsysinfo/gfx/images/TrueNAS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Tuxedo.png create mode 100644 root/opt/phpsysinfo/gfx/images/UOS.png create mode 100644 root/opt/phpsysinfo/gfx/images/Ultramarine.png create mode 100644 root/opt/phpsysinfo/gfx/images/Uruk.png create mode 100644 root/opt/phpsysinfo/gfx/images/Vanilla.png create mode 100644 root/opt/phpsysinfo/gfx/images/Venom.png create mode 100644 root/opt/phpsysinfo/gfx/images/Virtuozzo.png create mode 100644 root/opt/phpsysinfo/gfx/images/Void.png create mode 100644 root/opt/phpsysinfo/gfx/images/WINNT.png create mode 100644 root/opt/phpsysinfo/gfx/images/Win11.png create mode 100644 root/opt/phpsysinfo/gfx/images/XeroLinux.png create mode 100644 root/opt/phpsysinfo/gfx/images/dahliaOS.png delete mode 100644 root/opt/phpsysinfo/gfx/images/free-eos.png delete mode 100644 root/opt/phpsysinfo/gfx/images/iycc.png create mode 100644 root/opt/phpsysinfo/gfx/images/openEuler.png create mode 100644 root/opt/phpsysinfo/gfx/images/risiOS.png create mode 100644 root/opt/phpsysinfo/gfx/logo_32.gif delete mode 100644 root/opt/phpsysinfo/gfx/logo_48.png create mode 100644 root/opt/phpsysinfo/gfx/next.gif delete mode 100644 root/opt/phpsysinfo/gfx/next.png create mode 100644 root/opt/phpsysinfo/gfx/prev.gif delete mode 100644 root/opt/phpsysinfo/gfx/prev.png create mode 100644 root/opt/phpsysinfo/gfx/reload.gif delete mode 100644 root/opt/phpsysinfo/gfx/reload.png create mode 100644 root/opt/phpsysinfo/gfx/right_black.gif create mode 100644 root/opt/phpsysinfo/gfx/right_gray.gif create mode 100644 root/opt/phpsysinfo/gfx/sort_asc.gif delete mode 100644 root/opt/phpsysinfo/gfx/sort_asc.png create mode 100644 root/opt/phpsysinfo/gfx/sort_both.gif delete mode 100644 root/opt/phpsysinfo/gfx/sort_both.png create mode 100644 root/opt/phpsysinfo/gfx/sort_desc.gif delete mode 100644 root/opt/phpsysinfo/gfx/sort_desc.png rename root/opt/phpsysinfo/includes/error/{class.Error.inc.php => class.PSI_Error.inc.php} (87%) delete mode 100644 root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php delete mode 100644 root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php create mode 100644 root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php create mode 100644 root/opt/phpsysinfo/includes/os/class.GNU.inc.php create mode 100644 root/opt/phpsysinfo/includes/os/class.SSH.inc.php create mode 100644 root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php delete mode 100644 root/opt/phpsysinfo/js/jQuery/jquery-1.js create mode 100644 root/opt/phpsysinfo/js/jQuery/jquery.ifixpng.js rename root/opt/phpsysinfo/js/jQuery/{jquery.timers.js => jquery.timer.js} (94%) create mode 100644 root/opt/phpsysinfo/js/vendor/bootstrap-ie8.js create mode 100644 root/opt/phpsysinfo/js/vendor/bootstrap-ie9.js create mode 100644 root/opt/phpsysinfo/js/vendor/bootstrap-modal.js create mode 100644 root/opt/phpsysinfo/js/vendor/bootstrap-util.js delete mode 100644 root/opt/phpsysinfo/js/vendor/bootstrap.min.js delete mode 100644 root/opt/phpsysinfo/js/vendor/sorttable_org.js create mode 100644 root/opt/phpsysinfo/language/ar.xml create mode 100644 root/opt/phpsysinfo/language/fa.xml create mode 100644 root/opt/phpsysinfo/language/hr.xml create mode 100644 root/opt/phpsysinfo/language/id.xml create mode 100644 root/opt/phpsysinfo/plugins/bat/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/diskload/class.diskload.inc.php create mode 100644 root/opt/phpsysinfo/plugins/diskload/diskload_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/diskload/js/diskload.js create mode 100644 root/opt/phpsysinfo/plugins/diskload/js/diskload_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/diskload/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/diskload/lang/pl.xml delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/class.dmraid.inc.php delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/css/dmraid.css delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/dmraid_bootstrap.html delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/gfx/harddrivespare.png delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/gfx/harddrivewarn.png delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/js/dmraid.js delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/js/dmraid_bootstrap.js delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/lang/en.xml delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/lang/fr.xml delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/lang/ro.xml delete mode 100644 root/opt/phpsysinfo/plugins/dmraid/lang/ru.xml create mode 100644 root/opt/phpsysinfo/plugins/docker/class.docker.inc.php create mode 100644 root/opt/phpsysinfo/plugins/docker/docker_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/docker/js/docker.js create mode 100644 root/opt/phpsysinfo/plugins/docker/js/docker_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/docker/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/docker/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/docker/lang/pl.xml create mode 100644 root/opt/phpsysinfo/plugins/hyperv/class.hyperv.inc.php create mode 100644 root/opt/phpsysinfo/plugins/hyperv/css/hyperv.css create mode 100644 root/opt/phpsysinfo/plugins/hyperv/gfx/offline.gif create mode 100644 root/opt/phpsysinfo/plugins/hyperv/gfx/online.gif create mode 100644 root/opt/phpsysinfo/plugins/hyperv/hyperv_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/hyperv/js/hyperv.js create mode 100644 root/opt/phpsysinfo/plugins/hyperv/js/hyperv_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/hyperv/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/hyperv/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/hyperv/lang/pl.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/class.ipmiinfo.inc.php delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/ipmiinfo_bootstrap.html delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/js/ipmiinfo.js delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/js/ipmiinfo_bootstrap.js delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/cz.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/de.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/en.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/fr.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/pl.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/ro.xml delete mode 100644 root/opt/phpsysinfo/plugins/ipmiinfo/lang/ru.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/class.mdstatus.inc.php delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/css/mdstatus.css delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/gfx/error.png delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/gfx/harddrivefail.png delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/gfx/harddriveok.png delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/gfx/harddrivespare.png delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/js/mdstatus.js delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/js/mdstatus_bootstrap.js delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/cz.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/de.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/en.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/fr.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/gr.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/ro.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/lang/ru.xml delete mode 100644 root/opt/phpsysinfo/plugins/mdstatus/mdstatus_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/pingtest/class.pingtest.inc.php create mode 100644 root/opt/phpsysinfo/plugins/pingtest/css/pingtest.css create mode 100644 root/opt/phpsysinfo/plugins/pingtest/js/pingtest.js create mode 100644 root/opt/phpsysinfo/plugins/pingtest/js/pingtest_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/pingtest/lang/cz.xml create mode 100644 root/opt/phpsysinfo/plugins/pingtest/lang/de.xml create mode 100644 root/opt/phpsysinfo/plugins/pingtest/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/pingtest/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/pingtest/lang/pl.xml create mode 100644 root/opt/phpsysinfo/plugins/pingtest/pingtest_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/ps/lang/uk.xml create mode 100644 root/opt/phpsysinfo/plugins/psstatus/gfx/offline.gif delete mode 100644 root/opt/phpsysinfo/plugins/psstatus/gfx/offline.png create mode 100644 root/opt/phpsysinfo/plugins/psstatus/gfx/online.gif delete mode 100644 root/opt/phpsysinfo/plugins/psstatus/gfx/online.png create mode 100644 root/opt/phpsysinfo/plugins/psstatus/lang/uk.xml create mode 100644 root/opt/phpsysinfo/plugins/quotas/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/class.raid.inc.php create mode 100644 root/opt/phpsysinfo/plugins/raid/css/raid.css rename root/opt/phpsysinfo/plugins/{dmraid => raid}/gfx/error.png (100%) rename root/opt/phpsysinfo/plugins/{dmraid => raid}/gfx/harddrivefail.png (100%) rename root/opt/phpsysinfo/plugins/{dmraid => raid}/gfx/harddriveok.png (100%) create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/harddrivespare.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/harddriveunc.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/harddrivewarn.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/soliddrivefail.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/soliddriveok.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/soliddrivespare.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/soliddriveunc.png create mode 100644 root/opt/phpsysinfo/plugins/raid/gfx/soliddrivewarn.png create mode 100644 root/opt/phpsysinfo/plugins/raid/js/raid.js create mode 100644 root/opt/phpsysinfo/plugins/raid/js/raid_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/cz.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/de.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/fr.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/ro.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/lang/ru.xml create mode 100644 root/opt/phpsysinfo/plugins/raid/raid_bootstrap.html delete mode 100644 root/opt/phpsysinfo/plugins/smart/lang/ru.xml create mode 100644 root/opt/phpsysinfo/plugins/snmppinfo/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/stablebit/class.stablebit.inc.php create mode 100644 root/opt/phpsysinfo/plugins/stablebit/gfx/off.gif create mode 100644 root/opt/phpsysinfo/plugins/stablebit/gfx/on.gif create mode 100644 root/opt/phpsysinfo/plugins/stablebit/js/stablebit.js create mode 100644 root/opt/phpsysinfo/plugins/stablebit/js/stablebit_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/stablebit/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/stablebit/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/stablebit/stablebit_bootstrap.html create mode 100644 root/opt/phpsysinfo/plugins/updatenotifier/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/uprecords/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/viewer/class.viewer.inc.php create mode 100644 root/opt/phpsysinfo/plugins/viewer/js/viewer.js create mode 100644 root/opt/phpsysinfo/plugins/viewer/js/viewer_bootstrap.js create mode 100644 root/opt/phpsysinfo/plugins/viewer/lang/en.xml create mode 100644 root/opt/phpsysinfo/plugins/viewer/lang/gr.xml create mode 100644 root/opt/phpsysinfo/plugins/viewer/lang/pl.xml create mode 100644 root/opt/phpsysinfo/plugins/viewer/viewer_bootstrap.html create mode 100644 root/opt/phpsysinfo/sample/aix/prtconf1.txt create mode 100644 root/opt/phpsysinfo/sample/aix/prtconf2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Absolute/15.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Alma/8.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Amazon/2016.09.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Arch/2017.03.07-ARM.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Archcraft/2023.01.01.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Archman/2022-07.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Arco/22.01.10_l.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Armbian/23.02.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Artix/20210726.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/BigLinux/19.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/BigLinux/20.04_RC1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/BigLinux/2023-04-11_15-10.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/BigLinux/7.10.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Bluestar/5.16.15.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Bodhi/6.0.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/CachyOS/221230.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/CentOS/Stream-8.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Clear/35000.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Cloud/7.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Container/1409.2.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Deepin/20.08.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Deepin/23-alpha2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Devuan/1.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EasyOS/0.6.8.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EasyOS/0.9.4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EasyOS/1.2.9.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EasyOS/2.1.11.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Eisfair/1-2.6.5.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Eisfair/64-2.8.25.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Elive/3.8.30.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EndeavourOS/21.4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Endless/3.3.16.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/EuroLinux/8.4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/ExTiX/22.12.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Exherbo/2019.09.08.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Fatdog/813.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Feren/2020.07.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/FreeEOS/1.3.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Garuda/220106.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Gnoppix/22.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Guix/1.4.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/HipServ/2.6.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/JingOS/0.8.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/KDEneon/5.21.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Kaisen/2.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Kali/2018.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Kodachi/18.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/LXLE/20.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Laclin/1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Lakka/2.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/LibreELEC/8.0.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Linspire/12.0.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/LinuxLite/6.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Linuxfx/11.1.1103.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/MX/17.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Mabox/21.02.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Makulu/2021.12.15.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Manjaro/21.12-arm.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Milis/2.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Mint/20.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Mint/LMDE_5.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/NeoKylin/6.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Neptune/7.5.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/NethServer/7.9.2009.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Nitrux/2.0.0-280122.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Nobara/37.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/NuTyX/10.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Omarine/7.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/OpenELEC/8.0.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/OpenMamba/3.0.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/OpenWRT/22.03.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Parrot/5.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Parsix/8.15.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Pear/11.1.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Photon/5.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Plop/23.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Pop/21.10.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Proxmox/8.0.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Puppy/22.12.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/PureOS/10.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/PureOS/3.0beta1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Q4OS/3.16.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/QTS/3.1.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/QuemOS/1.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/RebeccaBlackOS/20230116.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/RebornOS/2022.04.10.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/RedHat/7.5.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Redcore/1803.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Regata/22.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/RoboLinux/20.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Rocky/8.3-RC1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Rocky/8.4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Runtu/22.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/SMEServer/10.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/SUSE/12.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/SalentOS/1.0.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Septor/2021.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Siduction/22.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Slackware/8.1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/SliTaz/5.0-RC4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Snal/1.24.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Solus/1.0-rc1.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Solus/2017.01.01.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Sparky/6.5.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Springdale/6.9.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Springdale/7.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Tuxedo/22.04.2.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/UOS/20.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Ubuntu/20.04.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Ultramarine/36.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Uruk/3.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Vanilla/22.10.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Venom/4.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Virtuozzo/8.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/Void/1.0-20160420.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/XeroLinux/2022.12.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/dahliaOS/220222.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/elementaryOS/0.4.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/elementaryOS/6.0.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/openEuler/22.09.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/openSUSE/20211111.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/openSUSE/42.3.txt create mode 100644 root/opt/phpsysinfo/sample/distrotest/risiOS/37.txt create mode 100644 root/opt/phpsysinfo/sample/forti/execute_sensor_list0.txt create mode 100644 root/opt/phpsysinfo/sample/forti/execute_sensor_list1.txt create mode 100644 root/opt/phpsysinfo/sample/freebsd/netstat1.txt create mode 100644 root/opt/phpsysinfo/sample/freebsd/netstat2.txt create mode 100644 root/opt/phpsysinfo/sample/freebsd/netstat3.txt delete mode 100644 root/opt/phpsysinfo/sample/logs/log_android21.txt delete mode 100644 root/opt/phpsysinfo/sample/logs/log_android412.txt delete mode 100644 root/opt/phpsysinfo/sample/logs/log_bluestacks.txt delete mode 100644 root/opt/phpsysinfo/sample/logs/log_debian7.txt delete mode 100644 root/opt/phpsysinfo/sample/logs/log_sf.txt delete mode 100644 root/opt/phpsysinfo/sample/main/1-cpuinfo.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo10.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo11.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo12.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo13.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo14.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo15.txt create mode 100644 root/opt/phpsysinfo/sample/main/cpuinfo16.txt rename root/opt/phpsysinfo/sample/main/{df1.txt => dfP1.txt} (100%) rename root/opt/phpsysinfo/sample/main/{1-dfiP.txt => dfiP1.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/main/dfk1.txt rename root/opt/phpsysinfo/sample/main/{1-dfkP.txt => dfkP1.txt} (100%) rename root/opt/phpsysinfo/sample/main/{1-mount.txt => mount2.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/main/nvme1.txt create mode 100644 root/opt/phpsysinfo/sample/main/nvme2.txt rename root/opt/phpsysinfo/sample/motherboard/{ipmi-sensors/ipmi-sensors1.txt => freeipmi/freeipmi1.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/motherboard/freeipmi/freeipmi2.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/healthd/healthd1.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmicfg/ipmicfg1.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmicfg/ipmicfg2.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmicfg/ipmicfg3.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmicfg/ipmicfg4.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmitool/ipmitool2.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/ipmitool/ipmitool3.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/lmsensors/lmsensors11.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/lmsensors/lmsensors12.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/lmsensors/lmsensors13.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/lmsensors/lmsensors14.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/nvidiasmi/nvidiasmi0.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/nvidiasmi/nvidiasmi1.txt create mode 100644 root/opt/phpsysinfo/sample/motherboard/nvidiasmi/nvidiasmi2.txt create mode 100644 root/opt/phpsysinfo/sample/openbsd/netstat_nbdi1.txt create mode 100644 root/opt/phpsysinfo/sample/openbsd/netstat_nbdi2.txt create mode 100644 root/opt/phpsysinfo/sample/openbsd/netstat_ndi1.txt create mode 100644 root/opt/phpsysinfo/sample/openbsd/netstat_ndi2.txt rename root/opt/phpsysinfo/sample/plugin_bat/{log_vbox.txt => log_virtualbox.txt} (93%) create mode 100644 root/opt/phpsysinfo/sample/plugin_bat/upower1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_bat/upower2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_bat/upower3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_bat/upower4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_bat/upower5.txt delete mode 100644 root/opt/phpsysinfo/sample/plugin_mdstat/README create mode 100644 root/opt/phpsysinfo/sample/plugin_quotas/quotas2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_quotas/quotas3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raid3ware-status0.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raid3ware-status1.txt rename root/opt/phpsysinfo/sample/{plugin_dmraid/dmraid1.txt => plugin_raid/raiddmraid1.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_dmraid/dmraid2.txt => plugin_raid/raiddmraid2.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_dmraid/dmraid3.txt => plugin_raid/raiddmraid3.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_dmraid/dmraid4.txt => plugin_raid/raiddmraid4.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_dmraid/dmraid5.txt => plugin_raid/raiddmraid5.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidgraid1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidgraid2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raididrac1.txt rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid1.txt => plugin_raid/raidmdstat1.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid10.txt => plugin_raid/raidmdstat10.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid11.txt => plugin_raid/raidmdstat11.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid12.txt => plugin_raid/raidmdstat12.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmdstat13.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmdstat14.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmdstat15.txt rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid2.txt => plugin_raid/raidmdstat2.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid3.txt => plugin_raid/raidmdstat3.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid4.txt => plugin_raid/raidmdstat4.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid5.txt => plugin_raid/raidmdstat5.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid6.txt => plugin_raid/raidmdstat6.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid7.txt => plugin_raid/raidmdstat7.txt} (100%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid8.txt => plugin_raid/raidmdstat8.txt} (89%) rename root/opt/phpsysinfo/sample/{plugin_mdstat/raid9.txt => plugin_raid/raidmdstat9.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegaclisas-status1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegaclisas-status2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegaclisas-status3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegaclisas-status4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegaclisas-status5.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegactl1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegactl2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegactl3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegactl4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl5.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl6.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl7.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidmegasasctl8.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidperccli0.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidstorcli0.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidstorcli1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidstorcli2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool1.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool10.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool11.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool12.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool13.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool5.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool6.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool7.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool8.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_raid/raidzpool9.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_smart/smart2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_smart/smart3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_smart/smart4.txt rename root/opt/phpsysinfo/sample/plugin_updatenotifier/{ubuntu-landscape => ubuntu-landscape1.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape2.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape3.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape4.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape5.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape6.txt create mode 100644 root/opt/phpsysinfo/sample/plugin_updatenotifier/ubuntu-landscape7.txt rename root/opt/phpsysinfo/sample/plugin_updatenotifier/{universal-format => universal-format.txt} (100%) delete mode 100644 root/opt/phpsysinfo/sample/ups/1-upscl.txt rename root/opt/phpsysinfo/sample/ups/{apcaccess1.txt => apcupsd.txt} (100%) rename root/opt/phpsysinfo/sample/ups/{1-upscDell2700.txt => nutDell2700.txt} (100%) rename root/opt/phpsysinfo/sample/ups/{1-upscPW5110.txt => nutPW5110.txt} (100%) rename root/opt/phpsysinfo/sample/{main => ups}/pmset1.txt (100%) rename root/opt/phpsysinfo/sample/{main => ups}/pmset2.txt (100%) rename root/opt/phpsysinfo/sample/{main => ups}/pmset3.txt (100%) rename root/opt/phpsysinfo/sample/{main => ups}/pmset4.txt (100%) create mode 100644 root/opt/phpsysinfo/sample/ups/pmset5.txt create mode 100644 root/opt/phpsysinfo/sample/ups/pmset6.txt create mode 100644 root/opt/phpsysinfo/sample/ups/pmset7.txt rename root/opt/phpsysinfo/sample/ups/{powersoftplus1.txt => powersoftplus.txt} (100%) create mode 100644 root/opt/phpsysinfo/sample/ups/snmpups.txt create mode 100644 root/opt/phpsysinfo/templates/blue/barrest.png create mode 100644 root/opt/phpsysinfo/templates/css.php create mode 100644 root/opt/phpsysinfo/templates/dark_bootstrap.css create mode 100644 root/opt/phpsysinfo/templates/green_bootstrap.css create mode 100644 root/opt/phpsysinfo/templates/idash/htmlrest.gif create mode 100644 root/opt/phpsysinfo/templates/lingruby.css create mode 100644 root/opt/phpsysinfo/templates/lingruby/background.png create mode 100644 root/opt/phpsysinfo/templates/misc/emptyfile.css create mode 100644 root/opt/phpsysinfo/templates/schabau.css create mode 100644 root/opt/phpsysinfo/templates/schabau_bootstrap.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-chrome25.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-chrome28.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-firefox15.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-firefox20.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-firefox27.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-firefox28.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-ie8.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-ie9.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-midori04.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-midori05.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-opera11.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-safari5.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-safari8.css create mode 100644 root/opt/phpsysinfo/templates/vendor/bootstrap-webapp.css delete mode 100755 root/opt/phpsysinfo/tools/MakeRelease.sh delete mode 100644 root/opt/phpsysinfo/tools/aptana/js.xml delete mode 100644 root/opt/phpsysinfo/tools/aptana/php.xml delete mode 100755 root/opt/phpsysinfo/tools/check.sh create mode 100644 root/opt/phpsysinfo/tools/checkpng.php create mode 100644 root/opt/phpsysinfo/tools/cputest.php delete mode 100644 root/opt/phpsysinfo/tools/lint.bat create mode 100644 root/opt/phpsysinfo/tools/phptest.php create mode 100644 root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_bin.zip create mode 100644 root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_src.zip create mode 100644 root/usr/share/smanager/lib/SrvMngr/Controller/Phpsysinfo.pm create mode 100644 root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Phpsysinfo/phpsysinfo_en.lex create mode 100644 root/usr/share/smanager/themes/default/templates/phpsysinfo.html.ep delete mode 100644 smeserver-phpsysinfo-3.2.3.tar.xz diff --git a/.gitignore b/.gitignore index cbb3a13..c03592a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.rpm *.log *spec-20* +*.tar.xz *.tar.gz diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias index 86a6212..f32da1c 100644 --- a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias +++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias @@ -4,13 +4,12 @@ Alias /phpsysinfo /opt/phpsysinfo SSLRequireSSL Options -Indexes - AuthName "phpSysInfo" - AuthBasicProvider external - AuthType Basic - AuthExternal pwauth + #AuthName "phpSysInfo" + #AuthBasicProvider external + #AuthType Basic + #AuthExternal pwauth - Require user admin Require {(($phpmyadmin{access} || 'private' ) eq "public" ) ? "all granted": "ip $localAccess $externalSSLAccess";} @@ -19,5 +18,4 @@ Alias /phpsysinfo /opt/phpsysinfo SetHandler "proxy:unix:/var/run/php-fpm/php.sock|fcgi://localhost" - - + \ No newline at end of file diff --git a/root/opt/phpsysinfo/.browserslistrc-bootstrap b/root/opt/phpsysinfo/.browserslistrc-bootstrap new file mode 100644 index 0000000..a48549c --- /dev/null +++ b/root/opt/phpsysinfo/.browserslistrc-bootstrap @@ -0,0 +1,6 @@ +Explorer >= 8 +Firefox >= 3.6 +Sarafi >= 5.1 +Chrome >= 25 +Edge >= 12 +Opera >= 11 diff --git a/root/opt/phpsysinfo/.browserslistrc-dynamic b/root/opt/phpsysinfo/.browserslistrc-dynamic new file mode 100644 index 0000000..2c42c69 --- /dev/null +++ b/root/opt/phpsysinfo/.browserslistrc-dynamic @@ -0,0 +1,6 @@ +Explorer >= 6 +Firefox >= 1.5 +Sarafi >= 5.1 +Chrome >= 1 +Edge >= 12 +Opera >= 11 diff --git a/root/opt/phpsysinfo/.browserslistrc-static b/root/opt/phpsysinfo/.browserslistrc-static new file mode 100644 index 0000000..34adc86 --- /dev/null +++ b/root/opt/phpsysinfo/.browserslistrc-static @@ -0,0 +1 @@ +>= 0% diff --git a/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md b/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..66eb307 --- /dev/null +++ b/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [phpsysinfo@yahoo.com](mailto:phpsysinfo@yahoo.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/root/opt/phpsysinfo/.github/CONTRIBUTING.md b/root/opt/phpsysinfo/.github/CONTRIBUTING.md new file mode 100644 index 0000000..c6e3f84 --- /dev/null +++ b/root/opt/phpsysinfo/.github/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contributing to phpSysInfo +First time contributing to phpSysInfo? Read our [Code of Conduct](https://github.com/phpsysinfo/phpsysinfo/blob/main/CODE_OF_CONDUCT.md). + +### Propose a feature + +If you have a great idea or want to help out, just create a pull request with your change proposal +in the [phpSysInfo](https://github.com/phpsysinfo/phpsysinfo) repository. diff --git a/root/opt/phpsysinfo/.github/FUNDING.yml b/root/opt/phpsysinfo/.github/FUNDING.yml new file mode 100644 index 0000000..e95f376 --- /dev/null +++ b/root/opt/phpsysinfo/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: [https://phpsysinfo.github.io/phpsysinfo/] diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a0f79af --- /dev/null +++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,41 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. + +***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini` +and include any error messages in your bug report / help request !!*** diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000..48d5f81 --- /dev/null +++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md b/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7973f9c --- /dev/null +++ b/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +### Summary ### + + +### Types of changes ### + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +### Code Preparation ### + + +- [ ] Check for unused code +- [ ] No unrelated changes are included +- [ ] None of the changed files are reformatting only +- [ ] Code is self explanatory or documented +- [ ] All written text is properly translated (english language) diff --git a/root/opt/phpsysinfo/.github/workflows/phplint.yml b/root/opt/phpsysinfo/.github/workflows/phplint.yml new file mode 100644 index 0000000..f6d7626 --- /dev/null +++ b/root/opt/phpsysinfo/.github/workflows/phplint.yml @@ -0,0 +1,38 @@ +name: PHP Linting + +jobs: + phplint: + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: PHP Lint 5.4 + uses: prestashop/github-action-php-lint/5.4@v2.1 + - name: PHP Lint 5.5 + uses: prestashop/github-action-php-lint/5.5@v2.1 + - name: PHP Lint 5.6 + uses: prestashop/github-action-php-lint/5.6@v2.1 + - name: PHP Lint 7.1 + uses: prestashop/github-action-php-lint/7.1@v2.1 + - name: PHP Lint 7.2 + uses: prestashop/github-action-php-lint/7.2@v2.1 + - name: PHP Lint 7.3 + uses: prestashop/github-action-php-lint/7.3@v2.1 + - name: PHP Lint 7.4 + uses: prestashop/github-action-php-lint/7.4@v2.1 + - name: PHP Lint 8.0 + uses: prestashop/github-action-php-lint/8.0@v2.1 + - name: PHP Lint 8.1 + uses: prestashop/github-action-php-lint/8.1@v2.1 + - name: PHP Lint 8.2 + uses: prestashop/github-action-php-lint/8.2@v2.1 + +on: + push: + branches: + - main + - stable diff --git a/root/opt/phpsysinfo/.gitignore b/root/opt/phpsysinfo/.gitignore index dbb8d5e..7c76f68 100644 --- a/root/opt/phpsysinfo/.gitignore +++ b/root/opt/phpsysinfo/.gitignore @@ -1 +1,2 @@ phpsysinfo.ini +composer.lock diff --git a/root/opt/phpsysinfo/.htaccess b/root/opt/phpsysinfo/.htaccess index 9c15814..a27adc9 100644 --- a/root/opt/phpsysinfo/.htaccess +++ b/root/opt/phpsysinfo/.htaccess @@ -6,6 +6,30 @@ # Deny all requests from Apache 2.4+ - Require all granted + Require all denied + + +# Deny all requests from Apache 2.0-2.2 + + order deny,allow + deny from all + +# Deny all requests from Apache 2.4+ + + Require all denied + + + + +# Deny all requests from Apache 2.0-2.2 + + order deny,allow + deny from all + +# Deny all requests from Apache 2.4+ + + Require all denied + + diff --git a/root/opt/phpsysinfo/.travis.yml b/root/opt/phpsysinfo/.travis.yml deleted file mode 100644 index 9ed9bd0..0000000 --- a/root/opt/phpsysinfo/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: php - -php: - - 5.2 - - 5.3 - - 5.4 - - 5.5 - - 5.6 - -script: for i in `find . -name "*.php"`; do php -l $i; done; - -branches: - only: - - "master" - - "stable" - -notifications: - email: false diff --git a/root/opt/phpsysinfo/CHANGELOG.md b/root/opt/phpsysinfo/CHANGELOG.md index 0451ba5..4bf6608 100644 --- a/root/opt/phpsysinfo/CHANGELOG.md +++ b/root/opt/phpsysinfo/CHANGELOG.md @@ -3,8 +3,242 @@ Changelog of phpSysInfo http://phpsysinfo.sourceforge.net/ +phpSysInfo 3.4.4 +---------------- + - [ADD] Proxmox to detected distros + + - [NEW] HIDE_SENSORS option + + - [FIX] pmset - UPS support for macOS 10.15 + + - [UPD] IPMIcfg sensor program - pminfo + - [UPD] SMART Plugin - rebuilt to show the state of any defined attributes IDs + +phpSysInfo 3.4.3 +---------------- + - [ADD] Linux Lite, BigLinux, Linspire, Tuxedo, Armbian, Photon, RebeccaBlackOS, QuemOS, dahliaOS, openEuler, Runtu, risiOS, Nobara, Fatdog, CachyOS, Snal, Feren, Archman, Elive, RoboLinux, ExTiX, Kaisen, LXLE, Neptune, Regata, Archcraft, Kodachi, Bodhi, Siduction, Vanilla, Q4OS, Guix, XeroLinux, OpenWRT, Gnoppix, Uruk, Laclin, Clear, Sparky and Venom Linux to detected distros + + - [NEW] SHOW_NETWORK_BRIDGE option + - [NEW] JSONP option for enable JSONP data mode + - [NEW] plugin DiskLoad - show Disk Load information on WinNT + +phpSysInfo 3.4.2 +---------------- + - [ADD] RebornOS, Parrot OS, Pop!_OS, Nitrux, Makulu, Absolute, Bluestar, Ultramarine Linux and TrueNAS to detected distros + - [ADD] schabau_bootstrap template + - [ADD] Raid plugin - storcli and perccli status + + - [NEW] Partial support for GNU Hurd + - [NEW] Ability to retrieve Linux, GNU Hurd, DrayOS and FortiOS system information via SSH + +phpSysInfo 3.4.1 +---------------- + - [ADD] Linuxfx, EndeavourOS, Garuda, Arco and Artix Linux to detected distros + + - [FIX] Fixed sensors voltages + + - [UPD] UpdateNotifier plugin - compatibility with newer data formats + +phpSysInfo 3.4.0 +---------------- + - [ADD] Omarine, NethServer, JingOS, KDE neon, Alma, Virtuozzo, EuroLinux and Rocky Linux to detected distros + + - [NEW] HIDE_NETWORK_INTERFACE_REGEX option to use a regular expression in the name of a hidden network interface + - [NEW] Ability to read UPS information from a file + - [NEW] Virtualizer detection on Linux, Android, FreeBSD, NetBSD, OpenBSD and WinNT + - [NEW] ROOTFS option to set root path of the system + + - [UPD] Changed all data file extensions from .txt to .tmp + - [UPD] Sensor CoreTemp renamed to CpuMem and extended to read the CPU and memory supply voltages + +phpSysInfo 3.3.4 +---------------- + + - [FIX] Fixed display in static mode + +phpSysInfo 3.3.3 +---------------- + + - [ADD] Persian (Farsi) Translation fa.xml + - [ADD] Croatian Translation hr.xml + - [ADD] Mabox, Milis, FreeNAS, UOS and Septor to detected distros + - [ADD] SMART plugin - reading contents of wmic command for WinNT + - [ADD] Raid plugin - 3ware-status status + - [ADD] IPMIcfg sensor program support + + - [NEW] Ability to read information from an external WinNT server (new WMI_HOSTNAME, WMI_USER and WMI_PASSWORD parameters) + - [NEW] NvidiaSMI - sensors monitoring for Nvidia GPU + - [NEW] plugin Viewer - show output of any command or file viewer.txt contents + - [NEW] Memory chips information + - [NEW] USB devices speed info on Linux + - [NEW] IGNORE_TOTAL option + - [NEW] HIDE_TOTALS option + - [NEW] INCREASE_WIDTH option for frontend "dynamic" + + - [DEL] Removed deprecated plugin Iptables + +phpSysInfo 3.3.2 +---------------- + + - [UPD] Korean Translation ko.xml + + - [ADD] Exherbo and EasyOS to detected distros + - [ADD] PCI devices list on SunOS + - [ADD] Raid plugin - megaclisas-status status + + - [NEW] OS Type information + - [NEW] CPU manufacturer information + - [NEW] Frontend Bootstrap view in web app mode on mobile devices + +phpSysInfo 3.3.1 +---------------- + + - [UPD] bootstrap 4.3.1 + - [UPD] bootstrap-ie 4.3.100 + + - [ADD] Indonesian Translation id.xml + + - [NEW] HIDE_BOOTSTRAP_LOADER option + - [NEW] Uprecords plugin - DENOTE_BY_ASTERISK option + + - [DEL] jQuery 3.3.1 + +phpSysInfo 3.3.0 +---------------- + + - [UPD] Frontend Bootstrap3 to Bootstrap4 with IE8 and IE9 compatibility modules + + - [ADD] Endless, Kali, Redcore and MX Linux to detected distros + - [ADD] SMART plugin - support for NVMe disks + - [ADD] Uprecords plugin - SHORT_MODE option + - [ADD] Raid plugin - IDRAC RAID status + + - [NEW] NVMe devices list on Linux + - [NEW] Docker plugin - docker stats + - [NEW] SORT_NETWORK_INTERFACES_LIST and SORT_SENSORS_LIST options + - [NEW] IGNORE_FREE, IGNORE_USAGE and IGNORE_THRESHOLD_FS_TYPES options + +phpSysInfo 3.2.10 +---------------- + + - [UPD] jQuery 3.3.1 + + - [ADD] NuTyX to detected distros + + - [FIX] Raid plugin - fixed zpool analize + +phpSysInfo 3.2.9 +---------------- + + - [UPD] Greek Translation gr.xml + + - [ADD] BAT plugin - Model, Manufacturer and Serial Number information + - [ADD] BAT plugin - SHOW_SERIAL and UPOWER option + - [ADD] Springdale Linux to detected distros + + - [NEW] SHOW_DEVICES_INFOS and SHOW_DEVICES_SERIAL options + - [NEW] Thinkpad - Lenovo Thinkpad sensors monitoring for Linux + - [NEW] StableBit plugin - StableBit Scanner info + - [NEW] HyperV plugin - Hyper-V info + - [NEW] Raid plugin - software, fake, zpool and megaraid RAID status + + - [DEL] Removed deprecated MDStatus and DMRaid plugins + +phpSysInfo 3.2.8 +---------------- + + - [UPD] jQuery 3.2.1 + - [UPD] French Translation fr.xml + - [UPD] CPU usage on WinNT + - [UPD] Ukrainian Translation uk.xml + + - [FIX] Fixed incorrect network usage on FreeBSD 11 + - [FIX] Fixed healthd sensors + - [FIX] Fixed displaying for code pages windows-932, windows-949 and windows-950 for WinNT + + - [ADD] Container Linux, PureOS, OpenELEC, LibreELEC and Lakka to detected distros + - [ADD] FreeIPMI, IPMItool and IPMIutil other information + - [ADD] PS plugin - CPU usage + - [ADD] PS plugin - MEMORY_USAGE, CPU_USAGE and SHOW_PID1CHILD_EXPANDED options + - [ADD] SMART plugin - WMI access for WinNT + + - [NEW] DATETIME_FORMAT option + - [NEW] BLOCKS option - order of data blocks + - [NEW] SHOW_NETWORK_ACTIVE_SPEED option + - [NEW] Ability to generate only part of the data + - [NEW] LOAD_BAR compact mode option + - [NEW] PingTest plugin + + - [DEL] Removed deprecated IPMIinfo plugin + +phpSysInfo 3.2.7 +---------------- + + - [UPD] jQuery 3.1.1 + - [UPD] Network interfaces info for WinNT + - [UPD] Turkish Translation tr.xml + - [UPD] Greek Translation gr.xml + - [UPD] Korean Translation ko.xml + - [UPD] Ukrainian Translation uk.xml + + - [ADD] Devuan and SalentOS to detected distros + - [ADD] HIDE_NETWORK_MACADDR option + + - [NEW] Raspberry Pi detection on Linux + +phpSysInfo 3.2.6 +---------------- + + - [UPD] jQuery 3.1.0 and jQuery 1.12.4 + - [UPD] bootstrap 3.3.7 + - [UPD] Swedish Translation sv.xml + - [UPD] Norwegian Translation no.xml + + - [ADD] NeoKylin and Void to detected distros + - [ADD] schabau and lingruby template + - [ADD] DMRaid plugin - FreeBSD graid info + - [ADD] SNMPPInfo plugin - support for Ricoh printers + - [ADD] UpdateNotifier plugin - ACCESS option + + - [NEW] sudo commands list + - [NEW] plugin Iptables - iptables rules list + +phpSysInfo 3.2.5 +---------------- + + - [UPD] jQuery 2.2.0 and jQuery 1.12.0 + + - [ADD] Show network interfaces infos for NetBSD and OpenBSD + - [ADD] SHOW_NETWORK_INFOS_EXPANDED option + - [ADD] SHOW_MEMORY_INFOS_EXPANDED option + - [ADD] QTS, OpenMamba and HipServ to detected distros + - [ADD] SNMPups - monitoring UPS via SNMP + + - [NEW] reloading plugins also for frontend "bootstrap" + - [NEW] Network speed info on WinNT, Linux, Android, Darwin, NetBSD, OpenBSD and FreeBSD + - [NEW] Coretemp monitoring also on Linux + - [NEW] QTSsnmp - SNMP sensors monitoring for QTS Linux + - [NEW] Hwmon - sensors monitoring for Linux + - [NEW] SpeedFan - sensors monitoring for WinNT + - [NEW] Separate configuration sections for motherboard monitoring sensors programs + - [NEW] List of IP addresses of clients authorized to run + +phpSysInfo 3.2.4 +---------------- + + - [ADD] Solus to detected distros + - [ADD] Uprecords plugin - MAX_ENTRIES option - maximum number of entries to show + + - [UPD] Refreshing status of all plugins for dynamic mode + - [UPD] bootstrap 3.3.6 + + - [NEW] language and template selection also for frontend "bootstrap" + + - [FIX] PHP 7 class Error issues + phpSysInfo 3.2.3 ---------------- + - [UPD] jQuery 2.1.4 and jQuery 1.11.3 - [UPD] bootstrap 3.3.5 @@ -14,6 +248,7 @@ phpSysInfo 3.2.3 phpSysInfo 3.2.2 ---------------- + - [UPD] bootstrap 3.3.4 - [NEW] Thunderbolt (TB) devices list on Darwin @@ -27,6 +262,7 @@ phpSysInfo 3.2.2 phpSysInfo 3.2.1 ---------------- + - [UPD] bootstrap 3.3.2 - [NEW] REFRESH parameter also for frontend "bootstrap" @@ -37,6 +273,7 @@ phpSysInfo 3.2.1 phpSysInfo 3.2.0 ---------------- + - [UPD] jQuery 2.1.3 and jQuery 1.11.2 - [NEW] Frontend "bootstrap" with Bootstrap3 and Transparency (JSON) @@ -121,7 +358,8 @@ phpSysInfo 3.1.11 - [ADD] Generations Linux and SliTaz to detected distros - [ADD] IPMI and LMSensors currents information - [ADD] Plugin IPMIInfo - added powers and currents values - - [ADD] Partial support of QNX + + - [NEW] Partial support of QNX - [FIX] Reduce execution time on Linux systems when showing load average PR#47 @@ -135,7 +373,7 @@ phpSysInfo 3.1.10 phpSysInfo 3.1.9 ---------------- - - [NEW] New plugin DMRaid - software raid status + - [NEW] plugin DMRaid - software raid status - [ADD] Calculate, Tails, SMEServer, Semplice, SolydXK, Parsix, RedFlag, Amazon, Korora, OpenMandriva, SteamOS, ROSA Enterprise Server and ROSA Desktop Fresh to detected distros diff --git a/root/opt/phpsysinfo/COPYING b/root/opt/phpsysinfo/COPYING index d511905..14db8fc 100644 --- a/root/opt/phpsysinfo/COPYING +++ b/root/opt/phpsysinfo/COPYING @@ -1,8 +1,8 @@ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to +the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS - + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest @@ -303,9 +303,10 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Also add information on how to contact you by electronic and paper mail. @@ -335,5 +336,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General +library. If this is what you want to do, use the GNU Library General Public License instead of this License. diff --git a/root/opt/phpsysinfo/Dockerfile b/root/opt/phpsysinfo/Dockerfile index 5b62375..59d10ec 100644 --- a/root/opt/phpsysinfo/Dockerfile +++ b/root/opt/phpsysinfo/Dockerfile @@ -1,20 +1,24 @@ # phpSysInfo -# VERSION 2 +# VERSION 4 -FROM ubuntu:14.04 +FROM ubuntu:20.04 +ENV LC_ALL C.UTF-8 +ARG DEBIAN_FRONTEND=noninteractive +ARG http_proxy="" +ARG https_proxy="" MAINTAINER phpSysInfo # Update sources -RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list -RUN apt-get update +RUN apt-get -q update && \ + apt-get -qy install apache2 php7.4 php7.4-xml php7.4-mbstring libapache2-mod-php7.4 git pciutils && \ + apt-get clean && \ + rm -Rf /var/lib/apt/lists/* -RUN apt-get install -y apache2 php5 git pciutils - -RUN git clone https://github.com/phpsysinfo/phpsysinfo.git /var/www/html/phpsysinfo -#RUN cp /var/www/html/phpsysinfo/phpsysinfo.ini.new /var/www/html/phpsysinfo/phpsysinfo.ini -RUN cat /var/www/html/phpsysinfo/phpsysinfo.ini.new | sed 's/^LOAD_BAR=false/LOAD_BAR=true/' >/var/www/html/phpsysinfo/phpsysinfo.ini +RUN git clone https://github.com/phpsysinfo/phpsysinfo.git /var/www/html/phpsysinfo && \ + cp /var/www/html/phpsysinfo/phpsysinfo.ini.new /var/www/html/phpsysinfo/phpsysinfo.ini +ENV APACHE_RUN_DIR /var/run/apache2 ENV APACHE_RUN_USER www-data ENV APACHE_RUN_GROUP www-data ENV APACHE_LOG_DIR /var/log/apache2 diff --git a/root/opt/phpsysinfo/README.md b/root/opt/phpsysinfo/README.md index 8f342bb..499c3de 100644 --- a/root/opt/phpsysinfo/README.md +++ b/root/opt/phpsysinfo/README.md @@ -1,45 +1,56 @@ phpSysInfo ============== -* Copyright (c), 1999-2008, Uriah Welcome (precision@users.sf.net) -* Copyright (c), 1999-2009, Michael Cramer (bigmichi1@users.sf.net) -* Copyright (c), 2007-2008, Audun Larsen (xqus@users.sf.net) -* Copyright (c), 2007-2015, Erkan Valentin -* Copyright (c), 2009-2015, Mieczyslaw Nalewaj (namiltd@users.sf.net) -* Copyright (c), 2010-2012, Damien Roth (iysaak@users.sf.net) +* Copyright (c), 1999-2008, Uriah Welcome ([sf.net/users/precision](https://sf.net/users/precision)) +* Copyright (c), 1999-2009, Michael Cramer ([github.com/bigmichi1](https://github.com/bigmichi1), [sf.net/users/bigmichi1](https://sf.net/users/bigmichi1)) +* Copyright (c), 2007-2008, Audun Larsen ([sf.net/users/xqus](https://sf.net/users/xqus)) +* Copyright (c), 2007-2015, Erkan Valentin ([github.com/rk4an](https://github.com/rk4an), [sf.net/users/jacky672](https://sf.net/users/jacky672)) +* Copyright (c), 2009-2024, Mieczyslaw Nalewaj ([github.com/namiltd](https://github.com/namiltd), [sf.net/users/namiltd](https://sf.net/users/namiltd)) +* Copyright (c), 2010-2012, Damien Roth ([sf.net/users/iysaak](https://sf.net/users/iysaak)) +REQUIREMENTS +------------ + +PHP 5.1.3 or later with SimpleXML, PCRE, XML and DOM extension. + +#### Suggested extensions: +- mbstring: Required for *nix non UTF-8 systems +- com_dotnet: Required for Windows environments +- xsl: Required for static mode +- json: Required for bootstrap mode CURRENT TESTED PLATFORMS ------------------------ -- Linux 2.6.x -- FreeBSD 7.x +- Linux 2.6+ +- FreeBSD 7+ - OpenBSD 2.8+ - NetBSD - DragonFly - HP-UX -- Darwin/OSX -- Windows 2000 / 2003 / XP / Vista / 7 / 8 / 8.1 / 10 +- Darwin / Mac OS / OS X / iOS +- Windows 2000 / XP / 2003 / Vista / 2008 / 7 / 2011 / 2012 / 8 / 8.1 / 10 / 10 IoT / 2016 / 2019 / 2022 / 11 - Android -- > PHP 5.2 or later - - With PCRE, XML, XSL, MBString and SimpleXML extension. -####Platforms currently in progress: +#### Platforms currently in progress: - Haiku - Minix - SunOS - ReactOS - IBM AIX - QNX +- GNU Hurd +- FortiOS (via SSH) +- DrayOS (via SSH) If your platform is not here try checking out the mailing list archives or -the message boards on SourceForge. +the message boards on Github. INSTALLATION AND CONFIGURATION ------------------------------ -####Typical installation +#### Typical installation Just decompress and untar the source (which you should have done by now, if you're reading this...), into your webserver's document root. @@ -59,10 +70,10 @@ can do this. That's it. Restart your webserver (if you changed php.ini), and voila. -####Docker container installation +#### Docker container installation -- sudo docker build -t phpsysinfo github.com/phpsysinfo/phpsysinfo -- sudo docker run -i -p 8080:80 -t phpsysinfo +- `sudo docker build -t phpsysinfo github.com/phpsysinfo/phpsysinfo#main` +- `sudo docker run -i -p 8080:80 -t phpsysinfo` - go to http://localhost:8080/phpsysinfo/ KNOWN PROBLEMS @@ -74,21 +85,21 @@ KNOWN PROBLEMS PLATFORM SPECIFIC ISSUES ------------------------ -####Windows with IIS +#### Windows with IIS On Windows systems we get our informations through the WMI interface. If you run phpSysInfo on the IIS webserver, phpSysInfo will not connect to the WMI interface for security reasons. At this point you MUST set an authentication mechanism for the directory in the IIS admin interface for the directory where phpSysInfo is installed. Then you will be asked for an user and a password when opening the page. At this - point it is necassary to log in with an user that will be able to + point it is necessary to log in with an user that will be able to connect to the WMI interface. If you use the wrong user and/or password you might get an "ACCESS DENIED ERROR". SENSOR RELATED INFORMATION --------------------------- -####MBM5 +#### MBM5 Make sure you set MBM5 Interval Logging to csv and to the data directory of phpSysInfo. The file must be called MBM5. Also make sure MBM5 doesn't add symbols to the values. This is a Quick MBM5 log parser, @@ -101,21 +112,19 @@ First make sure you've read this file completely, especially the "INSTALLATION AND CONFIGURATION" section. If it still doesn't work then you can: -Submit a bug on SourceForge (preferred) (http://sourceforge.net/projects/phpsysinfo/) +Ask for help or submit a bug on Github (https://github.com/phpsysinfo/phpsysinfo/issues) -Ask for help in the forum (http://sourceforge.net/projects/phpsysinfo/) - -***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini` +***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini` and include any error messages in your bug report / help request !!*** OTHER NOTES ----------- -If you have a great idea or want to help out, just drop by the project -page at SourceForge (http://sourceforge.net/projects/phpsysinfo/). +If you have a great idea or want to help out, just create a pull request with your change proposal +in the [phpSysInfo](https://github.com/phpsysinfo/phpsysinfo) repository. LICENSING --------- -This program and all associated files are released under the GNU Public -License, see [COPYING](COPYING) for details. +This program is released under the GNU Public License Version 2 or +(at your option) any later version, see [COPYING](COPYING) for details. diff --git a/root/opt/phpsysinfo/README_PLUGIN.md b/root/opt/phpsysinfo/README_PLUGIN.md index 26140ac..d86ae0a 100644 --- a/root/opt/phpsysinfo/README_PLUGIN.md +++ b/root/opt/phpsysinfo/README_PLUGIN.md @@ -13,13 +13,13 @@ Beginning with phpSysInfo 3.0, phpSysInfo can be extended by Plugins. So here is a description that a developer of a plugin must take care of. Plugins can be enabled through the `phpsysinfo.ini` in the PLUGINS variable. The name of the plugin is essential for the function of the plugin system. Lets say you write a -plugin with the name 'hdd_stats', then this name is added to the PLUGINS +plugin with the name 'pingtest', then this name is added to the PLUGINS variable in `phpsysinfo.ini`. And this is also then the name which is everywhere in the plugin system used, like creating the object, locate the needed files and so on. So if the name is now specified, phpSysInfo needs a special directory structure -to find the needed files. The directory structure for the example `hdd_stats` +to find the needed files. The directory structure for the example `pingtest` plugin can be seen here: ``` @@ -27,22 +27,22 @@ plugin can be seen here: | +---+ plugins (directory in that plugins are installed) | | - | +---+ hdd_stats (the real plugin directory, must have the same name like + | +---+ pingtest (the real plugin directory, must have the same name like | | | the plugin named in PLUGINS, else it won't be found) | | | | | +---+ js (directory in which the needed JavaScript file is located, | | | | to generate the html output out of the xml) - | | | # hdd_stats.js (the js file must have the same name, like the + | | | # pingtest.js (the js file must have the same name, like the | | | plugin in PSI_PLUGINS with the extension js) | | +---+ css (directory in which the needed style sheet information are | | | | located, can exists, but it's up to the author) - | | | # hdd_stats.css (the css file must have the same name, like the + | | | # pingtest.css (the css file must have the same name, like the | | | plugin in PSI_PLUGINS with the extension css) | | +---+ lang (directory where translations for the plugin are located) | | | | | | | # en.xml (at least an english translation file must exist) | | | - | | # class.hdd_stats.inc.php (this is the core file of the plugin, + | | # class.pingtest.inc.php (this is the core file of the plugin, | | name must consists of 'class' + | | name from PSI_PLUGINS + '.inc.php') ``` @@ -57,7 +57,7 @@ If the directory structure is build up, then it's time to start programming. Files ----- -An example implementation is the mdstat plugin, which is shipped with phpSysInfo +An example implementation is the pingtest plugin, which is shipped with phpSysInfo * en.xml - at least this file must exist to get the translation working, and the the first entry in this file is normally the headline of the plugin. @@ -70,12 +70,12 @@ An example implementation is the mdstat plugin, which is shipped with phpSysInfo other plugins don't redefine your translations. At the time of writing this, there is no check to verify the id's, so be carfull. -* hdd_stats.css - here can all custom style sheet informations written down. The +* pingtest.css - here can all custom style sheet informations written down. The names of the id's and classes SHOULD also begin, like the translation id's, with `'plugin_' + pluginname`. If thats not the case it might be possible that another plugin is overwriting your css definitions. -* class.hdd_stats.inc.php - this file MUST include a class with the plugin name +* class.pingtest.inc.php - this file MUST include a class with the plugin name and also this class MUST extend the 'psi_plugin' class. A check that such a class exist and also extends 'psi_plugin' will be included in the near future. And if the check fails the plugin won't be loaded. @@ -93,26 +93,26 @@ An example implementation is the mdstat plugin, which is shipped with phpSysInfo standalone xml. So there is no need to do some special things, only create a xml object for the plugin. -* hdd_stats.js - this file is called when the page is loaded. A block for the +* pingtest.js - this file is called when the page is loaded. A block for the plugin is automatically created. This one is a div container with the - id `'plugin_'+ pluginname ("plugin_hdd_stats")`. The entire output must be + id `'plugin_'+ pluginname ("plugin_pingtest")`. The entire output must be placed in that container. There is a helper function for creating the headline: buildBlock() that can be called. This function returns a string with the html code of the headline, this code can then be appended to the plugin block. The generated headline can provide a reload icon for an ajax request. Only the click action of that icon must be created. The id of this icon is - `'reload_' + pluginname + 'Table' ("reload_hdd_statsTable")`. + `'reload_' + pluginname + 'Table' ("reload_pingtestTable")`. Everything that then is done to get the html output out of the xml is up to the author. To get the xml document the ajax request url is `'xml.php?plugin=' + - pluginname (xml.php?plugin=hdd_stats)`. This xml includes only the xml + pluginname (xml.php?plugin=pingtest)`. This xml includes only the xml from the plugin nothing more. The last two executed commands should/must be the translation call and the unhide of the filled div container. The translation function that needs to be called is named plugin_traslate() with one argument, that is the pluginname like in - `PSI_PLUGINS (plugin_translate("hdd_stats");)`. + `PSI_PLUGINS (plugin_translate("pingtest");)`. To unhide the filled container call the .show() function of it. `$("plugin_" + pluginname).show() ($("plugin_hdd_stat").show())`. diff --git a/root/opt/phpsysinfo/SECURITY.md b/root/opt/phpsysinfo/SECURITY.md new file mode 100644 index 0000000..4e5b490 --- /dev/null +++ b/root/opt/phpsysinfo/SECURITY.md @@ -0,0 +1,12 @@ +# Security Policy + +## Supported Versions + +The [latest released version](https://github.com/phpsysinfo/phpsysinfo/releases) of phpSysInfo is supported. + +## Reporting a Vulnerability + +Please email phpsysinfo@yahoo.com, and we will respond as quickly as possible. + +If the vulnerability is considered valid and accepted, a patch will be made for the latest phpSysInfo version. +If the vulnerability is deemed invalid, no further action is required. diff --git a/root/opt/phpsysinfo/composer.json b/root/opt/phpsysinfo/composer.json index d839520..8423869 100644 --- a/root/opt/phpsysinfo/composer.json +++ b/root/opt/phpsysinfo/composer.json @@ -1,10 +1,10 @@ { "name": "phpsysinfo/phpsysinfo", "description": "phpSysInfo is a customizable PHP Script that parses /proc, and formats information nicely. It will display information about system facts like Uptime, CPU, Memory, PCI devices, SCSI devices, IDE devices, Network adapters, Disk usage, and more.", - "license": "GPL", + "license": "GPL-2.0-or-later", "homepage": "http://phpsysinfo.github.io/phpsysinfo/", "require": { - "php": ">=5.2.0", + "php": ">=5.1.3", "ext-simplexml": "*", "ext-pcre": "*", "ext-xml": "*", @@ -13,6 +13,7 @@ "suggest": { "ext-mbstring": "Required for *nix non UTF-8 systems", "ext-com_dotnet": "Required for Windows environments", - "ext-xsl": "Required for static mode" + "ext-xsl": "Required for static mode", + "ext-json": "Required for bootstrap mode" } -} \ No newline at end of file +} diff --git a/root/opt/phpsysinfo/data/.htaccess b/root/opt/phpsysinfo/data/.htaccess new file mode 100644 index 0000000..1c4ee05 --- /dev/null +++ b/root/opt/phpsysinfo/data/.htaccess @@ -0,0 +1,9 @@ +# Deny all requests from Apache 2.0-2.2 + + order deny,allow + deny from all + +# Deny all requests from Apache 2.4+ + + Require all denied + diff --git a/root/opt/phpsysinfo/data/ModelTranslation.txt b/root/opt/phpsysinfo/data/ModelTranslation.txt index dfa05e1..1faee2e 100644 --- a/root/opt/phpsysinfo/data/ModelTranslation.txt +++ b/root/opt/phpsysinfo/data/ModelTranslation.txt @@ -21,7 +21,44 @@ iMac13,2:iMac Core i5/i7:Intel Core I5-3470/I5-3470S/I7-3770 iMac14,1:iMac Core i5:Intel Core I5-4570R iMac14,2:iMac Core i5/i7:Intel Core I5-4570/I5-4670/I7-4771 iMac14,3:iMac Core i5/i7:Intel Core I5-4570S/I7-4770S +iMac14,4:iMac Core i5:Intel Core I5-4260U +iMac15,1:iMac Core i5/i7:Intel Core I5-4590/I5-4690/I7-4790K +iMac16,1:iMac Core i5:Intel Core I5-5250U +iMac16,2:iMac Core i5/i7:Intel Core I5-5575R/I5-5675R/I7-5775R +iMac17,1:iMac Core i5/i7:Intel Core I5-6500/I5-6600/I7-6700K +iMac18,1:iMac Core i5:Intel Core I5-7360U +iMac18,2:iMac Core i5/i7:Intel Core I5-7400/I5-7500/I7-7700 +iMac18,3:iMac Core i5/i7:Intel Core I5-7500/I5-7600/I5-7600K/I7-7700K +iMac19,1:iMac Core i5/i9:Intel Core I5-8500/I5-8600/I5-9600K/I9-9900K +iMac19,2:iMac Core i3/i5/i7:Intel Core I3-8100/I5-8500/I7-8700 +iMac20,1:iMac Core i5/i7/i9:Intel Core I5-10500/I5-10600/I7-10700K/I9-10910 +iMac20,2:iMac Core i7/i9:Intel Core I7-10700K/I9-10910 +iMac21,1:MacBook Air M1:Apple M1 +iMac21,2:MacBook Air M1:Apple M1 M43ADP1,1:Development Mac Pro:Intel Xeon X5340 +Mac13,1:Mac Studio M1 Max:Apple M1 Max +Mac13,2:Mac Studio M1 Ultra:Apple M1 Ultra +Mac14,2:MacBook Air M2:Apple M2 +Mac14,3:Mac mini M2:Apple M2 +Mac14,5:MacBook Pro M2 Max:Apple M2 Max +Mac14,6:MacBook Pro M2 Max:Apple M2 Max +Mac14,7:MacBook Pro M2:Apple M2 +Mac14,8:Mac Pro M2 Ultra:Apple M2 Ultra +Mac14,9:MacBook Pro M2 Pro:Apple M2 Pro +Mac14,10:MacBook Pro M2 Pro:Apple M2 Pro +Mac14,12:Mac mini M2 Pro:Apple M2 Pro +Mac14,13:Mac Studio M2 Max:Apple M2 Max +Mac14,14:Mac Studio M2 Ultra:Apple M2 Ultra +Mac14,15:MacBook Air 15" M2:Apple M2 +Mac15,3:MacBook Pro 14" M3:Apple M3 +Mac15,4:iMac 24" M3:Apple M3 +Mac15,5:iMac 24" M3:Apple M3 +Mac15,6:MacBook Pro 14" M3 Pro:Apple M3 Pro +Mac15,7:MacBook Pro 16" M3 Pro:Apple M3 Pro +Mac15,8:MacBook Pro 14" M3 Max:Apple M3 Max +Mac15,9:MacBook Pro 16" M3 Max:Apple M3 Max +Mac15,10:MacBook Pro 14" M3 Max:Apple M3 Max +Mac15,11:MacBook Pro 16" M3 Max:Apple M3 Max MacBook1,1:MacBook Core Duo:Intel Core Duo T2400/T2500 MacBook2,1:MacBook Core 2 Duo:Intel Core 2 Duo T5600/T7200/T7400 MacBook3,1:MacBook Core 2 Duo:Intel Core 2 Duo T7300/T7500 @@ -30,6 +67,9 @@ MacBook5,1:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P8600 MacBook5,2:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P7450 MacBook6,1:MacBook Core 2 Duo:Intel Core 2 Duo P7550 MacBook7,1:MacBook Core 2 Duo:Intel Core 2 Duo P8600 +MacBook8,1:MacBook Core M:Intel Core M-5Y31/M-5Y51/M-5Y71 +MacBook9,1:MacBook Core m3/m5/m7:Intel Core M3-6Y30/M5-6Y54/M7-6Y75 +MacBook10,1:MacBook Core m3/i5/i7:Intel Core M3-7Y32/i5-7Y54/i7-7Y75 MacBookAir1,1:MacBook Air Core 2 Duo:Intel Core 2 Duo P7500/P7700 MacBookAir2,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SL9300/SL9400/SL9600 MacBookAir3,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SU9400/SU9600 @@ -40,6 +80,11 @@ MacBookAir5,1:MacBook Air Core i5/i7:Intel Core I5-3317U/I7-3667U MacBookAir5,2:MacBook Air Core i5/i7:Intel Core I5-3427U/I7-3667U MacBookAir6,1:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U MacBookAir6,2:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U +MacBookAir7,1:MacBook Air Core i5/i7:Intel Core I5-5250U/I7-5650U +MacBookAir7,2:MacBook Air Core i5/i7:Intel Core I5-5250U/I7-5650U +MacBookAir8,1:MacBook Air Core i5:Intel Core I5-8210Y +MacBookAir9,1:MacBook Air Core i3/i5/i7:Intel Core I3-1000NG4/I5-1030NG7/I7-1060NG7 +MacBookAir10,1:MacBook Air M1:Apple M1 MacBookPro1,1:MacBook Pro Core Duo:Intel Core Duo L2400/T2400/T2500/T2600 MacBookPro1,2:MacBook Pro Core Duo:Intel Core Duo T2600 MacBookPro2,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo T7600 @@ -61,24 +106,50 @@ MacBookPro9,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3720QM/I7-3820QM MacBookPro9,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I7-3520M MacBookPro10,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3635QM/I7-3720QM/I7-3740QM/I7-3820QM/I7-3840QM MacBookPro10,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I5-3230M/I7-3520M/I7-3540M -MacBookPro11,1:MacBook Pro Core i5/i7:Intel Core I5-4258U/I5-4288U/I7-4558U -MacBookPro11,2:MacBook Pro Core i7:Intel Core I7-4750HQ/I7-4850HQ/I7-4960HQ -MacBookPro11,3:MacBook Pro Core i7:Intel Core I7-4850HQ/I7-4960HQ +MacBookPro11,1:MacBook Pro Core i5/i7:Intel Core I5-4258U/I5-4278U/I5-4288U/I5-4308U/I7-4558U/I5-4578U +MacBookPro11,2:MacBook Pro Core i7:Intel Core I7-4750HQ/I7-4770HQ/I7-4850HQ/I7-4870HQ/I7-4960HQ/I7-4980HQ +MacBookPro11,3:MacBook Pro Core i7:Intel Core I7-4850HQ/I7-4870HQ/I7-4960HQ/I7-4980HQ +MacBookPro11,4:MacBook Pro Core i7:Intel Core I7-4770HQ/I7-4870HQ/I7-4980HQ +MacBookPro11,5:MacBook Pro Core i7:Intel Core I7-4870HQ/I7-4980HQ +MacBookPro12,1:MacBook Pro Core i5/i7:Intel Core I5-5257U/I5-5287U/I7-5557U +MacBookPro13,1:MacBook Pro Core i5/i7:Intel Core I5-6360U/I7-6660U +MacBookPro13,2:MacBook Pro Core i5/i7:Intel Core I5-6267U/I5-6287U/I7-6567U +MacBookPro13,3:MacBook Pro Core i7:Intel Core I7-6700HQ/I7-6820HQ/I7-6920HQ +MacBookPro14,1:MacBook Pro Core i5/i7:Intel Core I5-7360U/I7-7660U +MacBookPro14,2:MacBook Pro Core i5/i7:Intel Core I5-7267U/I5-7287U/I7-7567U +MacBookPro14,3:MacBook Pro Core i7:Intel Core I7-7700HQ/I7-7820HQ/I7-7920HQ +MacBookPro15,1:MacBook Pro Core i7/i9:Intel Core I7-8750H/I7-8850H/I7-9750H/I9-8950HK/I9-9880H/I9-9980HK +MacBookPro15,2:MacBook Pro Core i5/i7:Intel Core I5-8259U/I5-8279U/I7-8559U/I7-8569U +MacBookPro15,3:MacBook Pro Core i7/i9:Intel Core I7-8850H/I9-8950HK/I9-9880H/I9-9980HK +MacBookPro15,4:MacBook Pro Core i5/i7:Intel Core I5-8257U/I7-8557U +MacBookPro16,1:MacBook Pro Core i7/i9:Intel Core I7-9750H/I9-9880H/I9-9980HK +MacBookPro16,2:MacBook Pro Core i5/i7:Intel Core I5-1038NG7/I7-1068NG7 +MacBookPro16,3:MacBook Pro Core i5/i7:Intel Core I5-8257U/I7-8557U +MacBookPro16,4:MacBook Pro Core i7/i9:Intel Core I7-9750H/I9-9880H/I9-9980HK +MacBookPro17,1:MacBook Pro M1:Apple M1 +MacBookPro18,1:MacBook Pro M1 Pro:Apple M1 Pro +MacBookPro18,2:MacBook Pro M1 Max:Apple M1 Max +MacBookPro18,3:MacBook Pro M1 Pro:Apple M1 Pro +MacBookPro18,4:MacBook Pro M1 Max:Apple M1 Max Macmini1,1:Mac mini Core Solo/Duo:Intel Core Duo T2300/T2400 Solo T1200 Macmini2,1:Mac mini Core 2 Duo:Intel Core 2 Duo T5600/T7200 Macmini3,1:Mac mini Core 2 Duo:Intel Core 2 Duo P7350/P8400/P7550/P8700/P8800 Macmini4,1:Mac mini Core 2 Duo:Intel Core 2 Duo P8600/P8800 Macmini5,1:Mac mini Core i5:Intel Core I5-2415M Macmini5,2:Mac mini Core i5/i7:Intel Core I5-2520M/I7-2620M -Macmini5,3:Mac mini Core i7:Intel Core I7-2635QM +Macmini5,3:Mac mini Core i7:Intel Core I7-2635QM Macmini6,1:Mac mini Core i5:Intel Core I5-3210M -Macmini6,2:Mac mini Core i7:Intel Core i7 I7-3615QM/I7-3720QM +Macmini6,2:Mac mini Core i7:Intel Core I7-3615QM/I7-3720QM +Macmini7,1:Mac mini Core i5/i7:Intel Core I5-4260U/I5-4278U/I5-4308U/I7-4578U +Macmini8,1:Mac mini Core i3/i5/i7:Intel Core I3-8100/I5-8500B/I7-8700B +Macmini9,1:Mac mini M1:Apple M1 MacPro1,1:Mac Pro Quad Core:Intel Xeon 5130/5150/5160 MacPro2,1:Mac Pro Eight Core:Intel Xeon X5365 MacPro3,1:Mac Pro Quad/Eight Core:Intel Xeon E5462/E5472/X5482 MacPro4,1:Mac Pro Quad/Eight Core:Intel Xeon E5520/E5550/X5570/W3520/W3540/W3580 MacPro5,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5620/E5645/W3530/W3565/W3680/X5650/X5670/X5675 MacPro6,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5-1620v2/E5-1650v2/E5-1680v2/E5-2697v2 +MacPro7,1:Mac Pro Eight/12/16/24/28 Core:Intel Xeon W-3223/W-3235/W-3245/W-3265M/W-3275M PowerBook1,1:PowerBook G3:PowerPC 750 (G3) PowerBook2,1:iBook G3:PowerPC 750 (G3) PowerBook2,2:iBook G3:PowerPC 750cx (G3) diff --git a/root/opt/phpsysinfo/data/cpus.ini b/root/opt/phpsysinfo/data/cpus.ini new file mode 100644 index 0000000..d7a1b39 --- /dev/null +++ b/root/opt/phpsysinfo/data/cpus.ini @@ -0,0 +1,229 @@ +[cpu] +; Qemu +0x0,0x51="QEMU TCG" + +; Ampere Computing +;0xc0 + +; ARM Limited +0x41,0x810="ARM810" +0x41,0x920="ARM920" +0x41,0x922="ARM922" +0x41,0x926="ARM926" +0x41,0x940="ARM940" +0x41,0x946="ARM946" +0x41,0x966="ARM966" +0x41,0xa20="ARM1020" +0x41,0xa22="ARM1022" +0x41,0xa26="ARM1026" +0x41,0xb02="ARM11 MPCore" +0x41,0xb36="ARM1136" +0x41,0xb56="ARM1156" +0x41,0xb76="ARM1176" +0x41,0xc05="Cortex-A5" +0x41,0xc07="Cortex-A7" +0x41,0xc08="Cortex-A8" +0x41,0xc09="Cortex-A9" +0x41,0xc0d="Cortex-A12" +0x41,0xc0f="Cortex-A15" +0x41,0xc0e="Cortex-A17" +0x41,0xc14="Cortex-R4" +0x41,0xc15="Cortex-R5" +0x41,0xc17="Cortex-R7" +0x41,0xc18="Cortex-R8" +0x41,0xc20="Cortex-M0" +0x41,0xc21="Cortex-M1" +0x41,0xc23="Cortex-M3" +0x41,0xc24="Cortex-M4" +0x41,0xc20="Cortex-M7" +0x41,0xc60="Cortex-M0+" +0x41,0xd01="Cortex-A32" +0x41,0xd02="Cortex-A34" +0x41,0xd03="Cortex-A53" +0x41,0xd04="Cortex-A35" +0x41,0xd05="Cortex-A55" +0x41,0xd06="Cortex-A65" +0x41,0xd07="Cortex-A57" +0x41,0xd08="Cortex-A72" +0x41,0xd09="Cortex-A73" +0x41,0xd0a="Cortex-A75" +0x41,0xd0b="Cortex-A76" +0x41,0xd0c="Neoverse-N1" +0x41,0xd0d="Cortex-A77" +0x41,0xd0e="Cortex-A76AE" +0x41,0xd13="Cortex-R52" +0x41,0xd15="Cortex-R82" +0x41,0xd20="Cortex-M23" +0x41,0xd21="Cortex-M33" +0x41,0xd22="Cortex-M55" +0x41,0xd23="Cortex-M85" +0x41,0xd40="Neoverse-V1" +0x41,0xd41="Cortex-A78" +0x41,0xd42="Cortex-A78AE" +0x41,0xd43="Cortex-A65AE" +0x41,0xd44="Cortex-X1" +0x41,0xd46="Cortex-A510" +0x41,0xd47="Cortex-A710" +0x41,0xd48="Cortex-X2" +0x41,0xd49="Neoverse-N2" +0x41,0xd4a="Neoverse-E1" +0x41,0xd4b="Cortex-A78C" +0x41,0xd4c="Cortex-X1C" +0x41,0xd4d="Cortex-A715" +0x41,0xd4e="Cortex-X3" +0x41,0xd4f="Neoverse-V2" +0x41,0xd80="Cortex-A520" +0x41,0xd81="Cortex-A720" +0x41,0xd82="Cortex-X4" +0x41,0xd83="Neoverse-V3AE" +0x41,0xd84="Neoverse-V3" +0x41,0xd85="Cortex-X925" +0x41,0xd87="Cortex-A725" +0x41,0xd8e="Neoverse-N3" + +; Broadcom Corporation - ('B') cores. +0x42,0xf="Brahma B15" +0x42,0x100="Brahma B53" +0x42,0x516="Vulcan/ThunderX2 T99p1" + +; Cavium Inc. - ('C') cores. +0x43,0xa0="ThunderX" +0x43,0xa1="ThunderX T88" +0x43,0xa2="Octeon TX T81" +0x43,0xa3="Octeon TX T83" +0x43,0xaf="ThunderX2 T99" +0x43,0xb0="Octeon TX2" +0x43,0xb1="Octeon TX2 T98" +0x43,0xb2="Octeon TX2 T93/T96" +0x43,0xb3="Octeon TX2 F95" +0x43,0xb4="Octeon TX2 F95N" +0x43,0xb5="Octeon TX2 F95MM" +0x43,0xb8="ThunderX3 T110" + +; DEC - Digital Equipment Corporation +0x44,0xa10="SA110" +0x44,0xa11="SA1100" + +; Fujitsu Ltd. +0x46,0x1="A64FX" + +; HiSilicon Technologies, Inc. +0x48,0xd01="TSV110" +0x48,0xd40="Cortex-A76" + +; Infineon Technologies AG +;0x49 + +; Motorola or Freescale Semiconductor Inc. +;0x4d + +; NVIDIA Corporation +0x4e,0x0="Denver" +0x4e,0x3="Denver 2" + +; APM - Applied Micro Circuits Corporation - ('P') cores. +0x50,0x0="xgene1" + +; Qualcomm Inc. - ('Q') cores. +0x51,0xf="Scorpion" +0x51,0x2d="Scorpion" +0x51,0x4d="Krait" +0x51,0x6f="Krait" +0x51,0x201="Kryo Silver" +0x51,0x205="Kryo Gold" +0x51,0x211="Kryo Silver" +0x51,0x800="Kryo 2xx Gold (Cortex-A73)" +0x51,0x801="Kryo 2xx Silver (Cortex-A53)" +0x51,0x802="Kryo 3xx Gold (Cortex-A75)" +0x51,0x803="Kryo 3xx Silver (Cortex-A55)" +0x51,0x804="Kryo 4xx Gold (Cortex-A76)" +0x51,0x805="Kryo 4xx/5xx Silver (Cortex-A55)" +0x51,0xc00="Falkor" +0x51,0xc01="Saphira" + +; Samsung ('S') cores. +0x53,0x1="Exynos M1/M2 Mongoose" +0x53,0x1,0x1="Exynos M1 Mongoose" +0x53,0x1,0x4="Exynos M2 Mongoose" +0x53,0x2="Exynos M3 Mongoose" +0x53,0x3="Exynos M4 Mongoose" +0x53,0x4="Exynos M5 Mongoose" + +; Texas Instruments +0x54,0x925="TI925" + +; Marvell Semiconductor Inc. +0x56,0x131="Feroceon 88FR131" +0x56,0x581="PJ4/PJ4B" +0x56,0x584="PJ4B-MP/PJ4C" + +; Apple Inc. +0x61,0x1="Cyclone" +0x61,0x2="Typhoon" +0x61,0x3="Typhoon/Capri" +0x61,0x4="Twister" +0x61,0x5="Twister/Elba/Malta" +0x61,0x6="Hurricane" +0x61,0x7="Hurricane/Myst" + +; Faraday +0x66,0x526="FA526" +0x66,0x626="FA626" + +; HXT +0x68,0x0="Phecda" + +;Intel Corporation/Marvell +0x69,0x200="i80200" +0x69,0x210="PXA250A" +0x69,0x212="PXA210A" +0x69,0x242="i80321-400" +0x69,0x243="i80321-600" +0x69,0x290="PXA250B/PXA26x" +0x69,0x292="PXA210B" +0x69,0x2c2="i80321-400-B0" +0x69,0x2c3="i80321-600-B0" +0x69,0x2d0="PXA250C/PXA255/PXA26x" +0x69,0x2d2="PXA210C" +0x69,0x411="PXA27x" +0x69,0x41c="IPX425-533" +0x69,0x41d="IPX425-400" +0x69,0x41f="IPX425-266" +0x69,0x682="PXA32x" +0x69,0x683="PXA930/PXA935" +0x69,0x688="PXA30x" +0x69,0x689="PXA31x" +0x69,0xb11="SA1110" +0x69,0xc12="IPX1200" + +[manufacturer] +AMDisbetter="AMD" +AuthenticAMD="AMD" +CentaurHauls="IDT WinChip/Centaur" +CyrixInstead="Cyrix/STMicro./IBM" +HygonGenuine="Hygon" +GenuineIntel="Intel" +TransmetaCPU="Transmeta" +GenuineTMx86="Transmeta" +GeodebyNSC="National Semiconductor" +NexGenDriven="NexGen" +RiseRiseRise="Rise" +SiSSiSSiS="SiS" +Shanghai="Zhaoxin" +UMCUMCUMC="UMC" +VIAVIAVIA="VIA" +Vortex86SoC="DM&P Vortex" +E2KMACHINE="MCST Elbrus" +GenuineAO486="ao486 soft CPU" +bhyvebhyve="bhyve" +KVMKVMKVM="KVM" +MicrosoftHv="Microsoft Hyper-V" +lrpepyhvr="Parallels" +VMwareVMware="VMware" +XenVMMXenVMM="Xen HVM" +ACRNACRNACRN="Project ACRN" +TCGTCGTCGTCG="QEMU" +QNXQVMBSQG="QNX Hypervisor" +UnisysSpar64="Unisys sPar" +VBoxVBoxVBox="Oracle VM VirtualBox" +IBM/S390="IBM" diff --git a/root/opt/phpsysinfo/data/distros.ini b/root/opt/phpsysinfo/data/distros.ini index 16747ab..e8e6b7a 100644 --- a/root/opt/phpsysinfo/data/distros.ini +++ b/root/opt/phpsysinfo/data/distros.ini @@ -3,174 +3,707 @@ ; $Id: distros.ini 709 2012-12-05 11:20:40Z namiltd $ ; -[GoboLinux] +[solaris sunos] +Image = "Solaris.png" + +[oraclesolaris sunos] +Image = "Solaris.png" + +[smartos sunos] +Image = "SmartOS.png" + +[opensolaris sunos] +Image = "OpenSolaris.png" + +[openindiana sunos] +Image = "OpenIndiana.png" + +[omnios sunos] +Image = "OmniOS.png" + +[openstorage sunos] +Image = "NexentaStor.png" +Name = "NexentaStor" + +[openwrt] +Image = "OpenWRT.png" +Name = "OpenWrt" +Mode = "Detection" +Files = "/etc/openwrt_release" +Files2 = "/etc/openwrt_release" +;detected in "/etc/os-release" + +[vmware photon os] +Image = "Photon.png" +Files = "/etc/photon-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[guix system] +Image = "Guix.png" +;detected in "/etc/os-release" + +[gobolinux] Image = "Gobo.png" Name = "GoboLinux" Files = "/etc/GoboLinuxVersion" -[SliTaz] +[slitaz] Image = "SliTaz.png" Name = "SliTaz" Files = "/etc/slitaz-release" [eisfair] Image = "Eisfair.png" +;detected in "/etc/os-release" + +[eisfair project] +Image = "Eisfair.png" Files = "/etc/eisfair-system" Files2 = "/etc/version" +;detected in "lsb_release -a" -[TinyCore] +[tinycore] Image = "TinyCore.png" Name = "Tiny Core Linux" Files = "/usr/share/doc/tc/release.txt" -[Frugalware] +[venom linux] +Image = "Venom.png" +Name = "Venom Linux" +Files = "/etc/venom-release" +;detected in "/etc/os-release" + +[linux plop] +Image = "Plop.png" +;detected in "/etc/os-release" + +[frugalware] Image = "Frugalware.png" Files = "/etc/frugalware-release" ;detected in "/etc/os-release" -[antiX] +[rbos] +Image = "RebeccaBlackOS.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[quemos] +Image = "QuemOS.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[rebeccablackos] +Image = "RebeccaBlackOS.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[proxmox] +Image = "Proxmox.png" +Name = "Proxmox" +Files = "/usr/bin/pveversion" +Mode = "Execute" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[q4os] +Image = "Q4OS.png" +Name = "Q4OS" +Files = "/etc/q4os_version" +;wrong in "lsb_release -a" Debian +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[siduction] +Image = "Siduction.png" +Files = "/etc/siduction-version" +;wrong in "lsb_release -a" Debian +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[sparkylinux] +Image = "Sparky.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[sparky] +Image = "Sparky.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[regata os] +Image = "Regata.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" + +[tuxedo] +Image = "Tuxedo.png" +Files = "/etc/tuxedo-os-version" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[ubuntu tuxedo] +Image = "Tuxedo.png" +;detected in "/etc/lsb-release" + +[tuxedo os] +Image = "Tuxedo.png" +;detected in "/etc/os-release" + +[ubuntu linspire] +Image = "Linspire.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu lxle] +Image = "LXLE.png" +;detected in "lsb_release -a" +;wrong in "/etc/lsb-release" Ubuntu +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu linux lite] +Image = "LinuxLite.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu bodhi] +Image = "Bodhi.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu linux kodachi] +Image = "Kodachi.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu kodachi] +Image = "Kodachi.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[robolinux] +Image = "RoboLinux.png" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu robolinux] +Image = "RoboLinux.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[feren os classic] +Image = "Feren.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu feren] +Image = "Feren.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[debian gnu/linux armbian] +Image = "Armbian.png" +Name = "Armbian" +Mode = "Detection" +Files = "/etc/armbian-release;/etc/armbian-image-release" +Files2 = "/etc/armbian-release;/etc/armbian-image-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[debian elive] +Image = "Elive.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" debian + +[elive] +Image = "Elive.png" +Mode = "Detection" +Files = "/etc/elive-version" +Files2 = "/etc/elive-version" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" debian + +[debian neptune] +Image = "Neptune.png" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" debian + +[neptune] +Image = "Neptune.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" debian + +[kaisen] +Image = "Kaisen.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" debian + +[kaisen gnu/linux] +Image = "Kaisen.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" debian + +[deepin extix] +Image = "ExTiX.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" debian + +[mx] +Image = "MX.png" +Files = "/etc/mx-version" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/antix-version" antiX +;wrong in "/etc/debian_version" Debian + +; at the end because some distros may also have the same files (like MX) +[antix] Image = "antiX.png" Files = "/etc/antix-version" ;wrong in "/etc/os-release" Debian GNU/Linux ;wrong in "/etc/debian_version" Debian -[IPFire] +[ipfire] Image = "IPFire.png" ;detected in "/etc/system-release" -[4MLinux] +[qts] +Image = "QTS.png" +Name = "QTS" +;detected in "/etc/config/uLinux.conf" + +[4mlinux] Image = "4MLinux.png" Name = "4MLinux" Files = "/etc/4MLinux-version" -[Lunar Linux] +[milis linux] +Image = "Milis.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[lunar linux] Image = "Lunar.png" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" -[CRUX] +[crux] Image = "Crux.png" Mode = "Execute" Files = "/usr/bin/crux" -[Foresight] +[omarine] +Image = "Omarine.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[foresight] Image = "Foresight.png" ;detected in "/etc/distro-release" -[Trustix] +[trustix] Image = "Trustix.png" Files = "/etc/trustix-release;/etc/trustix-version" -[NixOS] +[nixos] Image = "NixOS.png" ;detected in "/etc/os-release" -[FreeEOS] -Image = "free-eos.png" -Files = "/etc/eos-version" +[free-eos] +Image = "FreeEOS.png" +Files = "/etc/eos-release;/etc/eos-version" + +[nutyx] +Image = "NuTyX.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" [generations] Image = "Generations.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[Generations Linux] +[generations linux] Image = "Generations.png" ;detected in "/etc/os-release" -[Manjaro Linux] -Image = "Manjaro.png" -Files = "/etc/manjaro-release" +[dahliaos] +Image = "dahliaOS.png" ;detected in "/etc/os-release" -[ManjaroLinux] -Image = "Manjaro.png" +[laclin] +Image = "Laclin.png" +Mode = "Detection" +Files = "/etc/laclin-release" +Files2 = "/etc/laclin-release" +;detected in "/etc/os-release" but wrong name Slackware + +[artix] +Image = "Artix.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[Arch Linux] -Image = "Arch.png" -Files = "/etc/arch-release" +[artix linux] +Image = "Artix.png" +Mode = "Detection" +Files = "/etc/artix-release" ;detected in "/etc/os-release" -[Arch] +[xerolinux] +Image = "XeroLinux.png" +Mode = "Detection" +Files = "/etc/xerolinux-release" +;detected in "/etc/os-release" + +[xerolinux-kde] +Image = "XeroLinux.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/arch-release" none + +[cachyos linux] +Image = "CachyOS.png" +;detected in "/etc/os-release" + +[cachyos] +Image = "CachyOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/arch-release" none + +[archcraft] +Image = "Archcraft.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" none + +[snal linux] +Image = "Snal.png" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" none + +[snal] +Image = "Snal.png" +Name = "Snal Linux" +Files = "/etc/snal-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/arch-release" none + +[archman] +Image = "Archman.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" none + +[rebornos] +Image = "RebornOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Arch +;wrong in "/etc/arch-release" Arch + +[rebornos linux] +Image = "RebornOS.png" +;wrong in "/etc/os-release" + +[bluestarlinux] +Image = "Bluestar.png" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Arch +;wrong in "/etc/arch-release" Arch + +[endeavouros] +Image = "EndeavourOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" Arch + +[arcolinux] +Image = "Arco.png" +Mode = "Detection" +Files = "/etc/arcolinux-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" Arch + +[garuda] +Image = "Garuda.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/arch-release" Arch + +[garuda linux] +Image = "Garuda.png" +;detected in "/etc/os-release" + +[ubuntu biglinux] +Image = "BigLinux.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[biglinux based in ubuntu] +Image = "BigLinux.png" +;detected in "/etc/os-release" + +[biglinux based in ubuntu 19.04] +Image = "BigLinux.png" +;detected in "/etc/lsb-release" + +[deepin biglinux] +Image = "BigLinux.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/deepin-version" Deepin +;wrong in "/etc/os-release" Deepin +;wrong in "/etc/debian_version" Debian + +[biglinux based in manjaro linux] +Image = "BigLinux.png" +Name = "BigLinux" +Files = "/etc/big-release" +Mode = "Detection" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" Manjaro +;wrong in "/etc/manjaro-release" Manjaro + +[maboxlinux] +Image = "Mabox.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Manjaro +;wrong in "/etc/manjaro-release" Manjaro +;wrong in "/etc/arch-release" Arch | Manjaro + +[netrunner] +Image = "Netrunner.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[netrunnerse] +Image = "Netrunner.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[netrunner rolling] +Image = "Netrunner.png" +;detected in "/etc/os-release" +;wrong in "/etc/manjaro-release" Manjaro + +[voidlinux] +Image = "Void.png" +;detected in "lsb_release -a"" + +[void] +Image = "Void.png" +;detected in "/etc/os-release" + +[arch] Image = "Arch.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[Cobalt] +[cobalt] Image = "Cobalt.png" Files = "/etc/cobalt-release" -[LinuxFromScratch] +[linuxfromscratch] Image = "LFS.png" Files = "/etc/lfs-release" -[Rubix] +[rubix] Image = "Rubix.png" Files = "/etc/rubix-version" -[Tails] +[tails] Image = "Tails.png" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[Tanglu] +[tanglu] Image = "Tanglu.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/debian_version" Debian -[Tanglu GNU/Linux] +[tanglu gnu/linux] Image = "Tanglu.png" ;detected in "/etc/os-release" -[Mer] +[gnoppix] +Image = "Gnoppix.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[kali] +Image = "Kali.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[kali gnu/linux] +Image = "Kali.png" +;detected in "/etc/os-release" + +[urukos] +Image = "Uruk.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[pureos] +Image = "PureOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[pureos gnu/linux] +Image = "PureOS.png" +;detected in "/etc/os-release" + +[septor] +Image = "Septor.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[salentos] +Image = "SalentOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[pop] +Image = "Pop.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[pop!_os] +Image = "Pop.png" +;detected in "/etc/os-release" + +[mer] Image = "Mer.png" Mode = "Analyse" Files = "/etc/mer-release;/etc/meego-release;/etc/moblin-release" ;detected in "lsb_release -a" ;detected in "/etc/system-release" -[KaOS] +[kaos] Image = "KaOS.png" Files = "/etc/KaOS-release" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" -[CoreOS] +[openmamba] +Image = "OpenMamba.png" +Files = "/etc/openmamba-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;detected in "/etc/system-release" + +[coreos] Image = "CoreOS.png" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" -[BOSS] +[container linux by coreos] +Image = "Container.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[parrot] +Image = "Parrot.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[parrot os] +Image = "Parrot.png" +;detected in "/etc/os-release" + +[boss] Image = "BOSS.png" Name = "BOSS GNU/Linux" Files = "/etc/boss_version" ;detected in "lsb_release -a" ;wrong in "/etc/debian_version" Debian -[BOSS GNU/Linux] +[boss gnu/linux] Image = "BOSS.png" ;detected in "/etc/os-release" -[BOSS Server Beta] +[boss server beta] Image = "BOSS.png" ;detected in "lsb_release -a" -[Canaima] +[solus] +Image = "Solus.png" +Files = "/etc/solus-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[solus operating system] +Image = "Solus.png" +;detected in "/etc/os-release" + +[canaima] Image = "Canaima.png" Name = "Canaima GNU/Linux" Files = "/etc/canaima_version" ;detected in "lsb_release -a" ;wrong in "/etc/debian_version" Debian -[Canaima GNU/Linux] +[canaima gnu/linux] Image = "Canaima.png" ;detected in "/etc/os-release" -[Semplice] +[ubuntu runtu] +Image = "Runtu.png" +;detected in "/etc/lsb-release" +;wrong detected in "lsb_release -a" Ubuntu +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[semplice] Image = "Semplice.png" Name = "Semplice" Files = "/etc/semplice_version" @@ -179,78 +712,139 @@ Files = "/etc/semplice_version" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[SolydXK] +[solydxk] Image = "SolydXK.png" +Name = "SolydXK" +Mode = "Detection" +Files = "/etc/solydxk/info" +Files2 = "/etc/solydxk/info" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -;detected in "/etc/solydxk/info" ;wrong in "/etc/os-release" Debian GNU/Linux ;wrong in "/etc/debian_version" Debian -[HandyLinux] +[handylinux] Image = "Handy.png" Files = "/etc/handylinux_version" ;detected in "lsb_release -a" ;wrong in "/etc/os-release" Debian GNU/Linux ;wrong in "/etc/debian_version" Debian -[Parsix] +[parsix gnu/linux] +Image = "Parsix.png" +;detected in "/etc/os-release" but sometimes wrong version +;wrong in "/etc/debian_version" Debian + +[parsix] Image = "Parsix.png" Files = "/etc/parsix-version" ;detected in "lsb_release -a" -;detected or wrong version in "/etc/os-release" | Parsix 4.0 ;wrong in "/etc/debian_version" Debian -[Linaro] +[linaro] Image = "Linaro.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[LinuxDeepin] +[endless] +Image = "Endless.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[uos] +Image = "UOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[deepin] +Image = "Deepin.png" +Files = "/etc/deepin-version" +Mode = "Detection" +Files2 = "/etc/deepin-version" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[linuxdeepin] Image = "Deepin.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/os-release" Debian GNU/Linux ;wrong in "/etc/debian_version" Debian -[Ultimate_Edition] +[ultimate_edition] Image = "UltimateEdition.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[elementary OS] +[elementary] +Image = "elementaryOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[elementary os] Image = "elementaryOS.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[PearLinux] +[jingos] +Image = "JingOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[kde neon] +Image = "KDEneon.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[kde] +Image = "KDEneon.png" +;detected in "lsb_release -a" + +[neon] +Image = "KDEneon.png" +;detected in "/etc/lsb-release" + +[pearlinux] Image = "Pear.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/os-release" Ubuntu ;wrong in "/etc/debian_version" Debian -[Pear Linux] +[pear linux] Image = "Pear.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/os-release" Ubuntu ;wrong in "/etc/debian_version" Debian -[PearOS] +[pearos] Image = "Pear.png" -;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -;wrong in "/etc/os-release" Ubuntu +;detected in "/etc/os-release" (simetimes wrong Ubuntu) ;wrong in "/etc/debian_version" Debian -[SolusOS] +[neon pearos] +Image = "Pear.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[solusos] Image = "SolusOS.png" Files = "/etc/solusos_version" ;detected in "lsb_release -a" @@ -258,79 +852,139 @@ Files = "/etc/solusos_version" ;wrong in "/etc/os-release" Debian GNU/Linux ;wrong in "/etc/debian_version" Debian -[LinuxMint] +[linuxmint] Image = "Mint.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/os-release" Ubuntu ;wrong in "/etc/debian_version" Debian -[Trisquel] +[linux mint] +Image = "Mint.png" +;detected in "/etc/os-release + +[lmde] +Image = "Mint.png" +;detected in "/etc/os-release" + +[trisquel] Image = "Trisquel.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/os-release" Ubuntu ;wrong in "/etc/debian_version" Debian -[Zorin] +[zorin] Image = "Zorin.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong or almost in "/etc/os-release" Ubuntu | Zorin OS ;wrong in "/etc/debian_version" Debian -[Zorin OS] +[zorin os] Image = "Zorin.png" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[Netrunner] -Image = "Netrunner.png" -;detected in "lsb_release -a" -;detected in "/etc/lsb-release" -;detected in "/etc/os-release" -;wrong in "/etc/debian_version" Debian - -[NetrunnerSE] -Image = "Netrunner.png" -;detected in "lsb_release -a" -;detected in "/etc/lsb-release" -;wrong in "/etc/debian_version" Debian - -[Netrunner Rolling] -Image = "Netrunner.png" -;detected in "/etc/os-release" -;wrong in "/etc/manjaro-release" Manjaro - -[Peppermint] +[peppermint] Image = "Peppermint.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[Ubuntu] -Image = "Ubuntu.png" +[nitrux] +Image = "Nitrux.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" ;wrong in "/etc/debian_version" Debian -[Chakra] +[ubuntu vanillaos] +Image = "Vanilla.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[vanillaos] +Image = "Vanilla.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[makululinux] +Image = "Makulu.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu makululinux] +Image = "Makulu.png" +;detected in "lsb_release -a" + +[linuxfx] +Image = "Linuxfx.png" +Name="Linuxfx" +Files = "/etc/fx.version" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[ubuntu linuxfx] +Image = "Linuxfx.png" +;detected in "lsb_release -a" + +[ubuntu] +Image = "Ubuntu.png" +Test = "nolsbfirst" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[chakra] Image = "Chakra.png" Files = "/etc/chakra-release" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[The Chakra-Project] +[the chakra-project] Image = "Chakra.png" ;detected in "/etc/os-release" -[IYCC] -Image = "iycc.png" +[iycc] +Image = "IYCC.png" ;detected in "/etc/lsb-release" -[Mageia] +[openeuler] +Image = "openEuler.png" +Files = "/etc/openEuler-release" +;detected in "lsb_release -a" +;detected in "/etc/os-release" +;detected in "/etc/system-release" + +[risios] +Image = "risiOS.png" +;detected in "lsb_release -a" +;detected in "/etc/fedora-release" +;detected in "/etc/os-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[hipserv] +Image = "HipServ.png" +;detected in "/etc/redhat-release" + +[neokylin] +Image = "NeoKylin.png" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[neokylin linux desktop] +Image = "NeoKylin.png" +Files = "/etc/neokylin-release;/etc/cs2c-release" +;detected in "lsb_release -a" +;detected in "/etc/os-release" + +[mageia] Image = "Mageia.png" Files = "/etc/mageia-release" ;detected in "lsb_release -a" @@ -340,161 +994,305 @@ Files = "/etc/mageia-release" ;detected in "/etc/redhat-release" ;detected in "/etc/os-release" -[PLD Linux] +[pld linux] Image = "PLD.png" Files = "/etc/pld-release" ;detected in "/etc/os-release" -[LFS] +[lfs] Image = "lfs.png" Files = "/etc/lfs-release;/etc/lfs_version" -[HLFS] +[hlfs] Image = "lfs.png" Files = "/etc/hlfs-release;/etc/hlfs_version" -[Synology] +[synology] Image = "Synology.png" Mode = "Detection" Files = "/etc/synoinfo.conf" Files2 = "/etc/VERSION" -[Alpine] -Name = "Alpine" +[alpine] Image = "Alpine.png" +Name = "Alpine" Files = "/etc/alpine-release" -[Puppy] -Image = "Puppy.png" +[fatdog64 linux] +Image = "Fatdog.png" +;detected in "/etc/os-release" + +[fatdog64] +Image = "Fatdog.png" +Name = "Fatdog64 Linux" +Files = "/etc/fatdog-version" ;detected in "/etc/DISTRO_SPECS" -[Lucid] +[puppy] +Image = "Puppy.png" +Name = "Puppy" +;detected in "/etc/os-release" +;detected in "/etc/DISTRO_SPECS" + +[lucid] +Image = "Puppy.png" Name = "Lucid Puppy" +;detected in "/etc/DISTRO_SPECS" + +[slacko puppy] Image = "Puppy.png" ;detected in "/etc/DISTRO_SPECS" -[Slacko Puppy] +[wary puppy] Image = "Puppy.png" ;detected in "/etc/DISTRO_SPECS" -[Wary Puppy] -Image = "Puppy.png" +[quirky] +Image = "EasyOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[easyos] +Image = "EasyOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[easy os] +Image = "EasyOS.png" ;detected in "/etc/DISTRO_SPECS" -[Turbolinux] +[easy beaver] +Image = "EasyOS.png" +;detected in "/etc/DISTRO_SPECS" + +[easy pyro64] +Image = "EasyOS.png" +;detected in "/etc/DISTRO_SPECS" + +[easy buster64] +Image = "EasyOS.png" +;detected in "/etc/DISTRO_SPECS" + +[easy dunfell64] +Image = "EasyOS.png" +;detected in "/etc/DISTRO_SPECS" + +[easyos kirkstone64] +Image = "EasyOS.png" +;detected in "/etc/DISTRO_SPECS" + +[turbolinux] Image = "Turbo.png" Files = "/etc/turbolinux-release" -[Amazon] +[amazon] Image = "Amazon.png" ;detected in "/etc/system-release" -[AmazonAMI] +[amazonami] Image = "Amazon.png" ;detected in "lsb_release -a" -[RedFlag] +[amazon linux ami] +Image = "Amazon.png" +;detected in /etc/os-release + +[redflag] Image = "RedFlag.png" Files = "/etc/redflag-release" ;detected in "/etc/system-release" -[Red Flag inWise] +[red flag inwise] Image = "RedFlag.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" -[StartOS] +[startos] Image = "StartOS.png" Files = "/etc/startos-release" ;detected in "lsb_release -a" -[PisiLinux] +[openelec] +Image = "OpenELEC.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" + +[libreelec] +Image = "LibreELEC.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" + +[lakka] +Image = "Lakka.png" +;detected in "lsb_release -a" +;detected in "/etc/os-release" + +[pisilinux] Image = "Pisi.png" Files = "/etc/pisilinux-release" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[Pisi_Linux] +[pisi_linux] Image = "Pisi.png" ;detected in "/etc/system-release" -[SME] +[springdale linux] +Image = "Springdale.png" +;detected in "/etc/os-release" + +[springdale] +Image = "Springdale.png" +Files = "/etc/PU_IAS-release;/etc/puias-release;/etc/springdale-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[nethserver] +Image = "NethServer.png" +Files = "/etc/nethserver-release" +;detected in "/etc/os-release" +;wrong in "/etc/centos-release" CentOS +;wrong in "/etc/redhat-release" CentOS +;wrong in "/etc/system-release" CentOS + +[sme] Image = "SMEServer.png" Files = "/etc/e-smith-release" ;wrong in "/etc/centos-release" CentOS ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[SMEServer] +[smeserver] Image = "SMEServer.png" ;detected in "lsb_release -a" -[Scientific] +[koozali sme server] +Image = "SMEServer.png" +;detected in "/etc/os-release" + +[scientific] Image = "Scientific.png" ;detected in "lsb_release -a" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[ScientificSL] +[scientificsl] Image = "Scientific.png" ;detected in "lsb_release -a" -[ScientificCERNSLC] +[scientificcernslc] Image = "Scientific.png" ;detected in "lsb_release -a" -[ScientificFermi] +[scientificfermi] Image = "Scientific.png" ;detected in "lsb_release -a" -[ScientificFermiLTS] +[scientificfermilts] Image = "Scientific.png" ;detected in "lsb_release -a" -[ScientificSLF] +[scientificslf] Image = "Scientific.png" ;detected in "lsb_release -a" -[ClearOS] +[clear linux os] +Image = "Clear.png" +;detected in "/etc/os-release" + +[clearos] Image = "ClearOS.png" Files = "/etc/clearos-release" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[CloudLinuxServer] +[cloudlinuxserver] Image = "Cloud.png" ;detected in "lsb_release -a" -[CloudLinux] +[cloudlinux] Image = "Cloud.png" Files = "/etc/CloudLinux-release" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -; at the end because some distros may also have the same files (like SMEServer) -[CentOS] +[almalinux] +Image = "Alma.png" +Files = "/etc/almalinux-release" +;detected in "lsb_release -a" +;wrong in "/etc/centos-release" CentOS +;detected in "/etc/os-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[virtuozzo linux] +Image = "Virtuozzo.png" +;detected in "/etc/os-release" + +[virtuozzo] +Image = "Virtuozzo.png" +Files = "/etc/vzlinux-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[rocky linux] +Image = "Rocky.png" +;detected in "/etc/os-release" + +[rocky] +Image = "Rocky.png" +Files = "/etc/rocky-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[eurolinux] +Image = "EuroLinux.png" +Files = "/etc/el-release" +;detected in "lsb_release -a" +;detected in "/etc/os-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[centosstream] Image = "CentOS.png" +;detected in "lsb_release -a" + +[centos stream] +Image = "CentOS.png" +;detected in "/etc/os-release" + +[centos linux] +Image = "CentOS.png" +;detected in "/etc/os-release" + +; at the end because some distros may also have the same files (like SMEServer, AlmaLinux, NethServer) +[centos] +Image = "CentOS.png" +Test = "nolsbfirst" Files = "/etc/centos-release" ;detected in "lsb_release -a" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[Oracle] +[oracle] Image = "Oracle.png" Files = "/etc/oracle-release;/etc/enterprise-release" ;detected in "/etc/system-release" ;wrong in "/etc/redhat-release" RedHat -[OracleServer] +[oracleserver] Image = "Oracle.png" ;detected in "lsb_release -a" -[EnterpriseEnterpriseServer] +[enterpriseenterpriseserver] Image = "Oracle.png" ;detected in "lsb_release -a" -[PCLinuxOS] +[pclinuxos] Image = "PCLinuxOS.png" Files = "/etc/pclinuxos-release" ;detected in "lsb_release -a" @@ -503,7 +1301,12 @@ Files = "/etc/pclinuxos-release" ;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" ;detected in "/etc/redhat-release" -[Salix] +[absolute] +Image = "Absolute.png" +;delected in "/etc/os-release" +;wrong in "/etc/slackware-version" Slackware + +[salix] Image = "Salix.png" Mode = "Detection" Files = "/etc/salix-update-notifier.conf" @@ -511,48 +1314,66 @@ Files2 = "/etc/slackware-version" ;wrong in "/etc/os-release" Slackware ;wrong in "/etc/slackware-version" Slackware -[Slax] +[slax] Image = "Slax.png" Files = "/etc/slax-version" ;wrong in "/etc/os-release" Slackware ;wrong in "/etc/slackware-version" Slackware -[SMS] +[sms] Image = "SMS.png" Files = "/etc/sms-version" ;detected in "/etc/os-release" ;wrong in "/etc/slackware-version" Slackware -[Porteus] +[porteus] Image = "Porteus.png" Files = "/etc/porteus-version" ;wrong in "/etc/os-release" Slackware ;wrong in "/etc/slackware-version" Slackware -[Vector] +[vector] Image = "Vector.png" Files = "/etc/vector-version" ;wrong in "/etc/slackware-version" Slackware -[Zenwalk] -Name = "Zenwalk" +[zenwalk] Image = "Zenwalk.png" +Name = "Zenwalk" Files = "/etc/zenwalk-version" ;detected in "/etc/os-release" ;wrong in "/etc/slackware-version" Slackware -[Calculate] +[slackware] +Image = "Slackware.png" +Files = "/etc/slackware-release" +;detected in "/etc/os-release" +;detected in "/etc/slackware-version" + +[calculate] Image = "Calculate.png" ;detected in "/etc/gentoo-release" ;wrong in "/etc/os-release" Gentoo -[Tizen] +[redcore] +Image = "Redcore.png" +;detected in "/etc/gentoo-release" +;detected in "/etc/os-release" + +[exherbo] +Image = "Exherbo.png" +Name = "Exherbo Linux" +Mode = "Detection" +Files = "/etc/exherbo-release" +;detected in "/etc/os-release" + +[tizen] Image = "Tizen.png" Files = "/etc/tizen-release" ;detected in "/etc/system-release" ;detected in "/etc/os-release" -[Sabayon] +[sabayon] Image = "Sabayon.png" Files = "/etc/sabayon-release" ;detected in "lsb_release -a" @@ -561,7 +1382,7 @@ Files = "/etc/sabayon-release" ;detected in "/etc/os-release" ;wrong in "/etc/gentoo-release" Gentoo -[VortexBox] +[vortexbox] Image = "VortexBox.png" Name = "VortexBox" Files = "/etc/vortexbox/vortexbox-version" @@ -570,28 +1391,50 @@ Files = "/etc/vortexbox/vortexbox-version" ;wrong in "/etc/system-release" Fedora ;wrong in "/etc/os-release" Fedora -[ALT] +[nobara] +Image = "Nobara.png" +Files = "/etc/nobara-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[nobara linux] +Image = "Nobara.png" +;detected in "/etc/os-release" + +[ultramarine] +Image = "Ultramarine.png" +Files = "/etc/ultramarine-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[ultramarine linux] +Image = "Ultramarine.png" +;detected in "/etc/os-release" + +[alt] Image = "ALT.png" Files = "/etc/altlinux-release" ;detected in "/etc/fedora-release" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[Simply] +[alt linux] +Image = "ALT.png" +;detected in "/etc/os-release" + +[simply] Image = "ALT.png" ;detected in "/etc/fedora-release" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[Simply Linux] +[simply linux] Image = "ALT.png" ;detected in "/etc/os-release" -[ALT Linux] -Image = "ALT.png" -;detected in "/etc/os-release" - -[Fuduntu] +[fuduntu] Image = "Fuduntu.png" Files = "/etc/fuduntu-release" ;detected in "lsb_release -a" @@ -600,60 +1443,92 @@ Files = "/etc/fuduntu-release" ;detected in "/etc/redhat-release" ;detected in "/etc/system-release" -[gNewSense] +[gnewsense] Image = "gNewSense.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/debian_version" Debian -[SteamOS] +[steamos] Image = "SteamOS.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;wrong in "/etc/debian_version" Debian -[SteamOS GNU/Linux] +[steamos gnu/linux] Image = "SteamOS.png" ;detected in "/etc/os-release" -[Raspbian] +[raspbian] Image = "Raspbian.png" ;detected in "lsb_release -a" ;wrong in "/etc/debian_version" Debian -[Raspbian GNU/Linux] +[raspbian gnu/linux] Image = "Raspbian.png" ;detected in "/etc/os-release" -[Debian] -Name = "Debian" +[devuan] +Image = "Devuan.png" +Name = "Devuan" +Files = "/etc/devuan_version" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[devuan gnu/linux] +Image = "Devuan.png" +;detected in "/etc/os-release" + +[debian] Image = "Debian.png" +Test = "nolsbfirst" +Name = "Debian" Files = "/etc/debian_release" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ;detected in "/etc/debian_version" -[Debian GNU/Linux] +[debian gnu/linux] Image = "Debian.png" ;detected in "/etc/os-release" -[openSUSE] +[opensuse] Image = "openSUSE.png" ;detected in "/etc/os-release" ;detected in "/etc/SuSE-release" -[openSUSE project] +[opensuse leap] +Image = "openSUSE.png" +;detected in "/etc/os-release" + +[opensuse tumbleweed] +Image = "openSUSE.png" +;detected in "/etc/os-release" + +[opensuse project] Image = "openSUSE.png" ;detected in "lsb_release -a" -; at the end because some distros may also have the same files (like openSUSE) -[SUSE LINUX] +[suse linux opensuse] +Image = "openSUSE.png" +;detected in "lsb_release -a" + +[suse] +Image = "SUSE.png" +;detected in "/etc/SuSE-release" + +[sles] +Image = "SUSE.png" +;detected in "/etc/os-release" + +; at the end because some distros may also have the same files (like openSUSE, SUSE) +[suse linux] Image = "SUSE.png" Mode = "Analyse" Files = "/etc/SuSE-release;/etc/UnitedLinux-release" ; at the end because some distros may also have the same files (like Sabayon, Calculate) -[Gentoo] +[gentoo] Image = "Gentoo.png" Mode = "Analyse" Files = "/etc/gentoo-release" @@ -661,13 +1536,7 @@ Files = "/etc/gentoo-release" ;detected in "/etc/lsb-release" ;detected in "/etc/os-release" -; at the end because some distros may also have the same files (like Salix, Slax, SMS, Porteus, Vector, Zenwalk) -[Slackware] -Image = "Slackware.png" -Files = "/etc/slackware-release;/etc/slackware-version" -;detected in "/etc/os-release" - -[Qubes] +[qubes] Image = "Qubes.png" Files = "/etc/qubes-release" ;detected in "/etc/fedora-release" @@ -675,7 +1544,7 @@ Files = "/etc/qubes-release" ;detected in "/etc/system-release" ;detected in "/etc/os-release" -[Korora] +[korora] Image = "Korora.png" ;detected in "lsb_release -a" ;detected in "/etc/fedora-release" @@ -684,7 +1553,7 @@ Image = "Korora.png" ;detected in "/etc/os-release" ; at the end because some distros may also have the same files (like Fuduntu, ALT, VortexBox, Qubes, Korora) -[Fedora] +[fedora] Image = "Fedora.png" Mode = "Analyse" Files = "/etc/fedora-release" @@ -693,11 +1562,11 @@ Files = "/etc/fedora-release" ;detected in "/etc/system-release" ;detected in "/etc/os-release" -[FedoraCore] +[fedoracore] Image = "Fedora.png" ;detected in "/etc/lsb-release" -[OpenMandriva] +[openmandriva] Image = "OpenMandriva.png" ;detected in "/etc/rosa-release" ;detected in "/etc/mandriva-release" @@ -706,43 +1575,74 @@ Image = "OpenMandriva.png" ;detected in "/etc/distro-release" ;detected in "/etc/system-release" -[OpenMandriva Lx] +[openmandriva lx] Image = "OpenMandriva.png" ;detected in "/etc/os-release" -[OpenMandrivaLinux] +[openmandrivalinux] Image = "OpenMandriva.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[ROSA MarathonLinux] +[rosa marathonlinux] Image = "ROSA.png" ;detected in "/etc/lsb-release" -[RosaDesktop.Marathon] +[rosadesktop.marathon] Image = "ROSA.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[RosaDesktop.Fresh] +[rosadesktop.fresh] Image = "ROSA.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" -[ROSA Desktop Fresh] +[rosa desktop fresh] Image = "ROSA.png" ;detected in "/etc/os-release" -[ROSA Marathon] +[rosa marathon] Image = "ROSA.png" ;detected in "/etc/os-release" -[ROSAEnterpriseServer] +[rosaenterpriseserver] Image = "ROSA.png" ;detected in "lsb_release -a" +[manjarolinux] +Image = "Manjaro.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[manjaro-arm] +Image = "Manjaro.png" +Name = "Manjaro ARM" +Files = "/etc/manjaro-arm-version" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/arch-release" Arch + +; at the end because some distros may also have the same files (like BigLinux, Mabox, Netrunner) +[manjaro linux] +Image = "Manjaro.png" +Files = "/etc/manjaro-release" +;detected in "/etc/os-release" + +[arch linux arm] +Image = "Arch.png" +;detected in "/etc/os-release" + +; at the end because some distros may also have the same files (like XeroLinux-KDE, CachyOS, Archcraft, Snal, Archman, RebornOS, BluestarLinux, EndeavourOS, Arco, Garuda, BigLinux, Mabox, Manjaro ARM) +[arch linux] +Image = "Arch.png" +Mode = "Analyse" +Files = "/etc/arch-release" +;detected in "/etc/os-release" + ; at the end because some distros may also have the same files (like OpenMandriva) -[ROSA] +[rosa] Image = "ROSA.png" Mode = "Analyse" Files = "/etc/rosa-release" @@ -752,13 +1652,13 @@ Files = "/etc/rosa-release" ;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" ;detected in "/etc/redhat-release" -[MandrivaLinux] +[mandrivalinux] Image = "Mandrake.png" ;detected in "lsb_release -a" ;detected in "/etc/lsb-release" ; at the end because some distros may also have the same files (like Mageia, PCLinuxOS, ROSA, OpenMandriva) -[Mandriva] +[mandriva] Image = "Mandrake.png" Mode = "Analyse" Files = "/etc/mandriva-release" @@ -766,34 +1666,38 @@ Files = "/etc/mandriva-release" ;detected in "/etc/redhat-release" ; at the end because some distros may also have the same files (like Mandriva, Mageia, PCLinuxOS, ROSA, OpenMandriva) -[Mandrake] +[mandrake] Image = "Mandrake.png" Mode = "Analyse" Files = "/etc/mandrake-release;/etc/mandrakelinux-release" -; at the end because some distros may also have the same files (like SMEServer, Fuduntu, ALT, VortexBox, Qubes, Korora, Fedora, CentOS, Oracle, Scientific, CloudLinux, Mandrake, MandrivaLinux, Mageia, PCLinuxOS, ROSA, OpenMandriva) -[RedHat] +; at the end because some distros may also have the same files (like SMEServer, Fuduntu, ALT, VortexBox, Qubes, Korora, Fedora, CentOS, Oracle, Scientific, CloudLinux, Mandrake, MandrivaLinux, Mageia, PCLinuxOS, ROSA, OpenMandriva, HipServ, NeoKylin, Springdale, Rocky, EuroLinux, AlmaLinux, Virtuozzo, NethServer) +[redhat] Image = "RedHat.png" Mode = "Analyse" Files = "/etc/redhat-release;/etc/redhat_version" ;detected in "/etc/system-release" -[Red Hat Enterprise Linux Everything] +[red hat enterprise linux server] Image = "RedHat.png" ;detected in "/etc/os-release" -[RedHatEnterpriseES] +[red hat enterprise linux everything] +Image = "RedHat.png" +;detected in "/etc/os-release" + +[redhatenterprisees] Image = "RedHat.png" ;detected in "lsb_release -a" -[RedHatEnterpriseAS] +[redhatenterpriseas] Image = "RedHat.png" ;detected in "lsb_release -a" -[RedHatEnterpriseServer] +[redhatenterpriseserver] Image = "RedHat.png" ;detected in "lsb_release -a" -[RedHatEnterpriseClient] +[redhatenterpriseclient] Image = "RedHat.png" ;detected in "lsb_release -a" diff --git a/root/opt/phpsysinfo/data/languages.ini b/root/opt/phpsysinfo/data/languages.ini index c93aea4..eb3a21c 100644 --- a/root/opt/phpsysinfo/data/languages.ini +++ b/root/opt/phpsysinfo/data/languages.ini @@ -304,6 +304,7 @@ _en_BE="English Belgium" _en_BW="English Botswana" _en_BZ="English Belize" _en_CA="English Canada" +_en_DK="English Denmark" _en_Dsrt="English (Deseret)" _en_Dsrt_US="English United States (Deseret)" _en="English" @@ -687,7 +688,6 @@ _nob="Norwegian BokmÃ¥l" _no_NO="Norwegian Nynorsk Norway" _no_NO_NY="Norwegian Nynorsk Norway" _no="Norwegian" -_no="Norwegian Nynorsk" _nor="Norwegian" _norwegian="Norwegian" _nr="South Ndebele" diff --git a/root/opt/phpsysinfo/data/osnames.ini b/root/opt/phpsysinfo/data/osnames.ini index 08751d6..b42cad9 100644 --- a/root/opt/phpsysinfo/data/osnames.ini +++ b/root/opt/phpsysinfo/data/osnames.ini @@ -18,8 +18,13 @@ 5.0="Lollipop" 5.1="Lollipop" 6.0="Marshmallow" +7.0="Nougat" +7.1="Nougat" +8.0="Oreo" +8.1="Oreo" +9.0="Pie" -[OS X] +[macOS] 10.0="Cheetah" 10.1="Puma" 10.2="Jaguar" @@ -32,3 +37,31 @@ 10.9="Mavericks" 10.10="Yosemite" 10.11="El Capitan" +10.12="Sierra" +10.13="High Sierra" +10.14="Mojave" +10.15="Catalina" +11="Big Sur" +12="Monterey" +13="Ventura" +14="Sonoma" + +[win10] +10240="1507" +10586="1511" +14393="1607" +15063="1703" +16299="1709" +17134="1803" +17763="1809" +18362="1903" +18363="1909" +19041="2004" +19042="20H2" +19043="21H1" +19044="21H2" +19045="22H2" +21996="leaked" +22000="21H2" +22621="22H2" +22631="23H2" diff --git a/root/opt/phpsysinfo/data/raspberry.ini b/root/opt/phpsysinfo/data/raspberry.ini new file mode 100644 index 0000000..ef37b01 --- /dev/null +++ b/root/opt/phpsysinfo/data/raspberry.ini @@ -0,0 +1,46 @@ +[old] +2="B (PCB 1.0 Egoman)" +3="B ECN0001 (PCB 1.0 Egoman)" +4="B (PCB 2.0 Sony UK)" +5="B (PCB 2.0 Qisda)" +6="B (PCB 2.0 Egoman)" +7="A (PCB 2.0 Egoman)" +8="A (PCB 2.0 Sony UK)" +9="A (PCB 2.0 Qisda)" +13="B (PCB 2.0 Egoman)" +14="B (PCB 2.0 Sony UK)" +15="B (PCB 2.0 Qisda)" +16="B+ (PCB 1.0 Sony UK)" +17="Compute Module (PCB 1.0 Sony UK)" +18="A+ (PCB 1.1 Sony UK)" +19="B+ (PCB 1.2 Embest)" +20="Compute Module (PCB 1.0 Embest)" +21="A+ (PCB 1.1 Embest)" + +[model] +0="A" +1="B" +2="A+" +3="B+" +4="2 B" +5="Alpha" +6="Compute Module" +8="3 B" +9="Zero" +10="Compute Module 3" +12="Zero W" +13="3 B+" +14="3 A+" +16="Compute Module 3+" +17="4 B" +19="400" +20="Compute Module 4" +21="Compute Module 4S" +23="5" + +[manufacturer] +0="Sony UK" +1="Egoman" +2="Embest" +3="Sony Japan" +4="Embest" diff --git a/root/opt/phpsysinfo/gfx/attention.gif b/root/opt/phpsysinfo/gfx/attention.gif new file mode 100644 index 0000000000000000000000000000000000000000..48ede3f50e80dd1526dab18daae3c0f958d59741 GIT binary patch literal 1044 zcmZ?wbhEHbRA5kG_|Cw>dQoelp^5of*Bgc+RnKb3fwJUF4z4`O+&z@a-RMb@7 z0Hq#1IdbU8n|E(a%uIOrcuI;&7)HTp2n@;)Q2fcl$iN`MpaXIpC{M6+d}J`>knz~C z;9xU{uvW|ofo4W#US+PD9|1|u%)C+#TULBXJk}*6nDk|bVT$7Ynp^?};f!{eoA!0@HnVG6A7qSjEKR<2s`q`8K#skfl=GmV2P)wxe{Jl>AlVqANK^=g7O8zm6dF0GH4j!HrD}0x9K}XT z8$?J6m55qZid3a4PgPqK{(yqi<|zsg2qjXSNER_zB|*h8?Dy{M&h5jl7t@fKQXmf< z>FCbAqkGQpoOAD;b44k|*ZF9C&5!$DCmt2)S#4QUPOX-`RIMI5pwx|r2Jn3m>xaqY z-};A!Qq^h|{q*TU;M)%^1=}=jylegXRQ>I@F+ci<)ZpOOqaxpXC;($3q13u{FSac% zQp)AXU%pIK*Xc|qkBG>F2l$q*znDm;!-X?vFg9*Pi^r**KTk&{v-UTz^ML~VOeD5u z-MVq_)vMT*3TR-r`%F$wa_H4pu@@HbJ^eK1`t=lNW{5?j)>_j%a91HvN`0jqgyFw$+N5T> zyVY5bN6nr)rxtQKb?n$N1t`DYuV!aw)zw^1&A#=PIt}W>t}gZ0{{Gqlcw{C0D@Gs_ zjUHYd43fWe32WCbT$v2@Vv$fN1VAhn!!%8tn>R7HZNu8Kh2kflusRTM_4s^;|EClj z5!u}F=%e4^gAbss4Rg;P$mLLgWmy22rioz~0Epw@-@hLR(C6ogr&8Nr6WMsr0Nt_J zFTY_~8Q^fTJSc zP4xF~axPpz3x_dx?}ls^5kV={0`Pb|xLhto1Ocd22ux3drXh24#1n}vuZwK^uK_wc zIu1v5ox*3I;oG|xS0VwneH%bmR~Nm#y{$PS0>vVp#~!0?bd=KKB2kx%WH@}}%k0RV zO0r*zj6D9t6MykvxIo42Ci3pPh+!c0dV^Zi&@_#cCr`3w%^HS=hNx63jVOp9UN6r4 zJpbIV0mJ2DF`48aAAkIVy-NLQ#R!Oq)|pPf5>|@B=bz)7m_Un0ky@?gWiS}z`0?Y6 zjg7H=`*yBfyM|#HEda`8jDZ1y&pk(}P#{vTlZZqP^@!*z0{j-n61}~TRL`A5PbM)( zMY@(##mvy6<4aN@)XPMtbMJRZlk?c3KvrGk-86CNL@T&)r;mx)KC zKmU>g{FK*|QDfj&lp3x!N^N!*3YWfs$>1Ap$M$9EZ6~ zhWh2plu{`^ymIB>u3GKoFBGMZi|8+9GSB<7S#A`IcuFO5Q&UhX-SVpO(%5byEG`@W z&z21+TzO)&r+a4p+K4p0Z|rc{8k zQp#CT_uXDjn~O_p%98P=i-1}N;Q-EE>;1pK9se7g#AV9-JfD030000DzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/body.gif b/root/opt/phpsysinfo/gfx/body.gif new file mode 100644 index 0000000000000000000000000000000000000000..76d78ff7368e6e6575760c6c93ac2ee4f6c85faa GIT binary patch literal 551 zcmV+?0@(dWNk%w1VblXM0J8u900030|Noe{IIPe>qQpFkrZcI`KmY� z00000000000000000000A^8LW000L7EC2ui0Mr9A00RX7aL8$hC@1U9yZ>M)j$~<` zXsWJk>%MR-&vb3yc&_h!@BhG{uv8Eb43ng?av3_G(5Q4uty-_xtai)odQHWnay(#S zzUZ`i&2GEj@VIQ#>>pj&d<<2 z$YaXU*4NnC+RM{Rire7f;^X9<-HA=*>g(+7?qBB=-|zJG_V@TP@tO1a{{H|2zS~!( zpTL6%6Dll5u-d|h5F<+D)X?C>ix@L%+*2{##*ZM>LyELyfIXxF5ka^>G};!xUkv5h7&8cig>Z( z$4DDPo=o|sxm8?i70Nq_#ntw2g5z$e5NNdN!;f5r}rH5VKf z9kJf xwz>y})(c4bOm&z5y-YU)ak z9NM#F(VU*PmMxps)RdJR*|%lRtSM_&Eoo`1`Sb73o=s~QM!{$Z4A~G+{K>+|z`)9& z1M&eVPq1@%F>rIpcx+g3u$eY&g(xoRve!E5c#n nlO|41$&x=S6c#e{h%>5`Txe)$VrNh?xN~yz^7Hc;85yhrRBuWk literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png deleted file mode 100644 index b47ce55f685dac56ee9d63f2c3d426bfc4c9e31a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h^mK6y(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz1H+_;eX)`ni0%X8XBDc-`=Ph(Uan2 zYsR{H!kvIN--9isvHznRswz>y})(c4bOm&z5y-YU)ak z9NM#F(VU*PmMxps)RdJR*|%lRtSM_&Eoo`1`Sb73o=s~QM!{$Z4A~G+{K>+|z`)9& z1M&eVPq1_NFmQ9ocx+g3u$eY&gKc%FHdGGG#+U p(@9ogA)^;R3LBeRm<-}rCR}i2X5x}#=s2)p`T6+{^=vE*)&RS`Njv}m literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png deleted file mode 100644 index 9ab4a89664eee1aa81a51ca127f64cb3ac6fa918..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz4q@v|B?28{s)#N@CGn3@%_y|zAV9T z66e<&B4?b6oF&azg|C(V&1ZbI_D}pL`}(^FT2yXwG1Ph~$Q@h8mJYOz!PC{xWt~$( F699+YQR)By diff --git a/root/opt/phpsysinfo/gfx/down_black.gif b/root/opt/phpsysinfo/gfx/down_black.gif new file mode 100644 index 0000000000000000000000000000000000000000..81ba91c9702f98f72bf5ae3f793bc7107e58bb6a GIT binary patch literal 65 zcmZ?wbhEHb6ky0r5dH3``O|{VPwusxdJ#QBhM_vue$qdv|=id>BT-Xb23B5K#Qd0(OWFhy>*cc8)3r zMh+Q|4GRu7a|mmNWH=t_Xp-jPa7l1{z|P9TQNUoJ(89*X#LzM$VIxxmo2r{gfkQ!x zXQQBj$b}CH3%nWRg$fiVE@WmB5Z6!;@Dx&K;b*tvadB{Dx;ULpou#7d@)HM61+f;6 a%F9O%H}cC^tl&&IbfGol@*-Xi25SKAa8xS* literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/favicon.png b/root/opt/phpsysinfo/gfx/favicon.png deleted file mode 100644 index 80dd64e0c7e6a25752bac52437a4bfef0c589f4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 479 zcmV<50U-W~P)m_3WWmw zexG{1P7nkL-zRf>%faNSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!CBxDS21sKW1hYdg=l;!>QLVWQRQqQs@DC8gTg z;vvBK?{MYZ$!Bgn-6MC^=IGSYb;j1k@88^zXZR5uu~H~(Rm)VZ#HC)y%+57o+75Al zi*~lWE&Kg!tBx4Ag$!T+eE;_EYp-X|buMXLa5by(W=>m#&Nq$ub(?QCTz=V7VYBXY zlvFR$9Jn@~jSobB)5>_L*enk;3!A_S)3+L_4+pb;x{deqj=S??tSeO_& z*qSGtewy;X#_qE1)1pYL#&t9NmOuFX^T7M>n;EsHcJTzP4J)-}5kD@+cH!N<>x>17 zb6D!5*IwJsko3`Mp@ZV@zx&?I_fvnhG)QyTtsJwPzqK6JUtjE)6sXs5_~8P>&p-dX z)x7=I?5o>i!Pt*;yYH=MEZZ%cYs+`&{);%~J9*}_M2;u)T0bq?nId0(F=I*=&+@mm zJOw*rGHw?hQ2&tsq-^(7rL9rDPW)`l9%_@fC?^GdiCZ6jO`iF|Zejm#ohMV6-}0BC54St*_@8JZmHFmtRqd4X`iktd43<~ch13&w#8>^ z)dLmBaq2nC%o2X5_^(0=`}=+|jGud+rN!r5oBxD^oXA0 zhNtId9^3ujB~!yctCDuR4c*-hzPvjfg9LrsJ802=*`jZqAuKJCNTgCJAw&51_&A%* z(iFi{tE=<#^RSFLJ3E8Y=kt*OKqkz# zx3_n2a4U1(%b21$ur`|w>7&so6GS2r02}};92t3|7AV&0KeZa5)}#s)CkgSHsi#~}fZWN{(jfO4ZsFAYKXsoQPFy`MK;JF0?0m^Yhf~%`5YFZ|f0j7H4hT|n? zfLg5vi<_#`=}`Nx&cKr-O}AL0ZWnYP+U>@rXoCdQie6yQqF$XLe$XOnMK2Kf{OHH~ S4-Y$kl5Px#1ZP1_K>z@;j|==^ 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 literal 4217 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 M07*qoM6N<$g0azQO#lD@ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Alma.png b/root/opt/phpsysinfo/gfx/images/Alma.png new file mode 100644 index 0000000000000000000000000000000000000000..04a0a5f6917ae3172c7147a6e701442917cc884a GIT binary patch literal 1208 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 ge~GN~{{h3yubf_3fUT{~EtOR{O! zoFS*LifiBV(FQT{86SL`ovEQ6UfSxStvT}MxSYByXK%0u2k)(BfkNI>#k#9#n}@c0 zXrPewR?DeNlF!JQYXT=!PXER_i{;;=yzj8M)JYqiw4+c8&KjL!{1ofRlQ*yMp`&8_ zw49yb18=gEyT#-f>!}iB0oIzsx+~@67;Vm!e3msO^ZwV_slDQ-Px!gxtR;(I_(-xD zaj}^X9b=s(?8`FtRXHDghkj8cF1Cm(J>r)p4*9p|@_{3)DTSYVUtH~{?fI<3D{uWt z+udSfSX@8PnzxFHA8CV=cUSR~yJ(w>wq&!Or)i*o57+bIkJ;H;)_0iq)k=0tPX5Z; za%qEuHab|NLrMw9@&8!F4%9CnJ5Gp&)Rg+l;5Zg@ki`s+v4brGYv3qC4(9JXL`Zlq zK9&=4;ZcNG`b+vwTUw&YD8Lm}n+zWCp@N}n2=0D0!U~M3P_*rtm8-!B z4tQ(uIm*;W#< zMtPlSIjg*6Low`GS`%g3{F|TMtepO&7lW%GHFN+r0$}J%+>d9O9`zlO#FIcVCxD5sX#ju9zOv4*7{@8fXGPat2 z1QJjm)iemR6o3aY0`v;QYLG($vZjPx--H0z4I|yu#3bkBQ38Ps6f@E>DV0Nl(l*aY zi&F}AL_k#2?5a$R2mOZ~CSb=Llu_ld(L6jbf>kNt%#HwTnQIiLrP+;ttH7i&1dzE< zMLPIkt%Ot+DmW_I?K*Z6TzCW2Fab@62(X4A*as+EDPT;@Ap=6e9s~@1KlT9@@KHG- z5RY1*0Ek^Bi7alwkJ)O~L|p26F0n>pGz^0v0`XwL6ySVx;{fqzCO(;Z2z+2QfedUE zCcZayPeG=6t5fbr1Vqd#V6N-Y6)AYR=6*O^?n=#uZ3tkJ*>~RIF>l};0IOJErT#*! z-?QG>{|NsAhVyuGn z#8?ICiLnaO6Jr&mCmy`O<#y-ewEr_%p-(fy?w&bQkiLVvl$1Gn29U4geJEQ4~% z20nNDw))?h&<5oa52~N7k@vjQ{UiMDWHqP|$sq6kq6pVJosT9yJ0uDfA`JxHosbi9 zZ_@4h|NB{bA06ZLyWS}kb9Z{7+wJbAxcf67`QGURTX#{)`z=>rg?)gSkFH1%HqgJKb)7 z9dfT%XSKVX9Tfh>m)1545GHILVL`Q7R<1Ulj?vYh?xwx8ZNd!?b)Lcps3tC)Rn z_uWTU2!Fz1_oiF|$tn zch2|wzVpj>&iT&0-*4^uTq>{^0FXSJJGV1gtvva8?Dyc2BU4OR4{ZMOAYi+$Jmi$a zRtXe4Je}=3dmfYO;-}-p>-936aa-l;mu`o9?9!muXN1lLYcdMP?Y@3jcxD;aZE?f@ z`$S9mi(#@ck)+k}ILgcdi4Y4NvE*T>x$cL-EB>D5s+yu3+*eP&a|V;k$`_bK%m*3<MntbT0|v_fZ2>`bv^+zsy+|J zV!=3fXB#_GLA$k&;ivVa*PIW(XvS+xA%5bH^O5Zh+pgvp;7`$nC$=(j!q<<~J)p$Q zx(zcY8kSo2MyBvZ=6EiBC-r)?@L5Zs1zfCgLjvr*KwYo*Az@U^)PkTDyv~Wfhj(CS z?+B#?WGN_Js$xYlL}hkku*Ph8%=Y$GO~42t2o_h6OL(q&WGRMwAl+j~Y~3Zx^eaBr z;`*k0;(B*#hYzB;9E6JXM^|iZt a6LZ^!qxRn2%XXzcd_0@FI(s|zeD?+d<}PUf diff --git a/root/opt/phpsysinfo/gfx/images/Apple.png b/root/opt/phpsysinfo/gfx/images/Apple.png index ac1178d61d92d4b08838665e972817b7d767b3a8..c8635b410fb28dc9249c6766353440ce3c1215a6 100644 GIT binary patch delta 496 zcmVgJGQ4lbNLs=7I(xE6$6-TJ0!o>g56DXt|P02iUESwe~mggo$hhZ;k{ zYk1BaND>i+@pvD z15MxFq=3AS5vlo2NG(Ju8fZRyvkfHwlBE~|gOUZAzYi#Aoc5!lIL8@MUQTpt6Hc~)EP60k4 zuK)l4-v|bq!C=#-O+en3En9#LAPE!$GJqt64N-$ey5DL}1ezvV666=mpl)bpWAEta zpO#%v-`Kl+_x?kV-&_%DS`Jju?djqeVsU!wBu}A320Se7uAJQp954RYPu1=eKF?ZG z6k2{$Ir5Ucmf9|xh1xw1-&h(JS0)&6CUwiYc@|DmIkeo5Nf2y_Z8I{A#&V zDbsrVgW)e3(`7@4phxznP44$rjF6*2UngDdToo@gD diff --git a/root/opt/phpsysinfo/gfx/images/Archcraft.png b/root/opt/phpsysinfo/gfx/images/Archcraft.png new file mode 100644 index 0000000000000000000000000000000000000000..09e5d9ecc979788191ad0626548f8d785c2d63ce GIT binary patch literal 1442 zcmV;T1zq}yP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1vg1VK~z{rwU=#7 zTU8jx|M#|Zr3Ean1I8^B3N0`gY`_Lc$dE=ef{A9h7&XQZ#HjI;iP0<}%HjtT-3N{F zCGLZ|Xy(3{Wm$ZixW(Y7Ws8f9De^MdV8~!>Kuc+ReV%hKb-a{bCjOGA=bWdfJ^ypg zbIyIP1cT%idebBo4^g#&tcuJ_mP*FVkoA*YBI{M5o*NswI>}$eBd!2vfhS*;q&KMA zL1q`u_$-i}lq7Ut8|)v{T=_90C2;n9IUzvf!Wx&joJ z*G#(3=0UMu6h-RFM07s%C4RErVmCl|)?Dni{fR3bdI^KT_4u z;EE>;X}L*yD=t}NKj^C)B`SdToQjiV+%YbT{xIqvt$=%%qI(Rno$PC8Q3;PFhzg*9 zJ3<8?FGFPJI^Zl*PdnHtuU`?`Px35I^ z8s-IOp|^l5`Umpe78VW3ccx69^{5m6cWG9 zZWn{Ih)g9DS^1gzw}v^G=klb>^e-*cFnYrw!D>NA?9hK1ABpbfaVj^w`>n~zc)a^CEY<{4 zvxINDk7E4F5E3196iJ+ab`b@;3eeH@6l5uc*@;{D{PpAa+_N#c!Cg3$iHRDCpv>ok z$(j^hW{W)$))X6x>#N}2TR{RXuq0U#p_Sn6aAaq|`yeMwakMA9m=cCUsIWUZDw+qeB9YRazA*3tW82fz)XODd=`b`W?qON@(mgeFQKaiSHOpXf}r8eZ^+a(W1nJvdRpsr z51~L1V|{~S_DN|ekG;5pyc{p}zA~ z%ukJB^w+cav*!$gfdJirCcVe{1pNWHDog3o+K1fYJjikw$6xyd^Rsh$4}qVq&a%{E?8R77 z0Zw;$A`SElRYfMOhL#|i>D+Gt;iWJIX>{c-$`Tq!2Kz;tzG7pP0!kPqun5lG{ts@F zHPY<=(weL8s?lMQxBJK@gkx*rwA^>^;LHjEjGnhQkzEjut>GeBgZ|$uSU05a+@6|t zWTbyVk-CkVoG;vOFz`OVPka9KwW0oXUsl%~&ehNnbyBxCsk)h$Q@+^v<@CsXznrc{ we?8~?kyAKc6;5Pgy`KL}ujfPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2E0i`K~z{ry;o~& zR7Dj2=I-rox9xV@ZkN8SwG|LVpyD$aA3qvM#0M%8Ktx5;Pzq=id;uYm5aS~nt6~g^ zAx4p?;Z@YAi9{3;h=o8aP-wTcg+3^>-EO<@d;Mm*RNi!p`X#e-@3}MQeCM1wGqbo7 z9CEpavlYc&hXgIw$BjJ>T|@%@#iGZzI3^krM68b+)eyPRM4c`)0n->U$}pN@pW?!h zBS5@J_K60B4JKB^WN~9i5jX(k3W!=EL^1@Q1VX|v#*H@3!?7WQ#*iXFgXNr=47$$n z^H*3+fhDoeaUt#q92Cgpr2SEdoPLQ^A)_FAG$VTBD42Eq^1&hQ2v~r}G!ry#O8;Xp zJkIBSovVAwNW?NraC7LjfiUX_Ca=}UaC)vCd_?Yluk{uzd4beaVDZK$?aWSOP^)!Y;=MiBT z#>R0b9+rA8hD#FIVM7va?Wf*reH_`!moTS{* zG$V-!;(bc&2}1YV~bGcoHHARbLYXJf!^L8dKrbT zC%|q`LVaBwj(+qWiuP2&!Lc$WQ4{;ROiX+d@GGU~;G&E0TPw1C29`83?%jNs0~7AP z3x&_jM@#GRhT7Vy@<^mHfB5ils^4E<)ZASA^02JTj-t{9@DvrmFA38W9}Os zPxXY1%(T5`$z=2;=qkQZwj_v^p8#1(@j194fp>M>901DX1|xH1u(ypJi@#2F)}J_W zWcH#(ugjp|&O2_tKRw;~Yg_B_TjhIM*-K5KP{&mFm@%h%(wwqLRFzl-G8l<>M+O`Esm+U!ZIc?u@l?e=vw)zz8p zEyt~sN=lk_tL3YRJ5%YCdxJqwoDh#P3U@2v8ITU1g|~IgVYilLC&*kelMC@5ykcEeX`X%nt$$zW{sH2jZ+0(AcvaS11k2 z##Dg2nR>RjccA@fP1V-Q%BMR!yTXx(0bfry=V)+e=fdT5qOGN^Z-3SP``n3oo8Ho< z!Y_?;Ibsxh7yI2NPs}qgKwy;x!&&FA$b~2CT|yEFv&ndg6DN__@Yk%0ci#TQYPJ0u z2=pNwq(6k7U_*L_3s>jmefC7@y*q+?_f1Oi_bTIZ+cwywp<;SiZV}5jXyP$7kr*Jr zT78c>vdglOc{`l~NhV0yNhZs;YtLOT6kIjMqFb)s11l}yZi%IQ!A18IQ zc?Gw7pqV${_1U*gjMzq9H*M!{J0f4MU;o_?-+uGPp+mKHYoa|r-Q~(Y^2NH!NN;bq zUtritf#g$BXlzQKG-hE~*z?kWG1C&nr(&6oM3&i3Zkxr@TNQR1mFGU4kSEy&^7)GF ze_tI!-JSuEj)7g;K$ycUf$6Ak?u?#f5Z3*rRnKu%eHLZ)H&S>8!t|G()-6* z(hs_$aHdeXjBplHA@35r$t)1h3(TkdLmS_vQJ(uUREJ6Qb&57s1l3M_MVMhlj>W`N zJRe>d7DYxkJ(9N-Uaz~v5`hkuohv|QVG9}=n%8)zSo=YEU>W>tn5DzX9dU7zfinK3 zaycmztGJUe$8CNMZ_)Ug_e1dZ5C88lGXd@t1M|7rEWk<)6$=wEEcWex#Ug>MzX6}7 Vjl@5ZeRKc-002ovPDHLkV1j-hZjAr{ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Arco.png b/root/opt/phpsysinfo/gfx/images/Arco.png new file mode 100644 index 0000000000000000000000000000000000000000..f32ace9661ffb7570aa4304294c8b40a7f24fb2b GIT binary patch literal 870 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 a1OEaGb)w}^LoM+D0000rJ%) literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/CachyOS.png b/root/opt/phpsysinfo/gfx/images/CachyOS.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc2fc1e6da31e31378bca67a583abec31cd7ef1 GIT binary patch literal 1588 zcmV-42Fv-0P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1<6T7K~z{r?Ure5 zR8zPFp&q3rkC_Z4oH(1A+u8A`nPOG)Rnmz<{Y53`U~{69Z}_gv7)p z7&ReEqEREDEC!IJZ3-oYQYe&G=x(=}>9n1#GjHDYyf>F=hE7946aBz1eVupidhWSr zd3eZwjlh2=P+8rYSk+s<#cLXlIYuvvEKZ}9xi|s8*V}MoZRJTWPRgVTl%DL`d#(M% z>&dzl1dZKrGdCvP?GB6qvJ6c~#!S7rqUG6bCwR}Ki2OH-=iAtv&cw_uve^xX$%cS; zKCFS6FbQ#dL=0$SNFiELM3N@%U~W>zY2E`=H)~MUz5-RZa(PRHmKFg zgb50)Y++A#1h7gK7w@A z>(IuU@g>Zn*qvpx?BU`#$urzA7Hxv5@CV)!AxeS9VQlP{Fh4Aj28=5pI{?Qez}*IP z9sqo&AnUy0G5pcc|8!m42X(7957O(DiA2GQTP&?{1P#3**wlt#0BGA!r*x`fk~aB5 zX~x_)WaiP`9XyP#LYBrPF<`$?^UNliICUZ`&2M5K*Zc4$7Xi-*(Ecr%-3?I?{b>od zr2{KBp69*yrlvC)QeZn7nVebv6ia5^<~>oU3T$X)1;^aD>I%`_hsd!U-GIFYLZAiA zVuVR={?4G-W2l!-eH0k^ ziJYsQCd$x?I!}J`>>Ygk)X9lAtW_hggn z)Jh3Ofs#vNe9A}HmQ;{7_ep~3YYIOJnRC0(9c!&z{?42|`QkmZa7>(kE`?5tM|;K}C`lgUtx*VbY6lNCOS-k{riw=>3iwDF z`x#htzDpzPU*=)?FLAD`h>}+h1hEB+v)hD?w^-hh5j4AG#KCVT2dtw~c7sOJ-H}E! zQi`_TeroMLb@D%@s%a}7bT>JrnIs3r?`Aa$=GHrRHT2ZJi!sWeObO%hI5+6bj^zcb ziVhd&-B*H{z?J4qu+c`yA!|4?RC9N$nNa9Gx7TQI?15{DPOqGN9AD6#TGv_oJ{KRH z6lOvetjMN!8)-0&+$udZO;zCX>UB=5tzZ|-CX%Rg*iC7dQf(k?35Tce#p3F-C93eC z$f>=s#Gi+i>PH48(=2+@O{XKae*9vCxw-e^S(o4OnA$)&0Nw%`NTRQm=J|fLcPBoF zk_B4m_0+G}ajFQIr5To5bG>OWdOw3Gm(vxT!La3(@yjNPPaj`>)6sNDl7rzQB^3jO zt07R$w>j(4<7fm-<)k?&rc}ZyB9K*cG4NJfxotOZiV#%|w>`PyXmWhoZ(Jnkl=Nq0 zL3llNVA?@2|1q%kLtxIo$OyEwptA(jQl_I)KQVhO{w^Ipgs*n3!`s@K1$zRR3!c6v{4rtCY6mIX)e$Eor@EgpnyW2^^u)M zeF7y4hNRIeaD^x;VnRELqm;AG0X_7w(?@kgsivHGHWn%r243Z2Ok(I9#&+_TEv|my z3m7^DkEDG4Oa@I)XJPt#;l9{Rs(?c2k)IE^*+2#trw-FW(wF%Y mOqTW67Zt|5`-l8b0R9G^J~w62=8c8`0000 zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@g=mZ>RtO02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600WOnL_t(oN5z!cOO#O<#{CPr3JQWWqJ<2~pfJ$Fy09oMBD$9dOrjMeB3i8U zB5a}3D2uQOn@mwF6)hV@DFqiy%f@mcal>V1+-CLdJnwKmziE!6bn$ud<9z2i=Y8Mj zY+o1=Eh$RTNPm=~ktjtYQHn;Q6pchFE<|6ag-qsrdX{UVnyMlpspl;Qr5K7_(+j%$ zAd8-4Kc!nYGU(csG`g62NerpyFN9K@kCNiol#+akwnuHHwc)ENc4stM9>tT*yn`m* zC5kEPxKJoX6K z=Y>e2&VTzaN)gWr#Q_T0Cu}q}IZfmCQ3l@srG&Ovr`hTyVwLXmXSnH_D@`)-+UsGXG0gpAc zG}4>5=DFesOg?pn6Pok#DPdncuei5=h>rjUuu>m+8C*hX3PzCwm$0U~oE|^P)=Z#n zu7A&eOc=nE#_tPJHtC9aF_4p!mc-~0u1o@yJ&Lf zZ{+#2L$$006xD;ffYoDnuoIY!ZI|%n6WX+AmW#m<;=C0J1XKp_O-}oq8KEnSgY?^( zyz-Xz4&Dg_p_O!W^{^&)0?81E*WxRPoPXbdz*B!gGaOLVVT#}_!~}0m5?Qk&spCT` zzjGwOs$mFVcS0G!3bEDDU_=_gHy=aW9qtDhKtW7w&s@PPaK2nl)_cpS?eQk^)us3g zHeU7z+q*&PDj|E>A#U|!yb=+_h(Fto zmJNtj8j!C*0^|C=JQg`m8(1ooqLC;?BT;3qrOno6kIFQvd(} M07*qoM6N<$g6o*;ivR!s literal 3211 zcmeHJZA=?=7{5D?wa^wU5J!0F$|&0qiQqIa$21ts=)ew{A2cjeGv?F}#znJCjT*&m zPUFW#;})ZtsM`=NL(vHXwxXj8FCuKLAPhPgu+l;cwAZ`q`8!YBuEDj*!UvQ6`}FDW zdG2|C{#-azVc4vSO^GE4LZvS)sl=~V{K_eCE_vn{epb9vY1l>x;-}z=)Hk4sd8zct zmkA=yB!0=mIdQ23q0G^j6hFStLTZ(xE>aK#*e%}?%UjlSJ3-j-F8he+uq8+ae-5{| zbzf%~CM!+3sd#IIUNDR3njWkDe8#b;prfzbY%I%qJf4Gx_D7f_e1cOA$A4@xUFbB~ z?e>(El$!1Fc}b3_*kon7F_Ii%5}ZFDA^xNlR#D#G6}h5k3E0Xue=Gk*$##; zwr}6DC&W2#L&?s=5rvi<|MM1I>TNFFvI9mso$lM8n)BBeN)DN8wGxPsFFhh`_3hW+ zM2Nn@i!@E+eMM0eI7yNp9(ZrcHn+L7NF6UPct9UM4ctP`&S!RIWoXOv;! zdcfVxqQ~n7hcf@3dox#QK*gJiK0W$bhrUD??SjL*w>DJlv(l*{F+ z7&=xw3c7A}G|BNi4}Iq^P4jN9r*F{Q*#>cCQk=u#ID4i8I5#WtT&poYhR@GlDR$5| zX!+!$BST|WV05~_=HS(7+t|buibV&!zy%YOPLCHF@BAq1o`ef9$2tL^kt~6w1Chdg zr`=<_o~zbr(vW=hn)~s#VZGufO7KDxe0*P~k-R%5nh=3;gV0{Zb1v@WD!&c%zQ!W9 zE}QeQ!gL43zz+V+Dqs^RA8nxzbilA4iNy8RCNHu+=0qw=gFScpQ4mCb2QU!hc;*1u zQ-$bhiNEBk>fLv!WIo=9E>POUltUuxH5)`3?W0(pU$6p`cfUxwM*QUmfGm#CRZ-=p zXoWWLE^^go$dfWjb>7|r`^Xm?<(e{k`cs(Nor$WUk*jc4tJQ%JL5PY;7brOtlq^yD z4+V1*#=rL|QmLFhfdrE-MFu%w8R*xg(;6i+KJ>B7+DPSAuBg}LuB-OR5@ zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@g=mZ>RtO02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600NmwL_t(oN4=NNYg0iG$MesKkb{CELJwXW+k+H5>7}BGUc{3WN_WZ1lFAXH3A}dX*kP{P>XrRem~0*|v|1 zo1PpHMgrU*3KEDsy)5nB#;X3^-j>?H>g^yDl<-?&Q6yds$l$n!<@HrrN;(dG7>jXK z$O~=IAb%Wd`E=E);iJJeN-LsLDb^&c&;|`mfoLxKn(bRiJoF{TAs>H!mstU@l8MM9 z0QQsi;e^`({URUvrME_4MKUs|%g*h!9jqSY1Fu~g+$KKKE8^knhHrN2zPkjnABJ_{ z$3quIfA}9@v4KU;KtVj>+}NGaDMu(!0!dF-#@{? Y4%sa7grv2DhX4Qo07*qoM6N<$g0K^U8UO$Q literal 2193 zcmd^9`BPI@6n+LfW1Z0-`a?TYr!&rUY%8=Vvem7MB$5DzMJW3sn}C88M4&8Dj6}&J z@rHzb6WN!<5S9=K5E3F#1PMq4L?MW>BTJo5?X-O_52I+(f1qdP-h0mXefQjR&%FC? z*^{ky?fh~l1VOtYnfIh)!AKpm+ z^r3GEhYYNYzdddIJ<;SllF9xv#`}q;hBjvUw&n)p!#~&^F|5$V2W9O45E*7S)mS%32=I;0(JqU-rtd4pSEqqDlKBVKm*2n#Aj`-Q0@IP}hkbKJ5 z-Xh4((%%su%-J&7g%s+74{@~)b+ftPZhO(=Ot=Rz%#$4MMZV;1 z7vWB775g3@0FC20+1jK*?ib9ri0Wse(%V z8c74Qqk+?14aG~<<_`B%DtdTBz4u0X ztA_jdj~>*G_SY)=1!Due(T5FB2Ki%yO^*k~6NY2S_H;<_Y`A`6STz2qW9m`E zlM#t(q;W#oIjwAZ_E`3OR5&@-H8a+%8kbK`bWct6Kc5_&nNm!vMqj9gUQQ1$Opnja zj4aHKuFgJq^>T84ZgOdEY+-(CZBDhmC|z7ott>oQTAW^9dcL~!bY*2`_0@}&)#bI- z+4Z%#jrIB8Hx`h$@QH8FR}i!fy6i|k3;px|ww;+9$B>qM8bNf6f}q_pbZp}o?A`-G z+YLx~3#ZtzZF{#rdxL1+8Vdk8_idnMEdZ$1YGF1ZSSE0IMf8T81h%d4Qv#gxX;6UQ6YhApKLYzh|0to;Y zoPz-T7h0nhKKkopI6YH@t3}4V7J)tvr?(g329UAk_8RS<2!r(I4Kiu4tq%4zDv=~x zaZQ9?ALJq>YLE|{*9cFag+b8=_`C29043@yGw-mio)|_nh#|+MZ)G$Q+9dE_j{+J; itJGa5mT5pZrAeuAa=%c1M%rc8hXN!58P7fCoBS^#Z>a(R diff --git a/root/opt/phpsysinfo/gfx/images/CentOS.png b/root/opt/phpsysinfo/gfx/images/CentOS.png index e2c8a1152a0fdd25856f71162163153ed53511f6..642484143dfceae104b1e4f693bcb1faeb90b37b 100644 GIT binary patch delta 1303 zcmV+y1?c*`39br|83+ad0047(di0SY6MqSCNLh0L01m?d01m?e$8V@)0000ObVXQn zQ*UN;cVTj60B~VxZgehgWpp4kE-)@Q8#GSX000E6NkloBAkPH z6tzsxH+`X0L)0o9)IUbbkhu#%Zcll+-;XhuNYvW;w z-uy!SLsyo{@xfIpWF}fE{f(EUc1g8j|EpiB-?1g)kAc=tj`C^D;IfQ`x6N!Zg zsL0MvDsfwUqeg)I2Stzymw$jDd3enc={**c##MXd_x-;}ylp^>vyjVjJZQC>oC6h+ zY_&un;LhI%Q~(5pUOfAe@h! zmS?F{8Vbzkw8*nl({gs*aaDV4aG9Z-; z&?TraOMu+Fo6!&O^0jD}bWCiJ)A9G`fYh)V(XvTVu;jO`x={;`2_U8rq-p!N5n24q zdP{@~VCE=<9QAyRA9U`GIKeZ>j8Rth*qqSAQ>yo?I(0JpY;cm@5^b}|>vSD)54D1QKpM0%yBra`uDYjFZ$E8nfv2q5C?uUfR&trQp$)IiO)uza-k zh=t0kI-Six--v!7{?C8HlBE{1g9r3(kc)jRx!A@`P~FTfX}vp;lE zmM`C`FQeF~W~`y1TW7Ly!%2UyfSA?5DVe#tOOl75et1lKEq_1+k=V596ja9C%a9qq z_R1C|CSQ=Rcx$_c*^tw}(9@)a$z33Oqgf`~s#FBg&|^9;fEEEfBVse&%=4z4g#v)S z1PR1Ja*Bu_dB<3R;L01&cybF;2n$W2kY1pI&W**PLe3FEY$S$vk`K?Rsq04b3m0{Eo_m`E_j zil7f3NkEVc5fmVT0M9J}-sKcPtjjUqH=-7l0#*UJ4}XHCnMvQ%epBSEoNtfmiO4BA zJ|5Nkq23YmIp^9=8^nBnU@RwqqQ*(cX=$!)v>e|Y*JYT+WjSR+w_kQZj%agH<&NN5 zW~Ja9ECWi02reu{#532sMd2JQ6Pjzz1J7LVl!S9|0SKDwc?n3x1M77k N07*qoLKJyhY|BA&kC{Qdgrk$ zX+>Ky^1g=6W8^h4l2ZwJAOHY5@GDTS zJvaV`TKo1CTARb%Gj)v1uPy*U9kkQP+1Selu`vHwZ)`|xJSqkaxCCQwqK)B^C=A*Q zjS9v`51}0aKrI#N=>y}Fz}xercjUi>(hp?vkW|jw;SIdFZ0J(sZE zb)B{xfRBHFk`{wu)(stWyYQJFzcBBFTg(jA=jOB90CbwBBQ#7`ADiunp^?bN=pa7vNM0% zdCaLJUi$b$0uZFoNc4H;;jK0vj?os}1sZKK4G&!W{QfFC>nQS&ksA=21zE0qQgx4b zf%U~1%cs%ovB5!>i=i@ZoQ^WU)sb#p0)2ogBb}5j7}isUqIX%cqdBCqep^^}%wsIL zbmaZMAk*CTP=o#W`c)ggq^nfB^%e2 zyX_DXj&}_AhCAna9A0aVN=y9iG^5h3di&@Eh<34?La4pd*A#cD>%1ld`3n&OPVIXA z;i{d5@YEyP5wq<@r%I!4##@+sTY!7@*}|d1!#BF8K%#=_l{X+Ocyi6jz&N%$Yl4=l zo{4ye0}jvsA$GS=^%@2?SNQ5t(kE_|E$)BgO`#j5FHWeos33JjF7M{O{y2>(jPxGi*~ohZ zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@g=mZ>RtO02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600W~*L_t(oN4-|dOO#O*AOC??K`o-Fh-les5iNqC7C}LYMPVX6EXblFA_}2E zDk927&|}e}%mybPm{LATkw`*Ivl^AOL2V?aB(Z3B>vx^s=lSlO`DP?&@%!$*=braH z_k1@L$_f1wqJLvk=27dAiBJAEq`e#YX2LHXiPdqyZka7q}B^sz0(M399RymHrl_6hw%V1^)Zq@etgo7M#_YfiE)5+Ya zk7jlN(L;d*ggJMM%eUTHZVgBsQZ}$B;Papa{?0#FP?5@5iHJ^9b)4~YK&3AAGz7kM*b^O-f51Vc=j+{2mE0gOB@jsRqR z=bH^QA_~j><5~Ivy~tdwE~?Jn36+=zcq_mFqLz_^#yRN-Ler4~l^6iDSVl_Y?o%30 zU_=YoboihWGXU35Mk}*{IexvGoC=kg1@Kyu(F1r51-}0@sKhLRnpk?c&Ym}J0D6JO g7YLR3-w+D@0YIzSY3BZc8UO$Q07*qoM6N<$f;|)Lk^lez literal 2193 zcmd^Ai&u6)s`+(S5sfUY`KQIhNgz*if>n})Lf;t zQftksHEUO|UAJZ(v6i-e-TDp0M(qvSI&>X|_IFGjrY=Kw6O-JmyP4Xwh1$IJduqFZ zzT%#kdB(8@JK1Wx@9Z$#v49&Vw=YS_B;L?y=QLjOLem6gvqU4#u9@a3DrR?={E);k z-mPenx`)eA<;8PNjF<5eOia1U%@a+{Of)R+er=tiX_;iU*L0;-vdV$fRr^y`Tl1IN zr132FsU6BNx8$kYW?JsI*l%q`*zz~prP2?lY1^kCu=!EPA=Bp2LB^4LhwN-<&N;e{ zS?iDG+S%J~IG%Ud!Op?aev3=ik)sZdPDi%6c*|8 zo6$E;->HfI_13wVsxz^5K5_N_agT1t{B|LsCLpmkChksPQhi)PY;a0L2){8gDIqkq z`EGLJ)wKHX^d~8)$q^Y1k@uR?GWgfCTQcsY-^^{x%E^q*@3@`c6m!2NCqFy3ur;qB zH(t&g|c8twnFz9;jJyIQ=ASse0SrY*EvO5Gp6N2`zOk$3GKoBH6N|F@ptk(0fJ~B_khq_DL*m_$A~k*5n>O-1UqK4*$gI=VG5j(gP1rftc}5&lxR2%9zx9^ zUBG!zE(o>L$W)nmOq#`q+R-5lDhQUK1Afd0kH z{2|EG4Pi5=`$4BK4Vn}bTS@_=jRdd#A+!wK5|klAl6P3dU?X%}=7cBH!A?hr4Y2^6 z4TJC+!QTm?Od3|n$QB`4`$@k@C^N*zh8Ll)xV6AoBUFf4K%+?5wR+mdTMHt+6#V&0 zI|MmEfq}xoBT3;)?mYyUz_9i{ZH#o5kM#UcTY`f7I6e}3^(lHN8%{jaf=}5I3Wv+!g!1~d q8MN6r0_MbV{22Pyh(UYvvGTKWczE(&zKHb_gADYHSp03)Xa56pxmFYa diff --git a/root/opt/phpsysinfo/gfx/images/Clear.png b/root/opt/phpsysinfo/gfx/images/Clear.png new file mode 100644 index 0000000000000000000000000000000000000000..70994b771bbb626ed48a672440116e9ef85a7176 GIT binary patch literal 1665 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 literal 4217 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 BlV<<` diff --git a/root/opt/phpsysinfo/gfx/images/Cloud.png b/root/opt/phpsysinfo/gfx/images/Cloud.png index 0b0fd83bed3cd46f87cceb226a635731a5f62403..12f9b6c9c118466e04664e4aed1ae4ce532a2bba 100644 GIT binary patch delta 823 zcmV-71IYa3Ak7AlBYyw{XF*Lt006O%3;baP0000WV@Og>004R>004l5008;`004mK z004C`008P>0026e000+ooVrmw00009a7bBm000id000id0mpBsWB>pF2XskIMF-;p z0~QGnP{(hm0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE`KmCI2$xh*Z=?mj7da6 zR9HvFQn8g3Q4CuOBfXSILP!Od6JJ0=3LQ`b)IbfSgcs5PmY-x~k9T(2RP)h&xVx*vJfV) zUK*&$T|9)umpS9I7kf;Nyjw~BWOU)233fdKNik2e?vVLKqIOL5Ld1jCgDYDgkqcnGk*g%(k7oKYzxOC8h}{E z6!*2?LOuya+(gCEvvTV|0VPxc&cI1=LB`uAY^chsgQgsBRq>x1z%c58zBEx=WxwAA zNQ#R*BY%Mf7011D@1dHbE}o)oLI2ai03Bz7rbdC@GGgW41A5h@fo353Nj!5~p%-u? z2~K}@3vFukv!`vjEr2^DMd2)(&Tj$vZED|Ypyhgygam0K8_5`ev%O)};R(T0sP%FK zQQzu3NCJ&i$O4$aU2Vk-WIhdMjG8d-=Vo9$V}BDb(oJZMf|`x3WF77i$9+9P#C|?# zO(Mx~S*w?@AW;H&E&yZ?tH~I5H0o$Uk=#Hv$HZ7W8p0F}W-jg|#+t_A4A9ubfe_j= zP|%Tva3`Ta-Kj3P?1eM`nTZ48XeO-bh7w22T=kfJ9V#q!!13nE2OT&S3xNGS?hbs-8O5o&EI z-L670}ZvK+hLDBrhH{GnHeX%q)vUcwy zzRP#NUFPPtZg3OBiF-CWplcSlk7Zx(><#PdbfyHrjgvKd-Ynlfx6{r@)*rk`zdU$l zhmC0qfT9RHjeyhzU{q&6oH!hA-uiYq>DYFuJUZC!va6j=zH|DPuDX}|{`3ACV})~a zbN-_~0O(%WcHaG0?sU(_H?lt595zh3C{31h4B6odj4A$!I3xRd{}x+k zZA}2_u9IhRGB%`#e*HNt=JsX^&jxd0%ofHiK>z*wa~u>_i;h|aK&gK^_OZjWm%r2E zpixAr$Jt;*4$VH@{DA=t`f$Ky>pGNn28|{9kM0cCGDCG9sDzj!tlUUnr+7Epol<#w zT%!OmY0o+O1DJ_hwSO~jw=QJNi<-k<07mhpq8X|g@S%pigO|UUxJAe*)#evb+$(GN z%J@)Q$PclJELwb+#!OT*VDPPFQ`*%cw`pO>+c1~)ieu_@6T=%7um_@SObmAd5Vl~H z^Jei=C1yLhd6*mNn^eCD0}VRDjz)|>2PQQt(yo4Xm9HNSSu_BE#>kGE-7M3IFHEXB z{Gv%g365&Z0g)Y9d0ZVcO5*_l@m{|7-D6z-0p-o9z?gVW;m{gzBfHX6Hj8{0WW8~iDMMgaql=yYLoAx;V_JV+&?UnG0Bfw4YuHfh&Hi$GO}ouTL40dWN%gEFxkMC7uOL+r zc(7D8jav?VI<{JXl$<;^Vj4L+WJBtQh^FqI;mR9g=_-aQVhcrV2W5L7_1a$HC;HwFMiJTcEB;#blyuO6V4Uvf~ z?S>bU%<03$Kkwr3;|!!O048%F7(gP0m4V7{Q10!{s5)ho731~RZwSB^DUjknBTNby z6ssxx!_)TEqTA-;wkZJd2J34`Qaz~=aheu$HTplm_FG$>2W)1FR!cX^$&L%#X7q0v pDrU^U6!@B+uAK*(-u~(fKl|fy?@w!QoadzO_qLXPe0T4u{{g`*!HWO@ diff --git a/root/opt/phpsysinfo/gfx/images/Cobalt.png b/root/opt/phpsysinfo/gfx/images/Cobalt.png index 674def8ecb4dc8669e6b932cfe0a50b366aebca5..826095d835cd07483d59b6897d357572ddadb99a 100644 GIT binary patch delta 1954 zcmV;T2VMA=52X)~8Gi-<0047(dh`GQ00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE-)@Q z8#GSX000LTNklrE7nkoKx z=DhFsz4xByJLfs)Jr*zT8M4V&6U4Hws8DKZk7)|dH8sl>*9#7}XC!XiyrKj`LpO*e zCqG*bR+h`5sv}CG@$7|mbRc;v1DcKmZG8}DSvmCYb1WFKdnN!-;e(3_YK|(2rlt$`{E!?%4y}+bqJ>4>JR^NZLk|MZ4S}$*En>0T z<0K<1UGnzkNqK37RQ_D8sel0G)6mo+&ZB1}uk4iU$f*`vN~x^0nN!#s|V<#@$C2RwC1lGoEk)-4_Ar;wsiX=I;SOOL$ z%YY$^rE8y1>GdJnL;$JU=Kx(SO-HTU86=s zJW05#fD~+W*kyZavh2*x7yqEO^6vWqN`OW&Y|=Iv?U$jp{}-uh731UXLa!l_N)Dp0 zeHg1}KbXE-hE3Zcz6(+{T_w(Q+F?yvl)$Q0Hi@?f9w(S<|RF#Q|aiQ>?pG zbdFu8v>NzYoErk;7POL>x}->E2B&M3s1$9*%OY(u_VY#3?M**L&w>8Z)ysu90%g$n zaLLTA(K;t*d>IZAAGvTz@SK z7OvN5Kx$oVx>f{z;ri7^y{3r_&LDu|aRdRZsR;I6hDN(9p=|_++^la?wO<5S?P3Xc zX@CeY7xeQ95wBrEYKM%ClIgSKrMRS4n-bwC#Hju8?#tz|UNO?aD?vJXC#q%7b3^3S z(FyJd7y>2&q}EL!I(ohMP7RZH27fOSpN}IHV?K#g>+8Qw4^|yNp)DBU?bzwmvLe5P znXg6hlqL>vX5O_;0VE)R5R05AT17}Fq|_!(j*-DWK?*~F4mjR7O5ayk*Q*fG0`miZ zkX3wC31SfyZJW-wv!q@fniSv|VkZ1l6s4;gSREfGk?S0)ew_CoHbdgfIV@Kma+K&O@S@mE(r+<+K#ysh=$Lo zKzX6dBzf-T8S+%OKvg~>Lw{gKXtZ4v57?VE=co#*KzqT+NYxSoX6(c9T?7yz1RPs8 zx$lGcjk~o1xC^+DAc5lt0fJ@?3HJOB4RKY|qRo|j4*^;+Q6K`4NZHQSoG*I|$`pi+ zR7{*})6(?vSt31$ekZRC43RGVt%~jggQd@VAzHpTrQ2;vtCSd@7O52GBPwB5MgNjH-IdbXfWi~)z!Hpfe<~#$PA(pz%fpVgdqSS^gtva zK_t*cTX;Ta%~@tkO`VH`4!JH8I%&HuG(GhB>5diTC8`T;T+qP#&T3V(Xlq=8fXU!SP z84^s`R0p~s5?pGOD6QW@$NT8h#o`|jD)Z+D%j~a1b&X}udSPIgTC;u_JkJGw6QN3{ o#WVH+=1;mU7aQJ_oj#Ml0aA!C4$mea2mk;807*qoM6N<$f{p!&#Q*>R literal 1943 zcmd^<30KmI0>%GoW|lUVj_bT?%5Bs!d*ecxMh0&9Tp%Sg%Oy2)D|bcH#4Q(;AW^^s z1$Re9a%ILs++Zp(G?kHZ&#e@fTr!{YzQ()f{OKj(>+0jP+sQOU=0Oaj#A@GAd z^AAU)4je+u>Hz>Lz}ewCR9@k>f)e8RsRuuuyLI^Iup#$%&U#6%SSQ4+}~pv)(- z!Y91i7gZmWSnC_#5*0)Dd&EYi5QCGe15?_f(#oPUYva?)lQ0!gnJ*G?%_w{~`cV-Y z{S1vJr)3vnFwb&x3-bu688~8oRskM|$K!|uQgI=HNF)}JNTk%%(wtmc_ETy$zWPaF z8x~jk6kkgq(#T{Qp}6TekySz^6jO;=l#T*w2a)oEOl_x>P^sijYT5J3s^U^Aokp)I zudJ=Crq|Tgl+zn4DjRBQ8mWwy`i6!&W_x3OV*{g>!Dwn=v^TdiTUe~N*0u~%Zz|8rMj=Gj#tyft7;Z7U$7gRc`fa4J6P=2j=sj05o-NM*2@+~*HFi+ z!9Tcy_C8S^XR@vD3z2*xCU-Jgu2>6480>Rku$Pj;Yd}K&8GBzv}3OT%a-q4&tFgY+X zJ3PK5{Cn!%=*qZIESjAaPKrMY$0jDHrl%L@KF!U3T3VQyUR;`9{0H&;+}ix&>X$ED z3*v>(t6x_?i#OM2SJswS#p1P%ov&MK8{4~Eo9o*fJGw&*}A{qFgzb?DuoK*4_M&c>e8st7Zj z-m6HGQJKyfI%cfuYpbL^N83ycF;YG$YtNjL&ctLk9y>fXxX#96dUOu;mnrRRZvoLK zz@>`+8s!wwdZqKC;g&OJ&E>w5zTaz-cOfjz8PE9}CX)y=+00~)r^5{A( zGMG_Sx}@d6n~-T6A>f~7mIf8EkUC~amiZd{C- zL6?l)pMY8F{}O6wcSC=2@SCK1OJ@+}=^cyKhcaF+%O5OO&lhbN!m+Vpy8F)D@)gqM zKeYd}&+q@a=-;8fQg=N=XhYK+HWL&ZvpkYeoA+C!b{ECXWVTNsX_yrDQ$$jn&R?D1 zJLMM6nAWt@^SfVH+P>1#I-8KBq9gw#yMDN` zsY3-60p0)J+Zm_qw6+ithV@s$!V&jGHAQeW@KVfY;ekDC|+Lsw^Qt*J@G={np1;*KWMBhA=LPjk5&`6gbj(of$>F+1+9xaqJq zk5%kD>Oi=i5YjEdX}L=}(YkrqwAnNx$$=O$on5{1?N|U8ZUsvQz$@N~+u?&p6+^vx zluh32-yo*>ByZ`Sa?HfbUPL12U)g2qGQ$@Jv=pSy@Ub{gosHy*oxr7_K;Xhc{-S+~ z*K{Vdd6CIg8!N_0r~;~oOl{)KRJx}(^>?J6cnqpsK c-oM|Ml4f9C5C0godoUcp4(bT`-O4NFzm1Muu>b%7 diff --git a/root/opt/phpsysinfo/gfx/images/Container.png b/root/opt/phpsysinfo/gfx/images/Container.png new file mode 100644 index 0000000000000000000000000000000000000000..4cde49e2cbb5dc805c719ea1030154a2a062d56e GIT binary patch literal 822 zcmV-61Ihe}P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd0;fqtK~z{r?Uzk!6G0fq(+Ywhh*U)pzkn_H z0sI6C#hTd^S{r9uyqTR8p$8EfK|v3NQo(}s)lBOZ znwswvr(2^a&37ZydINBds8!a?!b$N{^QF<;Rn258F5DlWJV3e}JsGXn%a|ZLe!0VI zT#qy}KY~oQCgJ`7wr<=i>7)|IaLq#=iL`luT0$9iMxz^dt_o1XsK%I;`c=)sc zx=z~Ih>PRk08!Jrrh>axj)0z=EnXNt1|#8k5NurkIz+kzkT2`Tkb{#wqOKi4oB6O0 zKp*{J>81zhO_G;}jc}@Q&v|k`M3m_>ae4C7D;f_G5)sxP31TDu#4I@z0W(tP|s=82` zorCASs%o+oLx5g^2o_ubuVq&8H)+`LXgTM>Uqc(>Z4h7-Qvdf^7TPdz!8c>s>>klL zoKV_|LZj*{qqe`m4Gf4@jq5yJI0DOO3>wxI1m@3Yl(Ft=Q`T|OVte%W4@$ltCg~)A zo_n*JGTQ~h<9Z3J$J8<`9-EvyDlXa8PFE!I2T4PF`R;j zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@g=mZ>RtO02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600SRML_t(oN4=NpOH@G^#`oVa=)b8ikx_jRElH8mG)Pl0y0Ufy!zi%`EOosh znRWq{C@GCVMU=ucU9VtvSuERiS;1|4>lvBTnfJV&J<{5TAG>GH%=+A z*_vK@a4|r4u65AS+F|2eUgwM_BVwUu>f5>~3_^Kj6wWC&h#f9czmLz=TJaZkaSqJ%oVl&)<8w(GKrB4fJ?9YBmn za~Lrmz?J?_qOe99`ea}lqIn<3B`E4SFI8cmXERo_`L*0A5PMn#!s!G5A(M zoYT)gS|%*7k~Y>ZXI9@N?p$?~M9(v;j;;Pv0M4zt;iK zJ4uw|HVWtv;`+uzF^8B0l8$a1$t(~BIgyeJhJUD?N9O}7lluB+qoN=O4Rm9#24Z&` z3{g7+rPoy&_aT2vf}E`yphVmdO`ObWgk$eP%?t1COzE_$HZnc`~) zzJF{O!10N{l)!G7)%1Zf8s5{f`y&b%!*5RAnA)s#J&5x59Gtk6f$pGt8s09TtqcIn zNU73xac?MO8u*{1U_TjI27s5OlnS2B{JlFE20(fsC^kwJIPlu_3~_*&DK$(5Sod7d zc+jW>mEw`mCm@cazz*(vQn0OnUDoY(Bu*CEX?wf;PosegtrS-y7E06)FRO3pwr%U2 zf{7;Gf+WPkWPA;;tEGg!y!uUuFiIm!Yn}v6(tN)G9XVliI1-_q00000NkvXXu0mjf D-BYc* literal 2193 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 diff --git a/root/opt/phpsysinfo/gfx/images/Darwin.png b/root/opt/phpsysinfo/gfx/images/Darwin.png index a4d8d2de7f3240d0247657bdb51b0e88dd021fe0..e54b4a001c720945d46d5592dd3e31eb37341d1e 100644 GIT binary patch delta 1126 zcmV-s1eyEO2Ji@w8Gi-<0047(dh`GQ00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE-)@Q z8#GSX000BwNklVA|ee;vVVlIh3JC_dqPP_i?X7q zutMT(go;E6g@{tfAPu2k3$aCkkPsq5xzK(r+Sj6Bx}V9p%{}j2f0PeC@7y!z-ZS4b zXXe~nAtJfF8GoEK@v-$HYBVNKotLj~r;^L~_<9gEzU%2t8maiSt63IGeR_=;+C1iG z-wXGL_LV3z%zvKl)`^&KadW-QG`7iyh57W_-@7nOcshs^XGcD?_MeZ5N2Dl zF!oFx;BahPjr1I>QgCQOWN*7NSJjX!BGVykKFstj8h_UJQD9=6-f7(}Pfj){T#p{A zQvpQ9M1z2}MAWN~~k~36I@=N_?oEsz>51Dck!3w)Cl;l>|30?KM z1KSl=&kqr8O~*A4%&A3yNcsdfGMx}6HOMiR<68hNcq0A7Xd!LkFXh(!OHz9}u zOF%>rK|9)GM2#M@J|+New6qK0^!DZJ+7|0}r~q}IBpgS2_?#zd^bmo(@Zp@~q$Lm7 z0?HEGuT71)!aY%=LDG=r)HP-2$2f#=O87a9*mqjSaLm5@Gb4|v(SvhpnzF+ID;zA= zYk#u+_<9d)=#d(9 z;~0lt0Fb1toJf!_VbbOiHF`LPIYzxLCVzmauyP_`)vy|(Mvr|P`u9Oh0C`{uy4wAR zs4)Zq_C8<>UfjKuD_|}A4^d+XIbiini4kTW1xrF-CHCw}M2#U-fz`BSISz45IkI9~ zJuNxF)^S=QhH=oy1#@RQc_4s~6yAVVY95>-2X_6=06P(&3>l~8p1ikWnIQ(NhyMP4g+#P5`iSB+%*$!%>!@swJfg<6fB-(z sfbRjeDZFPnqQ-xL??=Rh_T`a^-yVrw`3?~N?f?J)07*qoM6N<$g4Cn@^#A|> literal 851 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2LgOTTy=z48>_l*>U&0cM7_Q` z@2XGYvax1%)B7oM_tqZsQTPYD(T7$YxCBBw0Y9aitPi$NF|MBwq z$!?G5ukZ^h}@RP5n+9U?1 zKd}mXtl@Uy@ZNjZFK^8DT+vniTPN`Q)0GFetpJ)Ia;Ucn=og2QAirQBmlD8msCuId z&@9FzZ+91ayJUk>AcwQSBeEDsdw{Xq$!t5If(M>1jv*GOYbSMsR-k{;Kq)?3^O!hq?Cub#!+eXZt6-_ITZfI##sBx3#RSy?l`hDm;0J9 zM}T$52S?7v4WDPqR%YD3Bs}9m;L-W37#@f%^W-QL5GZ^7RrW@K=(R&XYP5k)#uEibAF)=bFwq59%=ce8@pXh-q{eYuw&g`5mT3s8SRIjY>gDS%W&iU zQTs=?4P~Bg&1)(SzoY)UVw-21+ZfP7x-Y} z#TF&J!6+v0z?Br&;#G?0*RUHb7v=uXaN^p9|2vpPxkViU630Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L00jU500jU6zLxvw00007bV*G`2jc?+ z76}hf$8V?r0009h26vr<*@4e|qgb-gLJ{P`4ED(_*X_U;&yKl@!BFcgwHdZ!17Q~_!O+=K9 zSP2VCMQjijx=@j7-p9w;9I{xR)ndwa4o6ofKOHSt9bI-l+ynD|*_l&3% zN0U1(Rd(5`G=FVP-nJEa7VQ)CYioLQN{A_JI4d*29hc+#s@fdDeYKv1rM(t zM~SY(#GR0_{1@d(p}y}}vBNx7<(Qhj3zPiJpVSzET#u`Is~wbEucj8X+%b--U+on~0z7Sbm`Y?-`eoUP{y{qJU}P(s6o15Qh|R^=hdE7-~?DK}8e z6tbrmyMJ>k#u*B1R(qj{W^eyusb;d;7usVapli0OKf!MYmiH*eopMyUn@zHy?<6?@ z8BD7BGFE$Wvl)4+%EzoK2<&c9!r^8XINnIB!c7;>CFH=zqVWWS0Wx$nV+X5zu{7fV zIm^wG^ampg*@4lNh)rX)7a073eB-7sZe*+SQ-7%~8We3BKMG5cYuJI5sfL%c+6xRu zA#rZ{l2GJI*x1}GNajcrZpOsRv9<46saLv zjJ`k~aMKs3K0F^bW3;cV@{rJ?OZm|SC*?B6{O%Q@dRF;EO9biSWkF{|1$kkq#&L{4jpt4T@>~24BY(5DRaBx;PA3O2(XDa@($~8IhTD^h4s1&Y zzWgF|Emhs1l%?Q6!gZqDeFFm`Hk~S@ctEbF>WJ0Vf%|_yJ1`m##ul);cDR)cmE05y zs(y^swS~$rcNH|*%c|N!0f-2Gon8g+{azE&m91Nt4%43!R@assClV#|_+&BeghMe> zvY?zS*okh)AeC1YWw(jM3K$#V#64uno}!h_WWz;fyRAk-RBn}h*?17*KfSR8e)kZr Q=Kufz07*qoM6N<$g43V!#Q*>R delta 1256 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 XK46{h>qoqO00000NkvXXu0mjfAEL3R literal 3211 zcmai0d2m%%89&>-_w8gQ389cc2qYmOp)6%s1Og>0$YOE$Lj@fdv{)Bxsg|*HM%vn$ z3XGJgGPN$W(mFuLg1B@*N)a+F30ungfC2#$LYDXP?!9O8JMWQ@R*L7Id+)jDp8NgI z_xrZ{;{17!MneNa2%%`*oZ5wOFEM9;z*Q99{v+J%l?&%Bf;+VDzu~NhTkr>Smi!o@ z*nV^3ja9K?gd$aSwbQ?}>MSma#Jg~M^@A>3@Az9%;#h(yOfeEJWtQSdlW{?RLD*TA zZ9V8?gdPO&`E$ueWQU}5sYMlkz096Kq@{>JehasL-OhKUM9L2jQSEyway|{_{s7;- z(7nT@0VI7YkhYmZRW^C2%%WN&j5RU`bWHfT^QktUDHR+acHbHj{$H5;0F)nYOFChu zJ%IzZ6c{N*$bkx4#B3uMzR+4BILPRRjxL*|Eb4IVNa132q&lkri0sph1^c$rLv1M? zvOP}MQe} zIwSWqCu}WMuefX{O2Il)Z{BJ^~bw|7{mHj5qZ@(W^Y5Lg@oeX!Fs8ASVtygxHiu?PIYG$ZA?hU*1X4hA37D2sL~B{W2m zP|y*Vv+^8RV=QsOTQ=BwZDh`d%PFc=4k24Fb$;Vumy3jvly0yOpgE7>F)aCby-~sd zY`PkFxiV@A=41TKh$73?%mWMs9k9md1~lRr(s>*T6MXtJ+O#XJ{m2ozEc z`_kp81A8Q+0Rr@dfb8(*B|RxihN#+o!2|d2=LD|1yv_0zvLCkm$=fc%=D<~ZRRPv& zvYd^LH^{Dr8?(!EK`)Gag*9-!d;V}=B(;#xk&vgZG-J(51MctVlz#5rO96$xlG_EQ zefI_rc7t{0qUwSOr;W|Y4B;6J*zOk}itIYqOd4;sk1vWCc93m60h2Hym03h_K|HRw zdiA0QmTF6R%lBP7bX&^q`m*PF*jgsKjK2~V!++tr#@F=CdMLRFo6gzt#D>=WcU}|0v zTzJCPi=4}+Cgc%`cU^LkFB3@@gJ1MClOlz-!N`SH^i*?u&pfyQgkBJECKrV_&nWP? zCcdh_>_7hA_41rR)MD3!D%o(1CH3?H5yym>dS!o;7QPY`K|aic8-i3znvbi;)>*0iXBhRgw2h}}CUFXCPHsS+cw#K_(Ycg6Y4ceE?jgjj zr$5tcXCI*zJLA{dT(Y>Lpy5&igc^x`8dwiuzc@fze=>YSU8#-SL_*(oc|V1Jv!Jx` ziE0Ez!4}gto!1@_+^Xyk;c_o^+DdOf*1YnwrK~L5$$9oji_7yN1gKGxzyVjY*akO* z@K{`t_1K6SQ_75uz>*Xx>0?^8=KU1O(MT}mF0UB~3YtiUXG|Euu4_#n6g09*Li(BQ z=Qy>nhH_4%(WI}-!6R^uje|gX!eAu4_d>Gh=f^vEnE6R?p@a&3c}x+gtY8Ni3IqD# z+fAj}Ci9yeUhnqH)*LSmSu-mG3#((Zh8G%<_iG=ub*|sn^7_G>P-kGX8Y_t*S0`6Y zFIin%jG%xc3$iIuvheA{+rCpVZAibntc_lKBOwAG8n%JMlegT7zc_LB`SHaOQ*6?+ z>E&;JbC}>-%cO7ewA7NDRHU#}Qo_FrjD+B@XP+ZTo#`%9s$o@C+8xp&pg3bZW_80a z=jLXle+*#msQjhl90BpdB{7wNn8*i6C_a#j1$erTpmPFo%ee}>9oJr&G-5zF0LC!P z==PKz{PkUn$L4--_V5fKT<=konOeJ}Y0W!#9L=G~^e*Zd7?mZ3gAB_j2Va=X;P(Yd zjw$?*{rkhVFT8N-TebP?zFOI{-rPS408{@uadY0>ngcsGh_TKPQ0WwS0Y&pH=jWYo!8Vst^hz^Fs0;?`R z)zT{3lJKwPKDnTD<>K<(*eCy{dJ+B)K<~PJr>}i*(v9Ctz%R|fd}~H!&eTx_y>A~d ZXc<-WHTK)>JI#{1S@UYQ%~<-}e*r};N~Zt- diff --git a/root/opt/phpsysinfo/gfx/images/Devuan.png b/root/opt/phpsysinfo/gfx/images/Devuan.png new file mode 100644 index 0000000000000000000000000000000000000000..d1888d614f3296e78847404498e7904ed6ac7d9d GIT binary patch literal 657 zcmV;C0&e|@P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd0s=`yK~z{r&DT9hl~EkW@vBkNP=slgMF|bj z64aK^=1|cPDA5?S6ojBlL(vix7!(nWLR8QYL8FsPMK5G;^kUEuA}9zVv=rLQ_d6Uo zJRI#ldY^+o_zdFp`Tx&zUhc6*TCo@Va0aK*hNej6i3{z-S=_{9T*C=$LY8LYti=Ib z#V1VS7W%LmCRb$ZMZyv85=#S`=(TO-C|CozrC$O!fzYa_0OQP_ZN<|48-;Tm~>(1dHmX|cI% zv5BV$P3Q~Sku8T1H=r?O+pg>3>n}Fpn#hu^2slziY(e8y76zheg)mNhtz=UA$+-k=jJiX+t)oWlfC z#bP#g2Y!7oD;9KaH^A@zhxp%UzQJXGway?_U@`L;hL=rKdSw^me>|x|F^hVYa{Fz>ii^hap~Y<#etrqh^bS-O rN8>g68K&SB`Vw4F4ISw!Os)100pIkmb=Lm?00000NkvXXu0mjf-ZUI# literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/DragonFly.png b/root/opt/phpsysinfo/gfx/images/DragonFly.png index e51e1aebe9e4f2f94109a565b0c844cd2878052f..574bb6aa8823c0b300bf6d57b865ed8fedc1d56e 100644 GIT binary patch delta 1816 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 diff --git a/root/opt/phpsysinfo/gfx/images/DrayOS.png b/root/opt/phpsysinfo/gfx/images/DrayOS.png new file mode 100644 index 0000000000000000000000000000000000000000..8bef5c192b47e15559f77c36fda6f2c7d2f80b7b GIT binary patch literal 2210 zcmV;T2wnGyP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2scSYK~z{rbyt0G zRaX)JoqOMVd3pH`gtST8hL8rB!i-Rw^1oyq&bIzW< zyLkT#79^i+tG2Z2R2ug|qaIp=tq0O(p-f4uOvmfbMV&i$fs8)K(JushjtzJd zeBN*2cC~Nk;1C51QVQU@B)*8x%NUkc7&0mS3>w2(V*{pd_%p;#tLNwuVH@qf@g7bn zBUDohtX&UWR|8Cr1O4v;|LiwPJO?OfS|0_{W9`fMDB$xmGUm6-I(GDkN_MqX+gkmb zY_6QMYny?4H*-kGCMKW?3ZOzE;Jtq6SLn1vMOi>aB~;l0_UZaKog83P9Vgegpb$-& zTn7Ya9M^5IyKn#aH@O-vm)!D2z{7jsTpqwg$5-GSKL+=$-@>Z70oJNDNM61SduRaa z?$1JP>i|}-0m#R?4Zt15qGI5~4}o~XHzLFsyA}qy46XFn+t0IQ!jXB$oxo?lh>3kW z5xF{rU{Q$?*5Q1pr=LaQ{CTJspMkyTdQAU!40?DFRv?d&D2KIjH9`+=fgNEW55EL_ z@PT>OK*s1C)E6w0dbkoIG9rZ}jOyqZ0x9Fdn3(~tT!FQ4Arh0^mg#8}1;Z$=sY5|! z6(a11-#-iebQhd6r=dFcLoco~x-!P*phxQIfIpCSd_o2Yt!+vtnR1zMC1t?E3OJYk zL!QVI>y`j5cR_9V6i|Hwb3?K9+!D2ciN!ZF9S$!Lv+c!Xc<0iiV7sFjZ$X%)i-{D#CM-XQC)+Pb+|3FBSWwl ze*0tGe+m1UGr-ZKJj?uT-i&0!&2SGKKrq7O%r-74z}D_=ytO+u5LBbXaNd0z@rwgU zj*TJymp>t}cnPf1QUp$)GRloyAc#cmw~A%j?}1mAoec;hwL+zNL+_nRU1R%YB?%kQ&SrAPR8*@#MFli@1`HK4Nj=X&D@Z{>`tM zaHl*O%DUXP=($rUs;UQ8u7tYhZYC&mC>jO+%0l+~FPUR8UoQ#&CIWJyh;dnvnan}) zk9iP_L9rg_a2N@me_dY>^|iggova=H3a#j@F|HVT)%hqib09G?NXPPk`#%TO^#rtS z8=aX`kQJVJ5g-v+)y&Yd8qOSl1rwV$B6*+_@qK%srTl*30VGSjnqiPd39Vb;T)c?! z)_W1(yBqPHZAkv~XTXv=IG=9ubraZH+@Z|FK6;+XD#^BLr_~E0-EIPb4$m@5eTQUpG5QwkC^;P zI?Rb{79!tx8Ua)rXJgEaF%_k8^Oj#KQ{y^BnjM5 z&#hrKb%a6SoZWrf>TVI3_Yz@{M6TQEC{)uYS#VZ)tG4LWx^*Vp4kI&r@F^7AB?!$X z5xB@zHhuzjQPiCaLXfbc{~&Se@5u? z737!JrmLx-av#|t2R%!Hpb$ck=QkFI>fmLxW(~$4~w&VMw;bDab< zS1+?%@=1~X9C6E`2%9zT`V-bj0Dopq>vX7du*v2RH=T9sDkP%bTT}LP*G3Y*pE2n1#Bi$Y ziv#>(@gE8@sR;ILoJqq3Oev9aEVZDZ2+6BF*GAr-n};NGc%CsY)w204^?WIH(U)e7 zvPKg^cWvZA7#<%t-Uw7KLh{^M28cJ~|1&Nyhi62^xQw}Vxfh=9Q;CPSSKF34M@9r8 zzG6S~ZJ@LS`ZeC&XU@_vKR`C!4_#P*@s6!1p0LcTct%NDnb!(r@x^$KQ30<%Ru(_)gn$IZ z)w}FBUp?Yi20HO&Isv@E$%vawAbt~H!K$u@~07*qoM6N<$f~k!h?*IS* literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/EasyOS.png b/root/opt/phpsysinfo/gfx/images/EasyOS.png new file mode 100644 index 0000000000000000000000000000000000000000..2b9b202fde7ab7ffc0f3c20567dce675371037b8 GIT binary patch literal 2134 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 literal 3827 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 diff --git a/root/opt/phpsysinfo/gfx/images/Elive.png b/root/opt/phpsysinfo/gfx/images/Elive.png new file mode 100644 index 0000000000000000000000000000000000000000..8adcafbc156c9ea4af41885521696a89b4e8b267 GIT binary patch literal 2415 zcmV-#36S=QP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2?R+*K~z{rotJrV z6W1Nbe{XeImSowMWQ%4QFVRCQ{6^$=3w7Ytk>#*pxf&SN+sQs^xB5!)-11CJSU^# zm8Dv5r0NgyPyvm8s%tZjzIwac`i`N~k~-?-K%-WJR3eF3grRtOJzf~HSV&xatVJo4 z95xRR9xmUvaUg8*U?vpsy_-q~M*~~yZuIUo4*2!TXf-elgC*#S3f1r~-o~EsE~pTp zz;Quvx}5I1Yv1qfDl9z!zEfwToIE2lb7e?MR+yUm&I6cT5f^v3 zZv-m6G_|_PRNUDEc`<6uojwJFA!sVU1id%wYE2#O=Ujug4ZyqY07?KRHCB@~XL@p8 z&I@VjX-noVT}UKSX{2U&V5-iXHdcPIdksKeTln8F;{;T>X>3)?a9MZ1EMKiuMM?=Y zUcSWF6`nX|GnDSfUfdLoCn9G@PJ&9ceZlILug_VwSPGPivqT63myZ9-SaMV69i??>)?hdlJ z8rcwqIWPPqCORSUO`((_&-{+jaOC$&bu0w1(9N>YSX6up;3{q#fDO9~rOWqJ&Y%Cs zGjiemiLe*ccJ>*M1aU#KJOznDNhfD#y-BtmQ!vz|$VbM?9mD1WqaHUEd<23#BJRbY$AW>zhFemmqDHKhy(=j>e$sCg>Uc`zu_@}q#jnPP^tAl z&YCv!WbRW7Z_hbsIH7#E?0MbxGk3$_Jt(3X19ltR2!b~d0+~XQ!RU1{T8A$H&OiX{ zb|*o3P7F9=1z$(ccdg}B{sCh@apK~1`UB|LFWS08vhTrbS_9#qBln)V0)6Hso@ws1s z?NB(Ly!5#i4Ca@yz4f%qU?rQ1-DfLXjH`q)A+uQz9p8cJ?w>I7!C0GjS^xPo=(WBs z)$7)&rle*ok|q(UQh~u9P4BTD6CtE%dwmo26du8mC~1!T8)i)bfr}pl6AT1;_z;I% zBLIvX17k+=%m+FbIP*p)T;KJlpkAKu=;>TER8~N#$eGT{HHOdT_N1EkQB323pSzwa1tKhw&2QH#JeD!M<&c9s`S9fgV z^s+2hbIUqwWzAXp^(M}3v7mE5a5%^A5ewl>{RJ3_#KiL;h-B-L-1O|(HwN(ogAj~V z-2;U8I99eO=R~7^nNg}1)4?G>UtOL9e945LWx{k3?QaXOjmBv5 zsF1rUCWGrYFF?i4)nSt-Wb+p@;oGuUaGnSUwFwZjAs;oDl_Vyt4e}hmpa4pzgJxbQ z^j{voa2|)7#TE!O_eb6)L=+I})7*v_^%feZjsrdjpi%%hJu5(&dlp8jM?}jf zI+XRZ$(?Py2ON#}EpAZ&KpRUfiCvJa-vlxVfe@~lSXANgt_L==1iUvaVY|m;U#&gG zXs6}1?R|d+t$uwd{%IvYlF$rX3l4RdhyWy@Gk}Lqg{1g=aZ?LxL8rk3fb>^jOC12V z>9MBc%O3Bl);?#^(W1-K%p+DwfWTx%8NG`4`W;}Ysfw80jTs`zuSP@Cq*BOCTMQV< z!qEjy++G61_VX}2^dXGeE`se8&eQ!IDK2FcPcK_+a&Yf_d%1N(S!FYXcwq-(8yt4p z(Ax+Nw^jh0#c&^Hya0iPJM|!oIt{wGB@iV?1!y8fI{coKNf;vI`Ce^;?p#`8LR)%b zf;}m566kcA7)rRT5xeE5?LFq~t2M3E8}LW;V||t*&}+T{4V`O&KRxa%>wW+?^+?W*N5Er)o1l%dp!U2LYq_DXW= hvnG^-+vs5c{11^bR?1>Q;{5;s002ovPDHLkV1gnOX$t@V literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/EndeavourOS.png b/root/opt/phpsysinfo/gfx/images/EndeavourOS.png new file mode 100644 index 0000000000000000000000000000000000000000..3aa60cff0ac8a7f6cb1ff9786a8078f269a57a90 GIT binary patch literal 1121 zcmV-n1fKheP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81JX%EK~z{r?Uz|>O+gsP?@h&)c)^1RLc9@) zcqLjg)$ILl%Z;=QOzT}rP=bM@D|IOE#Ik%zz_Agl2g-o^mK4rR}%xl+7teY4sZtUW| zlG)}dpWZe)e~ar2wpXsoIW5@qJI5-PH+8j*$$-_VAX85=e}DL6Y<20D3C9E*eMYeC zGlCbrI3AC;P$dFmUC8vd(U}gifZt&}Qd_vo;Uo^|$;Vz0yu9UbH2SEsZH^CVwvG;g z__PNlo7$zQpUF1`uTJh+7`dKho2wzs){zm1^PJZBsxRxuoeYXA<~|Xei>=uM=UHQD zSe4z-b&e$MCY`j;zCAI04SU@}l zn{Y+2>ZHS%Q$X`w$n>`Nl95lbs@@Qf-P&MsgDy?t-UPq0}g}N<>gtJeTX95URV4Gz-cJB0AzlQN*(6e7J+VR`4=>(O2ElQtBRJHwMB++-NB)C)J(=lEQFuKy6B};Dv z^brvBGX-};DirO9!J3XKs=&zESh+(p)UKyM9SUg#=9I}}Nz`fgLr@%NeGEo@rIA#6 z@51pPxnHI5fl2`TA(`*$nd0q?55>yWA50u5*!v@ZmVjK9KOs8%+Pl|Q<8twxV6v#h z)gk@!%mhBitNNlx-l0VO;>}*LfVjnPU`bB0v_*v%*b5`Q1ez);d%$~5^?s>ZDK?Bh zVFvjb(j}x=^vX*BY^4N3Nya*%>_^E%M~Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd0`^HnK~z{r?Nr@Q6G0H~tN(_7gMtF;MU5CW zY9xpt3W(D3{S`Eb;PP1lQUxTYi3TDP6dnx0gczdxzytC?crb#!YkTe8L0cLr+F&Cl zjyrqjLjwhTGv8Tq6;&E^1w!2wiIyPOaisPW;HUivrimCuN>5ME13sYIt#(yQ297i6Z<3#JL zroNV3o&*LF%LULL*U)8WJ&~KT^fTtGILhee+H#uV8i&Zt1d*Gs6812vbX!5~wgK{n z$NTkoqV+KNTCW4&B*3@XHw`Qi>S870su;`LkOASzCtKu>%uWfO`U}K!=e%yq6h=kG zvSUo?G`<&0k3wLuRj}ZP+;ll%0x?w*)PY)pO6h@OMJ}bMWYwZREN8|^u=ajz+PJrDhP0CK>jC0x z&ZRsU3yQ&%t|IngC;1r;2rEOalb+k>^gBl8sXGfiFn+W1m1j*fCVx!WjNHCB6)YGC z$!zjLVPW2NMGAE`gMMKON0H87qew@h5PIwV2#-XtUPUulRCOISL^GtIz4q*9=!okVeB&; zXRWV_CyaNYkuGYu?T%lHvXAuun*>%aM(VCRL&H;pJIefJdXz}j>BMip!ByeO@Wk~p z8D_g97LWw*y$qf;$`%-I|N9>f!-i{~Yb&p0+=!i0(c b0T#<|_4Oq|X3B?^00000NkvXXu0mjfOInmV literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/EuroLinux.png b/root/opt/phpsysinfo/gfx/images/EuroLinux.png new file mode 100644 index 0000000000000000000000000000000000000000..219759efb81641a0ceab008f2dde78a8921df40b GIT binary patch literal 1932 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 M07*qoM6N<$f;5@$6aWAK literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Exherbo.png b/root/opt/phpsysinfo/gfx/images/Exherbo.png new file mode 100644 index 0000000000000000000000000000000000000000..505cb65822ad14876382037af199ddb21859d717 GIT binary patch literal 2090 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Fedora.png b/root/opt/phpsysinfo/gfx/images/Fedora.png index 883e96a4a00b36db82269a7c6864f69b2e3d782d..0b0a451d3eb1288c8a6aaaa4a0626eca7f2dcba4 100644 GIT binary patch delta 1019 zcmV<@q9C{+!Gqv(kX#hSgNRE&5OE@2Tm~1^gW`hVL4Przq9(xw6+O5h?ix+| z{armKGt-^v9`%EN-m99Pd9SOhURB#xNaBf_4w$)UDjJFUqmD>?L{Cu_x{S^yOA6m$ zbCNRw0uR7!M2k=x^@ZR&I)S#5$bGjbfWQO@+zPV=tw$}@mj}PlK7wpMSyK4fbfx2) z0KxlUl4yk6@qhO`L`957wP`kxl>os9V=kedZpXjlEt*LZw@uTKmH@#O^akqfcKmxZ zF~^Zat!Xw&AYNJ1+;Xg|xZ_MuBwnH`=mQ#vCZV8ta}SLsiLYwJ^x@*TlPzlSAE=DG z=*u52Myt^b`m{uk=>i{yp>pGTBf!vi$2>x9)eeb+ihl{H<(5TJqQ>UW58;-Yo;2#v zP=5O;mB4n)2Kf&yD#y>6ffH?P@PaF2l)NUSiG`U&uY2p zi-bGGMTu(N#A&n=O-JPn%}%V9EG^WWI49qS#U$P?W;xCT8r@7^Bwpylw(QQBQSuux z#jo%1}d1w`C=C=IlrvwU&-z0ZY0_{h8&^MGq1!XVVjSiy5-{qpfW|&^# zXc_r&3$0H27{CW|L{<g-OOUQp(qqvqjX=Dzy1;VmGqg1qbV5?84a<$75vXVsT*G-5Eksk0Hkua5 z#dd7@swLx5l;EN&D1r0(Ah?RmpN+#0)}Y@q49n%91fF?z2nyO(Q-Pa%HYz%zT?k5` zi+^Vyqk7|}q2T&XboFdhj`Em41ts8?XD-kL-6ubT1mC4bX_{xFpzU~voS+2C*w0(b zi8BegNB-qC@h z#PozF;7FFu(t5l8Gzn(y74-Eb_$l0|!F08>=cj^;T%}n2L>l@#Zp*Co$>>il2#No( zoCI`W=w+J!jRz=B@T?aTJ%ZGo{SWkNrd@KBUvQxjP+ivy&-eY$551foN81RT`{k4* p^i1nZ>M literal 742 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmUfZd~z?Faq)=OI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i>Z2=EDU1=9cj|7UQmqX>C4F?hEz z_;oP^_AvxcVhEeY5IKt>W*$S*GKSPu3>oVfvNkc~Zeu9e#ZbIYAh1m!W|~0RE`gdu z3Nd{ONz)Wsj~Qf4GsvFhP%_V+4V4-hc7_{>zW|-+6!j&hzv4U!Q;a`TmRd?>~Qk|Lr%>MWF7qRFFa-D=M&q_ot!_* zH?1!DdFbbo+b3DmzPSI8QjjP*_xnL=)AFCzT*gu?$>)wgFxHe1uHpPRvDdGV>y>b; zm57$j>_d#4zo#CWDN-ZUx2lEXr@(xk*2g`q;e|4bCp>yw(=ey~$2CVsGus(wt~))Q z{exl4h1msl`aL-ndMqb)S{|O%|10vLtY*N`LXk9EmBO0K!LgUM6cps9Oq;n>wN;>% zL#wq-XxCMyU?+`we{ZMYd1@t}W0@;l9y%7=_-G#JnARJsm(dxldu46R0jcTUA2qih zSh3-!|Dz8r_D`dyOsUXwC{g#i|GRIOc>AX>PvNM`^5 diff --git a/root/opt/phpsysinfo/gfx/images/Feren.png b/root/opt/phpsysinfo/gfx/images/Feren.png new file mode 100644 index 0000000000000000000000000000000000000000..d1168c86bd5bbf18c9ee097d974d33ba2d8baeaf GIT binary patch literal 905 zcmV;419tq0P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D10G34K~z{r?UqYu z6Hyd~&&?#QeNYN@AwFsl1*KaTg0vzi2o{67bYlgze9;zoK*7c@g=R#Gmd^3%eSgl1#NqMRL@gR)S@)dw1CpM)(=K)(lb zMS1?DjT9}4fCAW9A(K~$WAf0j7JPO?xW~Cq@Fb5Sfp4(h1lou7OE3?VSBhn3=?B^P zY`9g5;NPM!Hp_x5o{<)LiOx^ZOmPDHU}lt8gtTbU$Wn%9Qai>yqb>9{&7xd!r({J+ z<}$Smj#5w$^|zh%8}Yeo^B87^mb97$e+P9S_(OI|M#W^OJd?LgN?_+>i}TmjavwU3 z;O~{|lK>cVEs(T|+2^V+Js-Uo0$+ysnB?&pS>l*r$_Q@Y$gOB$xBriM4IMz>r^@wG zlE9a~X5JuU(#lanR9*I)P$z=rl)PAZt0z(@Kn4f^yY%$y(l z`R}KoF1meiS-GW@U*wVW1zhh!EhLc!o`{b4(F)50NZXc_{E4RTaBm?_BCT96=P5`HU-1U~n#m zD=!0fHtw%)kyPKr_rF4Qy7(s*(KjtNm%!khhU+7UH)8?bkXpp1=IvLJz^L21#lOgn f_!+nL7a;ltYGfjefHgsy00000NkvXXu0mjfJ=vl$ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Foresight.png b/root/opt/phpsysinfo/gfx/images/Foresight.png index 34d427ddac898eee507610cf64e58a026a05dfe6..213257b63e592f90b68f2ff071625d95ed2a2b56 100644 GIT binary patch delta 1358 zcmV-U1+n_%Am9p+BYyw{XF*Lt006O%3;baP0000WV@Og>004R>004l5008;`004mK z004C`008P>0026e000+ooVrmw00006VoOIv0RI600RN!9r;`8x1b0b9K~z}7?Uq?= zlw}l#A4(|{Xu3ctr7V>~r=`=G!gQU^z)VYLrp(sPFr|gkjek%9QJ~1aw2p;RAmRmx zCRBtFP(j>6!i|_1m&An&)R35Xp)nC-)OaBhHF>?LZCI))MB_~_PX6S}d(L@s{_mXg zA&LLf7y%do7y)mGD8KpHB=nlwF2$ ztjKId^GeaYa(`qjN5y_VGF0(pY6)!=CuILC0J%ZlE38JL1{A47p?Xxi6nR4^;78s7 zs&XN}5BaK*&yTE5WN{*^kL$C_xRFxMGHi*n?+d`=#9&*>=k<-KeGO`BM~$s0(u^W2 zP|Y$_3NL39Z20~WfWonX z!X;?iX0%}=YJUW^uSd;mQQI114WeWR%CewI1-v=v*A_@9EN6?Q0y!%BAp*hvZ!my- zK2+sFGmI$4%=V#^ms9Nwqn=K*$cK_FXw_q=V<%d>895?otQ9Y1G10{h$QefYZbVmC z?Co)8+kZK3EKU%&Kg%M@P<}r=CZ>$I;GbQT;9y-ieyF zqksBMsJszPvGMBdzUd3uO%{qPK+HsODTIe?!x$4Xtwf_I-pFkHsM4$bHu6~cY&!JU4+;Xksq9MZh zqJ_LX-_E7EVJ?~Kcq222irdgkADU5((wwvndmEbej)IpIh=8L>$?3%oQh zSv*n@K69As&@%2G z(Ij&*8B@w0Dr0@Roi8knTq|wonx&a*MjxL}E#dlv5=`avC5$}DMgT?tMgZ>D{sjE9 z>bK_oZYcl&03~!qSaf7zbY(hYa%Ew3WdJfTF*z+TGc7PPR5CI;FgZFgHAgEjFgh?W zy*XMz0000bbVXQnWMOn=I&E)cX=Zr{7cs6*yxS%%r{&pB$Gr%Rion$6;*8mc zImyw)A#i|5vLEmfSnKDSM0{RA?RF|LP*)dQp2DfYjM~O_Si3ZM!zH55$x|KIhZDLd zfuaI2xjPmI>_$wDi~#xx=p&$_dQ1X-UX8s#b2AVdi*J-3toC%lloADu<0VO~pEjyA z?Oj|`u5O8zaXOqh=fR%NQ}W1v5)iYDOJ~}YL-W%CFTLs`FryBIb1l1fZ4+?W1H|y) zjsT80FUn%oGqHA=W#*N`>j?Ith3hE(sLh^RLz4i>D zL@J?%hC@p=dZ-$Y=&LQ0CN4*g==oy7B7!f<1a?*cCmk!(XH0=R(ZN3*I%~cB=lo@LW0=S+4$Q8RvQi!yJjjwI9?3|?w-?%xAIpkq zbuv5_(?wa{lQn2_w|j^{(lYUKLJU4%Q3yD$qm^yeHa?ljHXUGchGabY3s83h%FUZN zTHl61WD7qB66S99hj1+doeGL=j8AhbBSUrgZCKlULVkHS(BaQQ1Y+~VhJ_2UCBS%n zw{Oa-)%CT195f&;V=j^tld&~zB9h{h*x#8eLB`$5glnOP-OPnvRscWEsB2(?_ORi3 zvGHn|e1AB|z2-w9NGldQOa{!U-oNH?DZgUNxIIMN3+Z%@06I0;Tv1-(k zRN5h&Z3rWWXJ(w;QFmIt#OdhA5P{Ked9aqDKJZ|VyuZ`N2#hH(rohMcq%Xccd7?zE Ooua3g79J>Av*lk%vM#^? diff --git a/root/opt/phpsysinfo/gfx/images/FortiOS.png b/root/opt/phpsysinfo/gfx/images/FortiOS.png new file mode 100644 index 0000000000000000000000000000000000000000..3a7a604c76966126d0fe0c120f4739d09e9684a2 GIT binary patch literal 848 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 diff --git a/root/opt/phpsysinfo/gfx/images/Fuduntu.png b/root/opt/phpsysinfo/gfx/images/Fuduntu.png index 73e2e432ef925ddb537631b0605acae1fbd14f22..472d473ad48f2c592b0a4b327989f4a866086e75 100644 GIT binary patch delta 1780 zcmV004R>004l5008;`004mK z004C`008P>0026e000+ooVrmw00006VoOIv0RI600RN!9r;`8x1{z63K~z}7#g|*C z9#<8|e{1cT`Mz^YPI96tiM2GKSZpy5T5nJq3O;Bm+J`>a27i4JjABZJY6D)tMvycw zVnji!RH~qegftbAgd)_Ih(<}Q)?!jLTAHLub8h{ltFm+@!+MEJ}% zr%wCe(o0u8?0@dd1~39VCc+T#?hu$(j9 z6i^JI1afTCCNAH%lRF;ylsqZ-5|#m+JI8@l#?S5`@>zhNeeSONw@%T+C@>t5iWG3X zR>3JiQ>H(7Cm-5*PPVlGlasOmxOcS?9FTi9$~)I@*~lk=AyP|j^=Ra`4n{<7eLLsx zx}Bf50DrH&#&$DqSS>(-@A%lRlW%+9cBUvgmJ5#Hon@7!P;&}o$Gezm0g{d@SUm-l zDAJL;LTHwgc5co=CdRu#n6Tz*R5rF5;I*ZO0E(l_U}&H5g~bj)Su!m`Tnj)5wPlU} zy;g%Z^c+F!^J)aRGTX_5Joi6@z^OHtQtf!X`G2L3fl7%b=O_?K4?bRDw!Zhsx7Pv? zm;BsVuQ-C$v$wKW_s7wLk1~1W)X}?_0Yvv7DEh#fg0QVfcwGmULarH#lOfNYWbxeG_un=lPPsST;&wPF@;bI$juF)N^#)YM!iGO#6vx zlAuXuAR>(pyYAQ+W&UElDd(+IU36wIPw+Q zP}f1DT0DZ2)Yla;MHQa!rF^^v*f$|}nDcH4l+rPHSqYam!H^Cd*%Fu;o+L<&)tu*5 zY0~VV(tzBvTR9m%}_N+5=22vAyE`Xtb!Cxz(9yq4NU-MdY}gkT5Y^ zbZmQ@%Gw-jh_HC88ijNf6=9 zlpI|s{8!iQh5!#t$vS`=1EUP!MZr!f@f}9;ojJdFosZKoz&CHMa^}JX1n6~}&~*X+ zSI55r8o324%GsQ^0BryOC3HntbYx+4WjbSWWnpw>05UK!IV~_VEif}wGBP?aIXW>l zD=;uRFfhG2T0sB+03~!qSaf7zbY(hiZ)9m^c>ppnF*z+TGc7PPR5CI;FgZFgH7hVM WIxsNIWa9k*0000D-K_wL^JV|<>OJ2#ue*zAwu zT;@G9XU>`PoO9;uZoFc}#r5v~ZUFUVmn>aLdXj2d<@fiu-+ln-U9@cJlB?EzWKQb+ z*NCy!a^(9fm7|&N?lwPaHgPt`%NQ{V6fxUd2sl5QPT(73D!ZP-29 zcz@q6+t~M6km*oGV0z_17waR&ph>FmbgBVHqX>T@uQFXHv{zq=fm=%^o`;g?}$jw5F}7!(k}Q4y3tL!0CE z9>;APu5`pbcLv`g_*PQMay}VW_~n%P)4{OQma&t5k9Yt@fl+R)|9QYj|L_uXA#hS< zTc*_Z(eOQ=2<-?z=4HA5N5-e^f>z7E&4~sNpZr+*?kLstA?v}UeAUlK;$U(VlN`yW z$Ef25^=07!`xoDu+1G{5=T@c#MWNR&@Kg|dYW#Q)qD>E>cgx^bcNldRUvBNg5u%%B zW}ebogrUfUKL>m~d|H$YABQT;dpj}zk>{}1jxXOQwL>nW!WIK@ViuG+ZVhuD6P4dF zJ(jP&3W_&uXrn}Gc^Yorj{2rYargV5*?}Y%>3)_N8C5EXD%CQsva%hgX&EyrhFDZai0rLuj6c`w<_C_$PY1xAbId9E z0bIeb74(Ih!sXP-bzW`LBB43`yaM0?WGbXwz%EXrS~}vBdr3>htP+of$xJ;}*9&k4&!`?HY!k~yN+AJh_DFF6+h zhWR2P`tEMaa;boZgGlQ+G7Uh{hBtw$+{B@qZ$z z2hbCvlG76z7t=ZJKB41z9iw4P!ioT`J0moh(~#H#klJjm$B<6+?L4VWO_44Af1}j%RQY@^sTg&S2Foe#mP#z7`4;*Ax&QC!}gq$`W76Fm2*wr36tzMk{DA2p?BgWU2k%Hk|3G{ z)yOj%kNoxD0r1{Dtl?w(V|rJmCrCKrD#0+15RX*gcu1hOy9>jgWcC$-Z&|y8C*9}t zR-rHADvDgui0Lt_RAOeGw8ik(=>2ZKLH;J)4uEZY?AV?$EapCJF`g-fc~4NnU#xTl zh}k~SMEaq{=UW=KUlWAVn6gh0*a%gsTtEI$;*rL@BVycn&J=M4_2v|QQLp0Jpm)S& zbS0N4qx!P mX1_N55(;`p1rP-O-?ab5WYN+qo43i%vR|%P`pgA4tp5huO%+)H diff --git a/root/opt/phpsysinfo/gfx/images/Garuda.png b/root/opt/phpsysinfo/gfx/images/Garuda.png new file mode 100644 index 0000000000000000000000000000000000000000..6f2ab6e81cc8304f58158327903c5e16b3a56942 GIT binary patch literal 1858 zcmV-I2fg@-P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n82D3>-K~z{r?N@0`6=xKk_jm|eYh$Brl|`2K z=9>YRAh@NCsWz!4sf`+w)~%*)u@z}+tqVk&f>IHcf_1kdC~n|_pdero6v3*oTC8mi zu@!IuS!8*DMsCmj7>rh{(fZSye0eW3!#(God+wcw@*-ZuvxfEaJDJVaZ}UDD8!B#T>#C^t znkpKSSW6=_8fg5{CYoNVCLwmzkw|HvK8dA2 z50B0m_L`ztjMPsKH$^eq5-xnLW;C{lG`mbBwxN2i487M@R*<&zI_cr4eo;9s+*m}u zzP{9d)I#zKE+i3EPGUnPiBvlU9J15++$Nfxf8%&y^geF`;_=}%E!It4TXIrXyBdHo zm83-(asyCbP)hoI9LTQEE2Y4QOBB2NEa`zW>6N!8ky~&&$ks{%1L290yZ)pJd3Ktd zQ(4&m{c#-)n1{n%Q5>x+PEHevl{ebt=3aup_aG1rX<;}$5`A7`R38d5UtPfgnQyMj zwn+K6L4GL41P1SGpy4~pXl#z1rWZET%&f~XJstlwqORQUd0YCZ+skvsUdYY;X33dE zJVM@xjQ@k>?i|T zQM?m>u~-w%2dU}RHR5nHi9<~!`_2iHL1YgIF{xynM37=4Xo+k`7zm(p`JE?#Rf+{U z_6bkR_B!bsUrdZ2J_qfor(xMmG^3#AoB@x1r(807MWzf_^P2CdM{kpw1rmI6TS(2n zP2vFNI=+^C;rxC$I#duamN?jEP6@fg(>)11Pac?LZCK5#^5+u`b88BEOqaC>5QJecb-6%??kn*6Z!WGm1X zeGSHNKNMkga9!>P%)RZ?)Nsz(O;Jp5m=%+UMKSj@n;blx&5mvzOwN55r3H=2wo}lN zzmp`mt66cdZN38mN9o~cGF#(|7og{@A{G5+0z2E>>jR(x0QHA?G_I0O#jb8Q zB?DqI^ldeyLmj#OppF_+lc2VFG;MXg)jzVn3c?w{zv#6}~ZW zKenS-UUI|T+1yzI7~$;fZ0gdbi`inaJgAK4tSC3zp{f(Mn6qgbB=_5Ki~43Yk$U_N zsd;dJ1{C1&1DFKo@9YJx6bptw8CU&*o$gaR0egOn?^+E5KWFGfZgAI=>ryBCe9>ka2zn#FL{> zWd5jtE!Xlz{Q2m6;Ky)SeqKmSf?vaIP;M1WDhWUh2@2(;ahcExtl^N7tDZxqxfto6 z9R4w90=x&0?%?s^7cOdEQ**ogDhznf11vvRFA2bW*mArfB>^lb0mHT_Ro|*kO$|ia zr~fJDf`wsAyPDZ9zltp=L5&e)RRj}iC$P(qojqXeeDz@UX^(MVIvXjUKCD~Ld?Mw~ zg#tMD%g@9_Hc0XKvH9Bj&SXG9Jy>7wy>P3|NcC*tF=A3TTY5#7_u`a5TS|F>bU*e2 zD8fkU+=9v=mFGEzNT^g{1?eYVtzzkBfSg7B=d>bff@t?N!Kv1L@A z5n1-TybmM+9z7<2*RQ(jk0h_Di(i#Vo_DyJ6bJrv?ciYXoE)LqmKBCz*_=`rpHERE wio(SFQ;A~MiFf3~kB;a2zrl-mexWG;0Ek-!_Iqh90RR9107*qoM6N<$g3WApyZ`_I literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Generations.png b/root/opt/phpsysinfo/gfx/images/Generations.png index f3adfd0472283b6db52f844fef100a95479c2c0b..1938481bb878da83291b1a5aef127f398268dc40 100644 GIT binary patch delta 2004 zcmV;_2P^pb7}pPw8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#EHc4#EKyC`y0; z000O-0*sCVj~@e% z9swgG2#1GVV1H-`c=!+)9Gr}Sfys!U*L}P{=o&%L$vgv$;ZdY}pCHvmoKcS_Tt;F# zc<905fkOip(1Qn2+`m6F?3xkkA4bqIjPc6HNOwO%s*}e)VhBfgoEKT8c*RT@8fZ@s(A^Dm zbl)izk(d=+i?mqPs6r(cP(4A~+7UJ+T_8yU4I)AUNnR7VMjl(d zDk2gi;rdB9W(P?m+&_{=o}26jt|To2X#na7SXT$s@b{fNKxJhn!n%5d^&}z^)x6%o zHO-6|3D>B~FC5_smsTXE_%3kCZj}pMl?%AK8h^Nb8z?UaN=tzoH-PKc-EpG40zoOS zmo*@DlLSOW>c|?B2u%s=2_r!j5;LTicWNlfE}sRiiYqE2(5qL0ON>zHX?KVmb*W!s*2XjKIKzUDsGwz5rKI1Vw+S`F(kVx7x)E&7Zw7?j^SC( zE?^g9-vQvjQARF;z59XFBq3F>dwHn8zmV9gp}$6i1L4ju$foqvi*s6TGY4u<-ug_g#9!P}6SBEMvkT-r)C zHBlAvT(YzBAZHJ-eFyOMVuJ1jmMsImTnH>(3atHw*R}&kjsSmM<~rIY>!hODpvIQU zwj(kG;_^3J7^`}|lT~JK1r`!q!0&&+BY~GQKKYEK76H5W0VmZD?0iZMZT9COyj-#h`088W$De>XbAgpBfkoc|+j3Yrfpc?# zGiQLy+zHwRYG#{=v+jaf=78I`^3CResySVV7dcd5$06>0dj0)c1m6&NMHXHxUxoCR z-?;zm48Q%ZJUNO<^W~LOhWl%45&p^Ei*WZr zJm0(>&o{CM_8;c?Gf3|zFSNkE~#&=#}M|78T0=dS4toJvZ~_%k3@ee^ys{f$Tx8425#)h$$k$2ul$ASv21 zQB@rgQlqM31D5BKoqy}n>LmkLUi02pub0#Rcqe4E_aIDCx~6to;CF`rxUbW7JPJ^K zqIbn6Mk}jT&Q?%t>kJSP3*JE6Uji;sn7Jo|B!G#^YNHz8#Xz+7F z$<-eM5+Q|t>zo0rk=1bWoZxyJcE!cPh3mcx^o8O{m=Zzf5K?Vi&`Z|ri=dTBsEG4Y z$rS>!uyeXjVE1rS)z)w-ir}uu7`Q&q68c1PUq>+#>Aqp4+Vx#GfHWg$A(39cOO)J) z`*2a%IbX2@mQCcbhErbmMI;>mRpba{K28-zVsHehZmQ58DG~7KzVDP&$rS>Mhn@Gp m8Og2TJh(o|T+zZE8^ga&Y!wE@R9`j#0000yG zbO0<|zI5Rg{-2g#ZaJ3g_dn)e`>jjY-v$r6C431GcxxpW1gG%kn90k85c ztw2N2z?r!T>1wiQO4LsD#yMh#c0VvluY^gF(pKJ=E#iZkAcFqy7zv2Tlh)SgI!U^e z%#{*e*Ht^Wk*BdBY9xo!1iDLms4B6^Q%@zgxZhNV&_s7m$l`HM*ody$#dxj3CY9=TJM*#~A;) zYj^Ksv5P>mKGrr|n&4m;VL?EMNMDHs6X9@kHKukEH#J7k0UBEk1DQsnYPX*=7x(sX zat*)VMt?}RpnD9*x=0eVmQW=qhe&ccNOX=f7m-~gM05!?-Dl>k9d<6AcHd(`D=Y*n|Az7>R2U(U)ylXvs4kuRd z;|)A>27@t9J%Z!MT{)5T=T7eDDb~S6m}+b#Q)ZnBC*8`jd`OUHtH(y8Y3uZpSUZ7H zRXz1MtJ^5=_=;F5+RKtlbUg_~Q%lZ9`Ek_xuJYqGH!%{D&T0X(FogEWjsDF)dg~`f z{R1p7bkX*tm#G(E>8_UDnB2Q~4m;JZDA2cqk%b<4(uGHgJN@ zP;0&(F+x6DNWj(D^ihy0MHNMuSV!A4m19D|x)MUlEQm)aGb%O4TW@Jlb18tToB65) zM2vRSOqTVFRm9|FH88Hjuvhf83xsP)Kmja2|V9zp%yV>O612mj(8`m~<$ zTC;%o2! E16j?cHvj+t diff --git a/root/opt/phpsysinfo/gfx/images/Gentoo.png b/root/opt/phpsysinfo/gfx/images/Gentoo.png index d806c576b7bf5069dad97953a5c740c2e7c6f47b..c4ad6b0fb1f716d54bae0eacce3feb9b55789ba6 100644 GIT binary patch delta 2158 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 N+0!x5rZ3K;{|kUas<{9F diff --git a/root/opt/phpsysinfo/gfx/images/Gnoppix.png b/root/opt/phpsysinfo/gfx/images/Gnoppix.png new file mode 100644 index 0000000000000000000000000000000000000000..c637148757aff959d5c3ff7ff1d6fbf72e70826b GIT binary patch literal 1205 zcmV;m1WNmfP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81SUyDK~z{rt(RMfR#g~=r}2~-X=+J!F!Mq& zN;;QaRfII6iQq+rmgGed5yFttIp}avL`j!j8BP>*Q&HVyWm=$7lX#+Y5M}2ebEeGd zdG@^fw}19O|7_`h;bH#ue&1Sq?X}n5>zl5+>ggLe4wk_N*aF|eU*Q{g8=iuti~9y9 zrrZA)1D*~~!mscTc)?HMRoE0>gU`U2IlsUYaB7A*diC@j9LE56!|(7nya6lW1)swqaQ58^9ku8? z23$oS%_lG`q1Gb7CG=Siz|z<)MSKd(gA3tom=4Dz+$8+vFbE%;7rR*mob6_Cw##BS z34azm1iQc$a(PSa_XRu+=cY?Tcq`yAybje>#k>O?=z&-b;Z1-?!Mi9g_!IbyeFNNd zUfhjm%nLmOlQKjh+K(iDOROPbOaot?{%eNqSiBQqE0hC22bV)-XXCklT%q5T z({<9d|$eW?E&A4ZWAvBFVdTwLbOi<-v(pLV|PT1cUQ(e|G$m- zi5H^%VEnDIIwrxw>proF=tV^u`V3GDJm zt4A;y%Cr5X*tJC;&jtG)j8ze_eXzwJ&x6HAW2u+$J)r$1I7mH2KKEYFjqfHMx*k8QeC%*-VMMh39DkSCTQDu5wlXh$ zDigr7E-R$-n1-@{&JI3ac+yo=#yu+!JD3dSc~5wQhejbQ$P*o7?D@w|J>_~T;_ z31bb|>G4<%;mrjfgK=@PmgD!p?a&KWLj6$Y_O|tqa>%ALdS48Yg@L782_rslVJ-AYp zdJpd=a7wbanj;QsP3i T_+SCP00000NkvXXu0mjf^7A!v literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Gobo.png b/root/opt/phpsysinfo/gfx/images/Gobo.png index 9efde30119e0af4b39f09646e4a24793e5ba56b8..ed53d8a28f6117f98739fa3544d8ee6a1c647bad 100644 GIT binary patch delta 1040 zcmV+r1n>Ki5t;~)8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@g=mZ>RtO02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600UV`L_t(oN41vUOH*MO$E7a&3%ZGdy67S*38IUFDC#zn2qK}vidIrxh!9dn zP$p$06MtZ&{U9YZBCW8ZR9q?QTvMDjbvjMY=6<*>H`kA+^So}y_nh;bb2hAnyeYNZ@B0M!5-H)L5dv8;z~yCVW>9Ez{hewv{cMN+tUEs+ujG+t9Wp9 z$&4nXn4s>i0R27l`UOPvn&3ABO;uc)qGL!g!Hwe@NeYV2x^+LK2u_ELQ3)LR=O&~C zqXvBJxPL1SADZXj_O(fzeUIp{z(Ad)4Gh z-@wC4H!Ftgfx#f)o{HfolY4m-ZWfOMPJoX?o!`qKMUnFbPAQ3B^H{85c-y)>B{XWv zSI1JC1SyJ~D*PcO@oOHOP{|YdWN>eOCD(F_>3@6%DTuUv>-H?nSONju{$2j?`!vrNpfI z0q`s=eFM-8?vsXiP{VVjPLZ|&eqZv{1<2k88yu{+Gm`7ZVT0fL1j?Eclz8AxpDb9} zq<_`zl_r!b*DX#M@DcwPRf5Rw&vFB&+n3$vTOD*E1JHDpllUO21d&WjuPo3RU4Sm1 zKkZxdVD2&N_tXq*uy(Duksf4Sl_0WpxO-I$kabmp$S(Kl7$EDa1d&Zs-{3-E2=Lug z=PRMmH^OSF&QwBzjz|bjMC`E6*9L0^3x7-Q{~bu%(BsGitAUrI&eehfEP&6>n1>nK zxX>Z7W3d+wMSGZzvL{g_b<3HQ#jT)q;4LJY+00{s| KMNUMnLSTZ^OVIoP literal 2193 zcmd^q7usjfTY9|HKVjd#@AG_qpWp9!(=_Ru zxj8ywX4u>?0Km-14dFDjFC_2jQ_vb-p2Y)T3fTPfmi54ve=iifHOE}K*xbAT<}EkY zF2QauGZnAU-(3dtzSFV4v|L%ED_>>Ih|=b6@US9A&i$g!p=obMo36)blM*~v<1|gt zFnO=ySfZT1N5!LIhmH*GIWCP$f{DqJ%)|2HL~X%A_07G+z7z?2w`s@u!Kwqs_MLbH z9j2dB?!O4PUG85{1oKX5c4rNioYZW}6`x9z(l5y?PZ}>|4Q*w>xO`D%3LHG*PGk%; zoHos_oM6xuf+SmUhH~@uzW9>9-x-4)r>(q{vE7Am-3?FS<>9ke;q6R)c!h9fl^{PG z&V4Yl=NgQu=xs^2He{M|3svjxccqld-fx!3Qa!0mm|PAk3bol~s&5~69j%tK3q~6A z&ChdSc)e?TUEc~`ry$RErW#6fT?@L~ch$j)n+6F3?<^WUSl{1T4D;@)fTD(3txjm} z<=(JF^UdcPBs=&b_8m`Yjpwt04*o3@gAHGlK~9xrYxnb|vU^kXyo6`{`}l4}IdQMn zc$Ozwq<(UhBX6i3nPK9VHmTEFVS-TgwW>pN$MvAzkjkwB~fn=mPl)tSVJNEF5c5)j1m443!=F$|vwe6TBp{$Lsi= z&92iDV~KEhE!I^gfJsVOUn};7t5d-pm$%?F{Qi@tgs$09(`)$2@$B#C?ozR;NTMzo z@DxaFad=(NGmO`5r>lpm2ekVw{js?4khSMgFN}9|9T@$mP-#1F5+5Grvc>K;k*T-O z%90a>I{lE)erB|tBOOU{im)EHUPx4HtmmC=42z;(WxPA=%yNp`RPc^P`vgG^4e>Y!fg8dSNOjRe<(ml2|VoxR;;t|G*JM)<&?={4DE2!+7xvJDe0 zxJ_$tnDx#!r-3)F=^3|39AhHFs>eMq+y=v#LpfnLy2sFe;f5#D3P1=rL5q$7@c*5# zeEbLWle}?s!?xo9%xWd?5XRD3^8lE-G%|e6mXqR;g;QnYXoeE()6kHRkkC~WMMdoO z8TY;Qu28BDuwTp7;QHGEO9AqYg@R3+mW$q5uVy+v>1N_!I+mFD%0SH$pLz}LVd(R6 z-t-B4HiGxSC&HHpNKd9~(Xa8x78POdPL_c+veA#ej{4X~e&gNW2~=}^Ulzps!Q1)( z0Dp~8nf`gikAWj3H2wwvYIyTiqkScUIlgjoquIez@+A*w=sEMhQ6ic@+3~H50YDc@ z(-i=oen^scA;FuE0YDduJr*sohtRT|ECcx-5L+e--v$7^BhUq)gHB%Ftnq8TPk8Gz zJt*@Xi1QDC)d2!v(*#J{q$hNU?teErlpHmE)u|e8}feoQ<1t zmgArZAk9dnmHD3{4(ve;a%fXiYsIjsNo0bqM3jhoGCb`1zxr7sVFQML=XS!|Es fl}=C$_?{9ppltQ=QRRi~1X4w=j}B+8-Er|>^MSgX diff --git a/root/opt/phpsysinfo/gfx/images/Guix.png b/root/opt/phpsysinfo/gfx/images/Guix.png new file mode 100644 index 0000000000000000000000000000000000000000..b4fc134a50a8d88b1e5de278950de6d434d6758c GIT binary patch literal 907 zcmV;619bd}P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D10YF6K~z{r?Um0< zR8bVizxR!rla&iIw4ed$2jZe2ONcV8sHheNnPRnZQ`DkApk1^JT11b9Xu&8l5yL$=Xhb1? ziXDHs)H&1erUy;xD5oBXO7NQSXC{t!YGmasO z%NRhAroaNqDoU1oP4avJzzi6`8LD%(M@GR0-m;toW@nUKTAgp#{i?y0WzorvKhrn9?R4B>3e;wzhKFnNj3`zMP-#1cr#vlY^{Mcd z0U?HKZU$r zjpqQ=QFL+Db{p(g>_az}u~kUfMM)55`lsF?^WrB1as(Ta8HljrN3oGt>vs0?(S$Vx8qNr1R3jFUtGAH{a@ZPqXU;#P`Ow#wu198|0*b{Tk`;|36o077 h@X0kvljeT`_zkM0@S<40&|Clj002ovPDHLkV1nT!n2-Pf literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/HPUX.png b/root/opt/phpsysinfo/gfx/images/HPUX.png index 6f55dd42698a7d69cfb580f068265232eec5d4bf..0ebb4adcaffb540d56512036f6d01274e228b1e7 100644 GIT binary patch delta 1144 zcmV-;1c&?U5`YPi7k?lK1^@s6b9#F800001b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^ z1poj532;bRa{vGf5&!@T5&_cPe*6Fc02p*dSaefwW^{L9a%BK;VQFr3E^cLXAT%y8 zE;t)BPS^kd1Mx{jK~z{r?NnQ6TvZg^_hynzI%y|kI+@ACB!5nmkdUSnBKVhvLJ9q- zKT;tdrDCK0*`f%c1&yFIp;Tz8h>ueG(U=b#gJP|v7~_YaU>_M`4bj%Lq?%}Bv^9@O zn&ny-W}K!0F%f^91MA$g_c>?pefD1aT4rQMW@Ls9ERTMt-#3T3x(>G^T8{Eqy<4BZ z+__a_sUqx#^MCU!Zy$DJKV~sqXLW-<^CgI}fD<@ThO$SN-dPpWg?!7e%dwnMVg@6) zf)8-UHFtr#NP==AY~fdI+OpH{t{BNh#EopE@i9u+WxL+P0_OXy?^Vf5;h3`+v|#5w zhE@tqsxM!CnUd!KFXBy1Vj^a-;cUyEl}?#hYioaHmVc&%EXzt1TXEBU2LCBEg`7|; zSDtgG_a??MhCBETKj1rD#)T3q8SS#J*D-;c)O^d`QFP#~HMZuHospecvJpe9hC%+k z&el~+u3xBsfI;2}I>DzIcsn05B7QOWCa$jq-QdHi0CFw2HyJ>;b$4MAiwEq$J9rAO z;Wnl!tbbwzJ?O(VjEI!@9>e$uXO*3j#gcN_U`g62kF#S!lKH6ZB5#?MH4vK^%zU90 z9^{$HVyE~y&v`Nc9vqT$)mFq40eN`bBjUSwzuKz5!5{b?kKtgewf5pJ?us8eU*S}2 zmkoB#selE}CJl4l$%hTw=jJrK%|2%9A~Q7441euSp7EfGhOTgh8mk$?3|%#&qs`iS z=xE`n9X*0P>_Y;xP1ZEv@#7c#6t(CL1;FnUo88R?M_^g%!TF$F`1hl{MJg+%*;>Azm-Ru-@ndujhxgEeg7 zcY;|tc3%Jyi#)29!zFwT2hZ-X9cM_hp?`L3KaNtoAg7W&@bzj#1;DzW)_pqi)9`Tx zM9fnES)p54Tke!^qx{u+TkpM^B|0R+H%>SH^%K)11vf8nb6S}Yv=)moh>Q3X{WN+z zxi9DZis745h6tuNETrrH7Rd#Bw2F0`q?G#OwOGqJl5Z~V#P_G`m2ST3rF#sm6mjXo z26w|o*6B+*pa$53!@{4bFinejg#W`6>5SB(znhHpUt0000< KMNUMnLSTZI<{Cl( literal 2411 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 iR5CI;FgZFgH7hVMIxsNIWa9k*0000Z& literal 4217 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Hurd.png b/root/opt/phpsysinfo/gfx/images/Hurd.png new file mode 100644 index 0000000000000000000000000000000000000000..1d851e549644c8945b62fa3b70d97951c1a7a7c2 GIT binary patch literal 930 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 aEigAaFfce2OI-i}05Wt%SaeL2_6euH9IC?r diff --git a/root/opt/phpsysinfo/gfx/images/IYCC.png b/root/opt/phpsysinfo/gfx/images/IYCC.png new file mode 100644 index 0000000000000000000000000000000000000000..0c30fabbf2ac7ea5e87ff4988761a76df7874a1e GIT binary patch literal 1164 zcmV;71atd|P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1N})vK~z{r?Umh6TV)u)xifx*kfA0nbtWV6 z!jrj)iw(ML*^HJ=vsvL}3^L?GvW!XAf@~xd5ENVaIMB6#97?I}fO<{`mL7ZRX}bca zb}e+PZ8_Oixmk`;FGiGqz{hi%!WPJz2WO`niMh!?0gk3MtXfqrtV3$=MlRGp7&Kbk-E6#7~CMotWL|w(=E< zPvGd86VN=+vDQA-%gqL8F0~{(O#^KhT3@aF=rcgTVfN)5UTjWa+ms&`}>eyl*8DFVT>C#2$37z4JvSAc}Y4 zxTY?7ej4TSlSI)=#e}@JS}AzJNk2FY8silR{I#kS^&KN>^s}K>blh>3ADJ@|D|ezv z`6fR`u7lP(4#T!d9(P(KDe)G=UJD%RtOTjz!^{Re%(u>&k_l>B>AiX5q&UYZv;ADp z=U`?CnDW{-*gqoN&+Bp7%HQ#l?R5E5|X7*l643%cK}XVK!`bb5;wAz8^wCjbLtk?_LqAki_s95 z&7(2Oj0zbJTDt-Cb|YLIZ%-N{>H_O=`}Q32$HE4!R{Kb(& z{mXUE=BIeE3cQgJB31#r9zn$Qofd6jH;y5$=n|+V)bNc_XTXKrD0}Y+_w@76a?cb$ zm$ACGkhj#Khnh}hjU^LdQ9Wsd33?jXyWzBT!TV7O9a}&z>AJ8h*9@+dxS;fy6!yOU zD!hICNHPh7iKyhYxAvj(>PmDW5_s@Jq5-n*vw%A+87&Pa5`|*6n`jadssTxfx0qk` z@(sP0!Qv%djoQYo7wk4^kc!$WWV1vE&7*wL%f+yJ|0`gepL*cP*Mtr$RhGjs)oCbi zu2QOJb*OL=D)xBe62XuAtO3zt(bLecF_gK>Vn40y{71R=n8}oe5{|S)L1yWd>{1 zw-KjRpAui0uw)0MmfeK^&q(ggNJ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/JingOS.png b/root/opt/phpsysinfo/gfx/images/JingOS.png new file mode 100644 index 0000000000000000000000000000000000000000..22edebc8e86e9215b01b5a666a381a00e64c0840 GIT binary patch literal 1649 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 diff --git a/root/opt/phpsysinfo/gfx/images/LFS.png b/root/opt/phpsysinfo/gfx/images/LFS.png index 3796f48e6128987490cf7e6040319d8925ff92cb..a009ccb4f37cae58b04d69ab1b428d0170a7ea74 100644 GIT binary patch delta 864 zcmV-m1E2hn5$pz#8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600OH?L_t(oN2QcKZWKWfMja!E4t)efw|gt`epOs{kw@S=UCcc2ZC46o^H;c zoKM_5zxi(?ZGW&r=T%&YV}hLS>^|CH1iU*@GhA< z3?OI{0XBJ06TDjt=&%Zr15U;%P>(q4WST%Vpoj(206Cf?Zui0-#oaSk!Afg@XBK3i zXN7n*0Dsj$cFUy$-d#@yfS}z11>US~HxF+ww)nWZ7;!LHsOKk`GmvZ873?m+%y+A`o2 zEMP$o@I)x5L5>~sG?(spaz4eaw{r=FfQPe~q&Wl=Vp&|M!8F*jrs6vWG(kcZGCBW5 z6ItREuEiyr$bIy73_u<>(KupG0a!!rZmC}GPf3S@fF1kH&(#@Nq7Ci?0fch2r-(xv qJOoFHsKUpJLmNDXQ-%MqKKlh`G`w$k1s+uZ0000P9u93dWp5YW=XLNtiAg`mY%vC=XG z1W6%+jid?|VkN;s1RG0BD-EaLo7r%;`4d7O+|JFs-+b?zx5M4D_0hH9&v_yW!?nQ% z#wGbI7(53%&p#3wTE9MCWzQcb{q4#2=4j>De*f^x=kd+)&SdlFr_H13(aPmZhr9iE zZ{NInwD|k$;&eLQdTcw*JJW;Vc99$Vc{-&0SAAhNtg=Oa1to=3zu>1tMlgJFPk|*+PJ1R3kr@Ux% zh#3%D!0QaOm;jvi94mM&HrS9$2mp)1k!|aNOk|G9PZR=xOWwT6Cdo^ra;X@JKqB%$ z-Z)P!D}JegIj6HG7^gLJ(!@k0s4--;wK{KdFl=pVnJ7kX2o<8Oswy4Ab5&Ve+2bRl zh5(kGt}2mm0vcV(iNq?jiOE~zK}g{!Dd)I~WL!i*K>%!Z0K9jpl8=@44(&i>Km<9R zpOX~HfP(tNobatdclRU=>YB#L^$ zijK!0R%#RslxhwDQYbkyLc=6lZNhPWA!&dJ8HngZ!>C_Ng`AWcs?LCqn&ox30<}s= z9Wa+aOxQ>YxI6(T48{bpsFZxm9?&e5fP@JFoplQ0*sWaDQ6!8@Cebe)v8FXRg$P)e zTjxX|DKwU`WYG!Pj%v}B?kgmXdzIl1^!qM%$gYVL~;p%9xclFMb{|2a7PXGV_ diff --git a/root/opt/phpsysinfo/gfx/images/LXLE.png b/root/opt/phpsysinfo/gfx/images/LXLE.png new file mode 100644 index 0000000000000000000000000000000000000000..1e76f12604810a38219b099420593045b3e025ff GIT binary patch literal 1115 zcmV-h1f=_kP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81I$T8K~z{rt(W^(5*J1WSXIr zis?~NGt{sg1r&r7rL=sNie~x9-u_Tcc1}J!m3FEhsvkQ2A-5TFH`ZNj0Pi{9A2`gt zd}ij}xtCMr%PypBpI3NSj-!wj%+H=6WGjX{+I01tO2BKUC0f9+Ph7kJ{68iR@nAR6|e zygZ%4kxE}!2qAwvyk4J5dlHH10pz_@2ZCNy`O{4>0leQ`<-&a(*zT|aFDQ4xlVdeo zO%RKA!Tq@ycj%I|iLpLpvloF*P{QYv&(3qDFf|s$OaPMM=aXEQuNfQ7g&-8DL5l1) z@O66d%ctWq$idbF)YILHi%0_I@j7sjO$uMEO1>{JZKBgD^4jZ0Lez0ThfjbT4CKu*o*@zM?Qnq7iG zuUA$tYJ>Gh$|^X{o-B`IKk-S8LB#}+YQMfb;}&Nl$d6hPy6VYD!QM8sJg=-6W`H02 zk2qgv12$RApd;6z6UB^0%aZz$gT&dhCD7Vb1D9Lsj#Xp*g)}`v1e?vAT^Y7`YC-Pj$Joqd z1l81>QvuMc^pfXz^Hl<63_$z+(0~sPztXgWorhdYvl|;t206AQnt-=&l1WIiYye`B zD`^4d$qeXnmB}$BQ9n;(70gYAGapD;0KV=&Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81#?M6K~z{rtyfz}lv@=3$Gn#J677ayrHLda znqh?+96c#&iM^@Nn-EE4;RTO6ija~Jl@BI_O6r40k5{B3AR@e?AgMwu&`sWk>=}%BS((Jmz0$JS6^SR85$a*$B!Rd_l6DLj#s?}<$tgKw(#fulIqN0Mz%E|;WHhvFsz?77fH0a~w6E5Y}j+B%X zm7AMeVR(4>d|X@{@z>CvJ$r})B3D;e+OS~*vDp$;Dizt=+Y`^Bty{NJU|=9cMn=-n zqem$;G<2Tl6ecDns-V3pSis)N$*Bo~4h{|`j%=Z$qoW88n*0Iw{A^_$I&?_IhRr;* zDE6o1V466eR$d7g7ndUbu{e3X=(Rg~SkcYE=&Ytd{z ze*7ritqcT$j+c;-AWBRxXf1igwE+PEp326J8&gl7JV_rue2^|y2ZFeD>y~Itmc&8U zCGLWPD+LPQiod_Vy1&0)N*gdXHb%X@y@GvxeKa#OBj4ySH#bM8PMxwS?CtF>k{Dac zhZODKzh89F<#yb2)Jj%XR^#;aw3O9hbaa%sDbc=t`)Kdpy>#Hf0m{zKmTwI}U=~Cv zCnv`wkB~d@@$qJ*%q!EVT)A?k150X*^XJc-7=oyh<=gb`-8y?X%j;|$H&K|g$~#jE+-QkoF8Amew7vmAOJKsV_OckSGjlZ zUW2q*LR(v#*>Z)1gou4NhE}U3&SVoi%&V@hmKFx2r>BcmG`8csXjD2oJJr%=32=mM z*tTsOd3bmb-*o8y{rmE*0l$9z!kKUOWmtvM(o%Z<{JFTOWMpKRI0vy+9DrJ3!xX7! zf`x?zdiLy@sQKUZhpShwiXe@}S0jQ!3G?+X756;Psi`Tg)Uz5B6BD9JtT`jlMbpyK zv_U~Zp8U6>3=R(VNIk283c7joCItrvi)Gb2S&3LJz7tSmW23GW1AH1L&CkzEN$c_R z=TG8t7FV||Teg_(H;6pJbq)Oh=M8-Fa~-&GsQA=-DD`Xt8c$bO7iDH<(!qlVY5Vr= zAz$laD=V`C{VFOOcoevK3MA$&^rI&juUasydFX(0h^0k-4)`}cJF_HC-It)=qv za&d!hX=$O6krA4mokf#cICt)x>4iiOzW4uwm$+iF}Q+yD#pb2gGknYUE zy!{{r+062mdpnx^d%1@#N&B7IpsS%^MTGefw6N z3&zB=<#w3M)Us9)R#(ce9h|9Qd{zu_AoSwJ3(;EF!j~^!66Rp;nKNg?q@3-zaN)vV zckbM2A08goyn6LYTvnbweM(QBJQ2hg&+v}3T?1Rpk<-@?-057oT>oxrYAWP}y58O0 o-3nsd+}vD%cd(J>Yk;Es50xpCJiS2C_y7O^07*qoM6N<$f;NHm4FCWD literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Lakka.png b/root/opt/phpsysinfo/gfx/images/Lakka.png new file mode 100644 index 0000000000000000000000000000000000000000..7e7c18b695a58481a2beb2fe98a0d86cf385b5be GIT binary patch literal 1345 zcmV-H1-|-;P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1hPp)K~z{r<(7L)TV)u=zYUR1p@j}MQ5X~$ zl*@r)|IwIeX1v8s$Dm~5B?Y#*jR0#woMA$B>M)DR6cgjdWypkiS;x>wf@6SdxomCO zRxsc$SwJY)(F?;(m+|_Z?i5NnwB4+WiBIwi~{AQ|3Mmw>`KLkGs>}*dBw*r*@{DEN9C8xq4E` zL%Jj)8a}i<$E4(#*-UN0llXnC^5IQ`g(1QLc?^$fb7!KD5RLCYFD6^MQ;7C_5*g_) z@w$P{Sxs#*p5o4oein3HU&J5O7l(BW7V%#Ke0+EGSguIOGM$)ws7oPJ-C_c|jRg8X z_F^?$0EQeb4F-Kt7+?VW%OBSlhi-!dB2T8hbK&mO(AY$qTLL5#xLoK-?~dKn24k}y zjC`_sE&vl^peXbyroChJttbAt^Lnefg%kq4nM+~fM;|b?u^U^!Ym>+QVR#RJ&U`M! zrvtJe=P&2EBoc{+SLOv^xR`ez7@9eYnj2e~-P@br4xlv1Lwp&V#nqieqVWWV*aGxP zJizc37tAMp!DRb5e!;ayUockT?%xk(4KP#`c6vY_`RHw?YMHfi9!%~J1igG=06c-3QF)9vW3#yE@k7JiI0ZLm1K>MwahoTY z526{GSSYiDSvP;_4*f5{>2YLi9IIVSco#MhMejy(iw;0fL4W?TIdeyp zt$@+Jb5k(3JLKkgVMu9@E4#N!qcO;kE}>fXBBhlLi#l^bT)zoq2cL!`U&Mj2dSd?;yAElOk8?TW8O>9>_2+kG23mseGQgtv) zm)pDtc1)M~f$E!RcwC(g0<4SE=2?2sV2F~43pvie8Dg}u2udUU&01(hsFp&(i47K` zYb+sX^T~<;$ZUOOUfnEeS(8Y!%lY?0oHjQ;UM-!lZ$Kf57^1jw9rPVu4HK0CmLO&{ zAFo^q+L{Q+ZAzY3GY_>?C(`8kGd7D$*dPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1p-M#K~z{rrIuYx990;GhbFBil@?omTA;J2 z7u3jAH7#h%0)nZ9T|k?7(ZoBAmc&GR0}F94?VVnDVIn3*BFrp>g_fYE{jKp zZHOjDDYV%I_J^5emv+|on?17~&Yp$EzR8=}nK|b?-}%mW&a9M+TK%mB?h$uK+i=@q z_9(03N_ka6l{*Y|UlDusU}`zvQt0x#E+GKJHR4)E5HGM-8A=QucqXnm=3xW=K~u}i z*sK31*Ql!m;0ZWs89_wxyaliGQms--3|1V$% zItagO#Wn1Di8Yk~s);M|Z4S;X|ELd?9$-y#Q~OZ+ez)H}DT3R)(&BG@C80Q~6Nm zJ3P_oYuru!!r`zBel?j)J{;(+%m-kQ2a1eL%*IstF%wQ{L{)z)0A(1v;>xM0czxdgG=FQ23UD&fEEFy1uti2ZZS|J28{E7%}g0X058)R%T8~>qO;orTRv#rmETjAmCd56~L;jtRf- z>r&s!ehLBuo`E;b1mJWyned3yTNteKe8=F-p6F72kDGy+`n4mHq6Ij3%8EXX_oZHJ zLjc~w;8}wpIIizaPfu@;9PKI!Iz5-y!&Am{E!f~`Pr;RyLx9W);rD$*QnfP7iq3-5 zfUMfVWIH_CZWPh(>N#UO*je;1twhc3_Cs7ZaLp6G}&qO8M{yqqe3WeMY}2WY3YBv zbI*6~1)QsPv9UZ;)Sh+aSqv@`urN-Q%7 z{Xzy%00000NkvXXu0mjfu%VNV literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Linaro.png b/root/opt/phpsysinfo/gfx/images/Linaro.png index b076f7a3e4b02be8ed59d0b0d37ce84d69cdaaaf..244f4cd4ab6a1541aea7d10ed9ac68fb87fd9a6a 100644 GIT binary patch delta 953 zcmV;q14jJ$AkPPoB!2{FK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01m?d01m?e$8V@)00007bV*G`2jc?+ z76}mD&thEw000t`vPp-$GZbMo`7oVH&&N<%?=h<_f1CPh^S0Tet z@_PV;Edh#eNPmmi4K^m+JJu7XgLp6#wF(Z{To#AbK88ZHBf=ki><)o7#Hrm-K5--V zC5`gMCgPesFobJSe^dvv$aqu;^I$HFXGJG;;sR!@^KkiL*6M_QhrlLcOX=cmHW6dv zJCP6JL?K%4asjVIlSX_CBT+`u?L_A<0dXGb+^jEBFT+k1OK<@L#0V_}bv~N%v}in^3B!?) z3h;Tph$0UBae-ANOnt?v*-F%96~UzTh3`gb73!)xF)U#o#WY)Y!LNXY{Udz^rb{p; zFJD3265UuPvEs*f!ZY~ggHchMr7$SqDNM7 z+$I-TM*P$Vq`VJCK!vFGreRF_6_D6KtZoC!5qY^Ju*d`)P&+QdXbx1M@hK((7Wjhn z!|PBMu=Aiyjtgnk_fb4pk83?tIcMJjdr=Hif`1OC2C7&h6BTXANcJz_#2fa;RPc4l zGKxS1v@n`9sA<)pdW#%f5%iak(apBcmmU{V`|OC~>yl*@fe6ScLd#8dP${YPB*>8B z{}cFu#6xRPY1wP3=QxpewGaA%dng&QqI{qX4Q*7ZFZ&Ys4ppifF#;=Z=6pg@mmS%* zF@NN|;@n1MFIDQxz698LaAqAUqa?6|B+EFmMp27L-YeWLkReAdAjb_=9yKpm$dL0d2;@@pf`tq@ ztRR7X9qV@~7u<+Xrsf3;8E(Pu`Rpu+W-_-Rl^mY4-w%-Uf`kl12^oeGG7KeT7)r=6 bba?O+?s=x}2CyuM00000NkvXXu0mjf{A8T4 literal 4217 zcmeHK+iMh882_EQ>}0ap&1Q2UjY(Wh3vC0jB}zfthqSRZFDgYJe3QJCf~A&FD1oZ+ zq2NmkN*~lepeWSGLMbh@v=3FJh;%Da$RgTAqmgX0lij(UerMN7=eRo?bu0Vg2eap# z?{dE1`7UQ>Pwd_OUZStAx6qZ;5dWC;ddY9e zfqnMfA5L~b!6%F(!hUU63mm78jPviM6ln0MMxvYxV@~?+)-19rgQjtCQ*i0Hh7KhG zA0v<9T$r?y%{DP9r(otsHbRKfFHT}8orTx31aEM*R}^y;yX z&&x=+^&mmeB2!ZaK=~*sq5DYB!=p_kBL}L!46~E^k6JG_M)?ssYotQQt#8JRYnaOg z%-CQqxA#lDVWvUKySe^nw0zzDxmAdO$Dw21K`n;M|9Ptb9UT5`eDks|OK^{*SH zQsHyh6vL}xApxjwwZ7EEfD=OpMW+J5L#cS}yK`UcID}HznhME{-@{G8`(FX5w4I97 zT6a+QdDex)^PhkF)qEI0crL2Fsnm1;ktxWrO)WO;tqOQtgy>VGJFlYuCAx@o3o+*+ z2If~l7h{7I34jW9qYCeJ4yCMeuf5*m!2K`rFiM2Ly>D}*xUi%M; zCR{wh+JvJA^Qe(Nor*4))B%s`Mn>RK#W;#q3f7_pBPnEY*!StyjI3^Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81NuosK~z{r?UZXwQ)d{*Pg}WIEYMSW+H-kN zvrG*c%h*0_vQ1{#G}DR$r(s+UL$OaY|1u#bC0cfpZ%zzTIhPy6M|Zv&lXl-pUQre#Y=dcTxTwDY<*s`` zx_=t%6hv`i!oh#Y+!+yX!H5yp>qW_LrNt01lnBL#iZWHA$+vs)0=SNYg2jC}`q&2s zXGVx#Xh|r}VOcb1%|q{S-zL+b-@w%U9jH(n1_Iw66sq$9v^*$IIPnx-SCixw!-d3@ zunSBQuLl>wY`X>1LyIx7L0wYp++9l5(ufs7n*hbUF6JVUV`R-mIGl+8BTharzd=ra z-ON9f{xbB;2L6&4$8)3PyZI<0`?az1`C#QhwsOnod*9x;9VWxW5%f?gJ~!3cc@;Yw zn5QiM8LIk;kM4B#Add=KS2lXa;-P9w!RkDv-)_y@a zE@{bGm74PF)bzShFLhKMldYTU=%BWfeysmNVlB!*KtSJIqYcx~juT^w-1xlv6!_kn3x->mT*j?5WBen#H_O&^i}+BP zO=?$~r1lcCu>8Y(WMG^2f%!{o)a<($}P8Pjg2=h0Bi@I}P@ z3;wJqC}!fBb);4R6$e(0#iXmEk0(ib3HnXH=b6tgQp+3}&%oR(axOD(kvIzr3k%Et b1%mtrs$zFZMAhAM00000NkvXXu0mjfgzq)X literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Linux.png b/root/opt/phpsysinfo/gfx/images/Linux.png new file mode 100644 index 0000000000000000000000000000000000000000..77cd23f155aa08b3d028bbb45a3b97c2155cd507 GIT binary patch literal 1979 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Mabox.png b/root/opt/phpsysinfo/gfx/images/Mabox.png new file mode 100644 index 0000000000000000000000000000000000000000..604d9f053d1d83a7caae71138f01da818e09493b GIT binary patch literal 1426 zcmV;D1#S9?P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81p`S$K~z{r)mL3ilUEo%ZgRDYU2HR1vSf2v z+%RJ}?v{*QXf}GGMp&XV!y(d5oPQHtP{yAwq4G0Ppb(^xu2DTn@PiC*kY-tfJr@B2K@dC&RI`5^yWORQ8cFRDA9%6w~d zMZ#-*`03gD^3)ZKOkHC!7!B6C@s^erD*Q}y6J=v#$4pv1M6Ik+E$3y6v$yr@maHw` z8eLddntsxvZ!lPlcV)syITv)hz*MRTVjT)Eh$((%ZCOeTBivPOt~Ki|#;IVSwU*O# zZ+&i9M;_e2mJ2du)*jx*1ij9w35jdn^lE}RZ93a@G@wv+9V6dk$fj>?PXveo z@aD=L3dx$%PiSHNaUUrN#q-xyIROHIg$aIU*{^VbtIzA4iz!z{krl;jmNEhV_IjOk z`oTTLZMQmUR(lEEZq8DO0fP1eSU5n#JqyyLx^%j?TceN)d`$Sl#FYnp5eT_Baplh~ z-C0!Co=%SpRMEjdhUx6=ES;G7o$6iR(=S@H7l;YvAVtm=)vO};}*KQeDq1j(exK`v^7VZkAw!EJBh z^n^6HTWuH&mMlBkCzGLub=5iz01mLgy8w4asn;2^@ zcLbAtr!ny*PEQC6Ui@{^?MncmyeSdO9fFIQhY}#42dEVtfv`UB;KP;LgeXo=NKBau z7t%kX2x{dSqkWMGz-cJQsFktV-E*H)&l?+@5p6>f+9m)HMz-)ORN z+Ifq!Z+a#7YDJ@K>L$JH9asQ@j)W2bp|XHrx#$QkE9P@~{n`d_aoRv*1*_Rn{2Pk! zJs|Fc#Rxzx-X_di=V~5gV;^vu@WwvNqf#&BWSqU(`4@!XX!REW;9vr&%bvWkZY(?CD5>r74$KJwZDSYzW*-~{?6>E5+S4~i_TIXVUHvKD-`L{p g8{go=5gH-?0ZSwS^((dc6951J07*qoM6N<$g3?TpJ^%m! literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Mageia.png b/root/opt/phpsysinfo/gfx/images/Mageia.png index 0bfd1a862854d785d9919069e8cc17972381728a..c8855336f8f668d3c2b8c65d532676f265462747 100644 GIT binary patch literal 1911 zcmV--2Z;EIP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd2IxsdK~z{rwN`0NR96)KKoCjmQmsH-RGETh&RR;`(cRs&Q)Mbo5d6Qi|F8k^J~ z?H{A5jaHdqh9>l!I}C-HhtxDq^38kqynE02?m6e4bJ5e&^TvQq=ZvBvcVv7y32B}q zlsdRT2WRx?oawWZ+?v54D;x?iNW+kMB?np8&Omc5Q>nBP&@l-jC%0xW$O>Nv`Z+-& z0-75Kk=@aZ%xe|U_`4$S+(*d2Fc&H>H=5(j^W@gsLsmEx=+6lmS0*95bvZOm6H#dR z5ScCKiOdCLw5$*W-zEWu)$KmR$(TFT&A!NPzlNL}SE0R8@YV^ia_rZSCc|5h)m(%0 z)(A4Z1X&$gY}Ac;YXoSv6Dthpccg zh@(a)KpZ>mWl!X^H&Y_EA>&ptH2U|k?py#?ADu$RhuetC>FEzy;b5SjGyLI-w5A}e zx)cF*hZl0&<{|&=D5QT~P2M<*w5z9(eevVIV@U}sr^^Oep&VG5*m=fPHPo%=puYYE z(wlcdLvBw$Js#O@EtH6tk#qA3vTr2_OC1~5u zBk$5U;g#H*mC$tDK+c_W&>AKa0T&6hZivb#E3|?BoH{tU_{aqx^hRuhFVyWB(A>Tb z?VUDyR%kSEm6)I^-;MHMB39>*LgaxN2(Fn872I?~6eU@q4ZIK%o%OH-8?fZWGc41; zK*ZrHtZ!OOAqYoF^*bQrf&hDHUfLLh9o~$k`X@-#KSyM31w7M6h};>3goA*g>!Ab! zH5{eR1tGO-N#URP^rQ(Z2q`CDL3R8gB5P_8UcCZAI~BC!6etc=Any1NNTu)638O&r z$-fX*RSNRbU?c_%`h+x5BwXO8S%^RO7^(VBq%;s3jYw^LB}hp6E-b4vBC(+hOY1sG zPN;u{WSW~q&y;$aPwxrG$P-l&gB7O%0~cLd3ob#2oq! ziARlALWI-?@(LMDr8&#$O^7@A1fl!)A-?KIB-8h#`j?2QzKx<9clNBktpNiYL`?m* z%|cwwGb9}`V(}3Z7V1(&oMZNnhA+JL7y-rL3jwA+B4 z!HBOR@<+RnQ2PS&_eIGa%K?KvAu9;nQHZ67I|ZWlK0q)v9rg?-CdX4l9^y7E(ZvLO zQj{)wJ;jQ0At^)1t}|FtWkN!=5rI3)=@uel z*bA<5F8nUSWgw6BCYg|N0&~p>*pUs@0h7=ZzUL;UNbU}{>;*!oq@xq2yA2gBjM;01 z-_V@{`0=c1gx}1#2^MLAWj!i}o3jKzbDA_vlED>2F8qvKI&;RBll0 z_y+NNO^B{AVs^)E($<&`AeZEbjL%?(N1ufYcF8%;k9~{{oDbAJ|P>MQ&fjV6q5Y$&$;6LR|3?xo&DJZzQtu&wA+mMatm#uiSLUJbL|B}$VuguwF1gABVu+Efs)4v z(N16z*4@3P%kia!Z_SE~k?=46Nvw}9>w-^iDHkLA`2z+v7?^->q6Y$sen<3nGos2Y zn2}j2x*L(;?kKm8JtUx`5EFcmfo=oytHu$*!UDtTZsHtGiGEp3h&WT?Qch{u@?v- zyP0eEsJOB4$@-26SP0!%Snv!Vtto+rhvx~Cd#v@vT+J^CFR~E25mI2ntjznEPTu(>DS8A#r(^o6P|RFg z1aI}X;(KT@d9An`ez}j~Aw}^C61v`$0J}`YeQcx;W~ARoNTG!cm=Q+LAbKv$vtYiq z69HNag7Ym<6q=#fU_oeMH)f~*3Xh~{?y8IqQ8^v&hXV%opg)RfkCR|OKH&q(fkW^~ ze~RD@W`wZ8yl#Z%{Y~%W86p#sV}_slIi@Z@jnT2wm^_~vQbiS#cmIYSu%S1(xa3ku zq-pR-F2Kx{Ut!j|dqn7G_^y8d?={Vsl)4q;V!gR3@kwG2S_#POWylKUAV^TB6A4FU xS>lcf>0My)dqCny9W1u literal 3065 zcmai0Yiv}<89j6F-M#DG_40M(l|ZumOe`K+xzFMo^CD}Q8D_1%rzo(Dpw zWEH;%hZX{X#HI~vAKyDD4h6oE6^`R@-P}dQ;|ekv9ho(CuzxrnX&o|?fQ?QA4h(Ld z8$g*G_LG?vDS@fTGf?aH!~3i4AhIk*+<=H1V&>oMzjp)|EJ$#p61WSBUQc@$CzrJe z-28QmF?M7n`VV`!L~+;6g8%<%0R+C;+XRp2K{)x-sIokm4(tb11-5kzQ-_Wsk+4bc z|L}W9%cU`r)X2rhM$ojU7ZXR)$ofN2z4h>Det7i-vlv_%(ki_(z>5XSF;Y z7fQr{lDypeG=#Pee$|FOeI91-%g8@a3$MC@SS5G@)v$wi6W9fp&gXcge9F1Yuuu{) zp&E!N$>Da=p|7SgbZ8;~-Fpu_8$&p^BMntO3x^az%R-EPKr|&v-$*xAklCrw!cp<( zq)^w!Ia+*mDXIe+T9&SX>UjbT6WGps?TEZMF#$V~-Oags>oNV$X$&uFLc!xj?e_AG!V!VvtwB`Z z_bh6wen36xn9BVemp<5sp+hAuaSsqoJqm;YBf_>+vkeXYpTVzGx$K#+kS|_Ep>zV4 z^&U!-*H9IlkCJvDg8CNLrBIw1YE5BcbmAo}f8hYSxsL}(js%^jCf|O38R}Y3BH#_d zRg|QV*~C#9>9&TF$-bg+&Z0xP&30g`0*>XH$3>tKW#sdZVcz?vWJ*w|QIY(8mw>l! zFMLXn`2xrmuVZZDRb-~eC^rQb2UW#^hxhRaDuQx0iI$tnVs!E~aAoQrJRpmLm8Sc1n9dDieDXA= zOTWa8%yamA>ICXTXPIlZbH9f~G$K_zoxFZ>h_pmieCZ3{#^>hk<6XhcA0mJD0X&>2 z!f=@vXz${kyMc*^G$am`5s9E{TT*m9Aie6j0a`U9oXzhE4c`gaSl9U3RS4|KA|=t&ueZskMQvqBin-41-( zC79C5oU`mYXaQY8@&*S?6^_XbtfrMmYM0#VmRpC&wv%3yEf*4Hrh{0_9)5(nDreHL zOBS(6d)beW&#QzHl#2_lN(7~;VP52B%uNQj4!BdxTZ!&JL>!bo3uv`QB`GLc87iru zq#_BM(KSdzsB2b_^I)>kz4V+(1*N@;TQ|XZ#d^h@#%Z(CT zFr*tWW_~BiSKmlM^swHJDgV###;Jj@z{T=bg!E-h5kS6_rJQ@C{A^GX1ZmsdJC5-q4VJc6URUd z;^Thix^v?xc=Yw~`xa7~Ug+!(O_YX?+&GKP(-y+KK{zVHiI{RP{oNW#>gm$f?P#oi z4SubbX-XiSy^8eZ9cWpVO%4n=m3$uKBawLbspVKubrdy$&&!)rmL}4WL;~}fo>?c zX3|nJ8jbR)OKxt2uVxPe;VFayHIj9gPr1UDpo}3|^QAmSGsiGF`C>Hl&gHNHr<0LJ z7+1>_{Y>F%2Ax!a4B!(Z9DM=vqpxE${V3}7br9agw9>~z%B1TGCiACIoI2jM@0|;E z{QjlyxLcN6<`V1E?#z_@mC9gJq6`fYW2TCdK#Hmg$dM1#j6%1oZIx3EgO!ld*;Xg0h{qTa{vGU diff --git a/root/opt/phpsysinfo/gfx/images/Makulu.png b/root/opt/phpsysinfo/gfx/images/Makulu.png new file mode 100644 index 0000000000000000000000000000000000000000..d197c3531397d43500a02c79e437ece1908a127e GIT binary patch literal 2182 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 IM6N<$f~*Y*7ytkO literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Mandrake.png b/root/opt/phpsysinfo/gfx/images/Mandrake.png index 09ccd20aaefeaec1f47f83a9360f3afbf5388e39..f93e148e3f37916c4b1aa223ceae98a1fd276524 100644 GIT binary patch delta 671 zcmV;Q0$}~a1FHp)7=H)`0001UdV2H#0004VQb$4nuFf3k00004XF*Lt006O%3;baP z00009a7bBm000id000id0mpBsWB>pF7<5HgbW?9;ba!ELWdLwtX>N2bZe?^JG%heM zI2$xh*Z=?m97#k$R9HvFm9bF+F%U&f<^o&+2|Z8&RZsyjGk=so8#F+`cp#tzXQTuq zKtSMt027J*yIS2!-jh!UBZ7A)t#tZ-SF*eaA^aQ#1@y%PbyJpBP(*E83{w&T`8oDX-5@qe4vXAxvymfwO8r3y9C5}jM0 z&jN=GfZ;s&3ymY^0#%esu4IcaM(c8RQw%U%x~UbAi%EsCK5I}sZ3V5#nY9_%7s`>c zt2owW!MFyW2lJk8Al~=>VYGe8yc8ZI85sK&BvST=wqPlH?XBT3%>ey`BzqN?GUup) zMVkS=gnz*34QBS<9xNp{(RLm4Lk+l9z>QW2>;3|?5o6J4q}c$3)r6i-1*L}o-a4k+ zW>2(Kf<93L{D+l`dGNz-1Au@|z?hz9dtOvr!5lTwYyj9QsE9@5V$MG+S_v2^4UUm@ zG{X`Ys0mxt#4G~?5Ssp<{u|t2PuyTn++a`KU>HBb;s+KU%8m91I`{wp002ovPDHLk FV1mo_9LWFx delta 437 zcmZ3@dYE~FL_G^L0|P^2NcwRgWf0&K;;Lj-xua7(u59!6J!d{IVtlaPO>_45U54xZdq#wjEG~fTxRNh{pNkAN_0+8iGH1^(F-MYkg2xkyra5 zyC|76=77wZ6SIW)MStY{|7II-{M<}~#zo)V!}3qp?#)_iAL8)ye|rDS)nR9&Ua|}R zIQIX4{fSk63ocyw{Qv*D`12n;fv!5VF4UoM>gsK=@q6bzY_`3SbUt!*Lqfe;2MhNf z^GH^004R>004l5008;`004mK z004C`008P>0026e000+ooVrmw00009a7bBm000id000id0mpBsWB>pF2XskIMF-;p z0~QGo-OplO0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE`KmCI2$xh*Z=?m5lKWr zR9HvtmrZEYKp2K!5d^pGLSa#96_sv(V7o~sTPR)yJr*yeRTPg3Uc3w9&AT`8X3HYe znTe%P5d|;e!T!)61O6=3N?p*_g9i_u*0))#8PtMZ(n=f1L-;c9_svU^$u~i*R@+u? zg*Xt8twAWa0DmpML;EW{|1001MBl(TTA;luYmnHu@jpVlUm%aRTXR~0EaWME4cnChNHNZ{#PDO@F|EKgX|F5NXDG?m+iWK^LCe z^e#f?N{u~&aUSD5Fq+Ro9~**h8?aDq z=O7QAi8R{1O9Km5@j8vK0v`Khh~{b)nK;wr{ydtZgd`1M#ObE+GrQRGdGRTx)n&HCoXTY>D_ z1&F1dR$EC1PECQkuf+4LSh!W9jf{Lj`NFn|MHj+X_w9qoPVr3!t zQ3#^g+Q-V1NK_=49Jz!fUNm>f?u>8tyzIRVo-21I%?-@XzBljVHy>~2&E0dOXSy@{ zGXT1CXGbn@+iz>iW5H@%l&V&wg2kF=j{W&G+!?eUc?=g`N!$g47g1 zMIhqW`v21QvC4_jj(5{9{NZUpvAEG&Iz$8$q!26(nX%b#HNIQ>30v(~;CS;Ovmp4% zh%y4d(zzEt3VNOgVMh=FFornN~FwPzp`9pl_Zm7=W z_I~?Hs^CDYCD7Mexh>`$&<-#Rs7^segi@R(Cc$BD_41)*M&~Nqu2hAkY`Bqks9zZ?+Y1Lg8sREZ^VS+ zqyS(p&6J+x@$z_I-5Jgrb6oR9cKaWS06>q14kP2d<@H_QDUKW(bnpN_T^>TN)ffZ- zq?NtBc>2lK2mtX72Nm0Nt$`wsV!dhC(C}n)Ywz-{TFqKo<5O6X07Tc$5N!Z*26XD5 zn z4nv!G+8Pyt$I+1r8P$H97nUOd{v*mlb-Al0n>ndoX7E)~_cpYbn;}kSJdwyq0DgJ} zYU2SEt;vkQILuoL9r}w8+0knlUnV5vboO*im9DI!{Ki?n0psxnrlW(66u%997ioTy g*A?+PuH*06@6pfuj+AcSxo;ijPLGZ}KQ(^q7mK1QCjbBd diff --git a/root/opt/phpsysinfo/gfx/images/Mer.png b/root/opt/phpsysinfo/gfx/images/Mer.png index 90489649cb087ed69f38c25e136ab949690fbbe1..2eeb38e36b1c1beb2fdbe92ee5f89f27c0925d9c 100644 GIT binary patch delta 1355 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 diff --git a/root/opt/phpsysinfo/gfx/images/Milis.png b/root/opt/phpsysinfo/gfx/images/Milis.png new file mode 100644 index 0000000000000000000000000000000000000000..2ee4e8b86154f8ffc3f3e33afc881756804a12fc GIT binary patch literal 1391 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�ZdMj_)S!HbCc-R2wtTO)XYFZvmsv5vw|SY_>Z(^g)7{lQ z6-gl?)nEhI0ZxId;Eo~hY3l?}gViQ%|A1H>*adEaNkQLku+GSo4+K|%x4~av0bAQy zSzJrYi(o{C-hbT(ALu=8Y;&*;QlrYqCIbR$!C6p|!*BM>l(bJa%jKbCa$(?*muzdF zY=ZBkaC{q%v>;Sh@-B?`5q{2yU5r4UX8SMNQ9XRkIIPghWbQz|WW>h3t zT`1Um`-9KM7{*c~vXRa*>|h6q79y5biiBY(t^A)0^rMTtUS=kIX zROrXg?=q0;mEPBPN|HYGWej7fVQVsnLB155{lL2!kq@WuK`j3?a~ zKY!eg_3)YBj*rFy@4mV&?^otMN&KWQV{8p>$J91puK39ahBj>iq63M`tHURxW&E5@ zI3L+YA7AWPrq8G=;s+7}#!7HTn}L6MB%_uE9?2?A+BnbLCRHRiE}#r{7|T|kT#^Axz(=Q&Gz!q4-H Zir)-4fRVtL2A2Q;002ovPDHLkV1g`a*M*x0y{W7{6Mx~{9LS}Ydfx?CU@*w-1P)W7P{?F5uq8>V zED>-BljYde*nbyFAp^*(g4A=Du3*+w7EST5Z8>F*D&#y&R; z=J)$WQPebzGeOr2S<10;o~cEql?|qGgKe)r+x`At?|(6_4lqN%w(|Yh^0%evO`7E{9=}bBa`8ISVG{=jTDGh)r%m zfniiMW>~54WY-%V$`PGutECuvyZsM$D!m|pi;xF)4Lsg9gy2|i3NIlIwnW&3s4yfQ z^}9a9_}6AI4Mk|$=kJGiW#;1xw_o{f@sdUTbAR;HOOaQH7runs69@@JF6b$+V%|=Y z>0MNME2CQkaJ^z9svh2SVyvX*XOiP)7@JLBE3?9EW&$oxMW5JGwcF{IrDs%3i_eZU zbHFj3SuRW~yt4GFbA@hs+TiIh+#BK0J26{9*rK0ULu^#cU@+}z)F!Dd5phN|sui5A8mW0+1*tU%4yk}fjPT4-#+hgbAKJ#0$Z&m5jGvJPaGo;1|JRo^XvHB5B=?@ z8r&_fJ@Q#Jd8@1!Fz|eOO6N4gR?rZ5X_wUI;$<+-=Ke%+)FQwkg`?c(^Yt{J=nNc+ zCZ@g%pLwD09Ytz96g*i;zbUi>d&lL*W2MP$l1wRu^!a=qhsSeA-o7~T=FGp>&wr1; zba?k;t-b?44YfpeE{eKea0 zPt5(u5o<`Jl4p+E9E93EYDpJdG$3_Q!ZS|WoB)f!==hew<<}&4zTE#wBtCj`;g`kq zbWzVSL$#R5#&#`*VynDA)Oxzc3S{h5qXmbeDA4L~a1g(;o-gY~OPp#D`^ght7W|lg z4FZRQ5Q0ks`EZ*Mc(*9Zb$-IE-?jvoPK{`00+*ljPTfE-t{s!0ZtUO-^Z);K{U7H( V>%`9)TvY%7002ovPDHLkV1f*?T}%J~ diff --git a/root/opt/phpsysinfo/gfx/images/NeoKylin.png b/root/opt/phpsysinfo/gfx/images/NeoKylin.png new file mode 100644 index 0000000000000000000000000000000000000000..3fcf5306074946bcbf4cfe2cd4ad402699f048b3 GIT binary patch literal 2207 zcmV;Q2w?Y#P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n82oOm`K~z{r?U#E{RQDCf!D!6bYIq2{m;2ZU z`(T9yWZ5oZVL=|tLv(|vC^{$x5XF@WiVqB^u~H)%tsTt-rb)FkNz51%TPLRNwAyI| zZQ?Hbyt@m#?1O#qa(#?ZBA#Bz9UUie8Z);2C!d+~$35qF?)Thte!qL?hWuDYKio3g zxlK6D)3hqDuTZ{}cK>gCk_V;Mvxh!Sjd0y)6r7 z-1tN7T3`F}9^2YdQo|Dn=q1k&*G3-USSbvrFGFsAxJRf|Gj2Xdm_0_?TwwMDQwL|{HHLHhD6txV!m3lmIDE5-SgZI#(#zB`x z3~B^CE}i!L@Tk-H-koJ&$>7{J#9>ZHr8GG5PN`$0OZj2onAq%X=Yg%70K?+AiGhPv zzZ*W=F@sKhKA0uK7mYmbc1Tp&e?Rtzu#fs=xGOs$8G2V4n;@+tzpND`UJO*@;DCnXw zFr>smf1S!{EiEah(|!>C_Uwq@N85knZ?6s-6XU&_2n?k|PtupgC~(y!UGg-_pihB; zF@h40KtazWTm~kmUKft;BNeH4UAs4YOs70zV0H8?s_4kR96XX_N4-S5L;MG_!-Jo; z{?osA#X|#!^AAk~DyKu=#aV$b8R=R-;c3nQiwFfn7}a_No6xh^OARk0ou)ZRyphZ6 zcD2-6=#-Gb%?R$_lio3QdaEgT_RZU4r}p0pwEwc#UA?r$o+k_&>8jd3+F1=`9DdHZ zt!k%xPu&>E5&PAT9YM-W@p?gXi18St$eaYy^x^D40`uU?f;a94jR22e%b|;ohX`7+A@X z1P)|P~UPb?E`awhaC2{4H<=*6(}IwrnfhjUI3 zY^&^`B_HEyO9=C|=KX2({Vm{FmONE}nc9GsWG?gk9B{#-S zy#_;v^TD}}4;C2$dOiwT6ay`Sfi4CI!({Q%2$&FRj2y}*Vo&H3`1dSJ6ngK;9Xwk0 zTLNuS(}p_B&U$xdzCCpOHL$NtoEpJo5hR9!Et3z<+6?f%UJOG=${_G&5qO%C!Cs01 z`3eF$N?e0cPbuV#8*`E_S<2Hd^sQ3dB@=~HV>C+Rz>p@YwpQmT`x_R{p=GIac}N;I z`u@7ykyBO2+-(ad3`wzSSJU!4{VSwkiNnGCGF1d+BpL&@6gKqd3&CC@pxTOqHH!(P zoDvsM;%pqWBF+H0P@XxsTU|U*Q=#IeQ-W;Dr~=GG#bDa}${ujSkerv+S>m{;r=FJ3*Faw9&WzE(S#^!&Igi>1Gn2TwxMy+8yF)%rx}n zbEkH7ZyXy8auFDFlfYCYeP}LD^Xp~FA6$>ZWRq+C#}@Mj4=(C-u9NpzCHQ^&V#Z~A z5yNfbqqhvHqUNhC*0iacejit2&}o_+$%P(*-P(=dQ{VZ4HFIbB52)^%6hgSp#BOOK zF{K7!6=@J6j}jG8uhX!vB3Pl5YyHQwXAPfHU(jdAjrJyqR$CWI%vKq7Is^z<%N7L2 zF8-c1x$dc4WpQ4-DvnpWcI|pprAIATlPYmJsggDQi^pl|VG?!Mn8eTM@FP51vMQ~MGrrcM z#C{En@$?SZOQJ#@Wqib0BVOa)EO(L_;&JU<>_`7_3{)^@x$5GZ`->9qX`}JawGrq{ zI`sY67es}+sudY7b+MYvOWCN6#A>zSC{Bl;3A-wm*-0oa-uwwuK002ovPDHLkV1hQTHTnPm literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Neptune.png b/root/opt/phpsysinfo/gfx/images/Neptune.png new file mode 100644 index 0000000000000000000000000000000000000000..798cd332a7b4b1c0b2b7069e9201e411a02b826c GIT binary patch literal 1157 zcmV;01bX|4P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81NKQoK~z{r?N-}T+ei@gr|Hw?3$oc17vsAu zOSbN|?v{lIUxW-cAqfy*Ltr;c*d+TAy**l|5(u#^^O{pNW!Fg4-RI1i*5rO+RlGTi zInxlyXy`x`8sPf|c%Gh)z}H~6XF@Xez_Ar_`F_UDmpvVrj8N);-EM*1ks%B_FiCna z+3(V@+a_!zaX^#(5V}DdEK5$uXz0Qy4#+%Ab|5pZ7q-)+yOD*#P4dUvWGS=j>tm86 zA?39{Fptpi!Int_qgfgqO#AbUwWpcBe^M<-TXo zFaMrCc`rZQopH7$(++Oopx;?sM9)?5#U_jf&T7>nF0Q6rADOcMpTC@N1{!s^=lq}= zdMAyYjQz)B52-`iC{;gNQso2e^{rImICk+@1kX{ywvtlxtrR$5hH{>h1AiLj$vm+hAz*rLJb(jx9vv zrXvW{wN8R(OCU>?Z(C^^0u_V;titFZ_Bj#XWhyXV%%@kz<;6Y``5lNN^IP%LNf%Yf zgW4=FWi&|~B47X+{c!Ux`_-#b+(^k@oIM~LxH7F(x8dlp_tPRyFOrl!OWxmgGAEBh zmGads7!TdYbF@tXD&LnI`Wb!KJsX^LK|FzD&!d4UqUeJ)TCH*?vXOmpRKoLWSR03n=8D zLm3mX!Ty&}tvbIAt|fxr;>qo&^QR~N8Q5N4Ud_nqt06giJt8;PQ^Ib<^T)rC0lD0N X7Z)PZUdPmI00000NkvXXu0mjfmkS}_ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/NetBSD.png b/root/opt/phpsysinfo/gfx/images/NetBSD.png index d3ea3349912e4fc8f726982304531d94f4daa184..ebcc33ff5d0aa7a1cda4b3812ee70233b2942df2 100644 GIT binary patch delta 1580 zcmV+{2GjYY6|fAD7k?lK1^@s6b9#F800001b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^ z1poj532;bRa{vGi!vFvd!vV){sAK>D05Nn$Sad^gZEa<4bO1wgWnpw>WFU8GbZ8({ zXk{QrNlj27W^ZyJL}_z$a&K2*bYo~PV{dJ;v2C*e000SYk%%uM?cz?IAt!!uSKI@My5aN$vviM1E`tE)A-t&Fuo^x(_&-h;f@f-QLakr3h zR#HjTM{dTl2N?Ayz|?O8rez;6#v*&Vr?NO14HRUTEY5G^S45eq>xJ3wq7b8uM=HY9 zr+)glV1_>M63}100QCNqkW_sPN&QZAdvpL{#YR5X?SJIjpTCbwv&$F9(bklhRc;1c zwN`y+<*P-h&SNO$ zm7{d8q&O4x2(#NSO|Q2Xjrp5_7Tw=`$+quBpi9>PeP|WXU$5ZSCad0ol=Um1tKUMj zdMnC|cz+@gkK|^}EKW2U6__l>%$#ZW!p0VB#PBge0-JaB&qqC?>~@ca%iZlC_O=3j zFng{`w4~%+z_$H05JY*|Egp}XH*X3wS}O5}q3Gv@403JXN}wy(Cz7p)D2Vu$cJ0H` zY-_d$eO*7&;y3RbC2>*q8YJtt#%>Qb*1)g9Cx7$B3*qQ>2`^f#*jD>eZW)J5(JV2jm^LMfkV&{ES@tM&OFPfwxr%qb`rp9B*!-Xg~SEr4J! z=|NsAgL?wVAoD$v(Iu-OY4{u%&1XO#;Ip^b{z)t?jHI0vFIPM)v#TAk9>9J5=j=LzF45s=w|jlPGV+zafLBIo>M=QU zwzS*XKt+0^4x5mPB7w@ox~=?#f0ssI2kNszb00009a7bBm000XT z000XT0n*)m`~Uy|33hNnX8-^IAOHXW832iX5hnlu3Jys`K~z}7&DRT16h|5W;6+gp zqw?0MF$suZt}vmZiKR(6O+~$!L=uApTu>2|hXxIt4-f^65*0xNQ7{6lBA~p2AW=~S z5fRM_@>E^|${S&4_A$FV(|z;LjAl*6I&)Q5mHrB9wx_qJ|L*CTe?|CZh0!_QhHG&% zmI?L6I1$&Par7`QXEtbu*#B#_UHCTh6K#dtQ4&+H(+7|11DCKmq6wO5!UD>`NwAENtE& zSsbEI`MLcn63OgWhmLxi7%7ey%_j842Svt&k(-66kN9Zy6nzsSW}V2;j*xBeG#*dR z^r#@wxg8bTV(IjKi#^<3~H)-v2*{pz^>a)m{A`QHKP0~n1@9id6NjqP2^G}J| z^%Ew@Wg4-CNJPHpJKNlk5}(}@(9WoP=07YKuB*by*oPZjKYryRdg&P@Kr!eP67I!w zdoF}sGH-q-dsobL^&GD?hUUa%-v|o{ImKtWnGyMhkJ!wTwDoB+>mlFt2{QYd$n^a1 zHBpr`fzp?^@coxdV1Ncpp!ruEAapdy_&A>bG18jgIPℑN$0CmjL+nyNm^!C zOuPIcs!yA@xl6G=CSb*B<-IryXAw0&ebiPjt)X;6o&!3hR1$NZ&vXJ_i|;ahbTL*S zIda0W_zccL+2}mVKw6|h8ur>?1;?KA4re{5g~OM4jwcYkuqeHF1PauBNU^H`8#)5* zMZ&YZrlZF0euZTA>HO63d<{xKu4n;!-x65yhc#5QeeuN~&qoij5f&jDuVaU^0lVPu zSbQ1c+~WwHa#S3?Vwe*IxHV$Li-{#hNhHmay#O_tY)a=Y0luC!A}Oddq?+< z?=_}((;;-QZgeV7(6kM7#{+dbkX3`>1kkMyh716n$oYMHV)8v8(u5W7J294sUuSB# zL~WdXE3{g;f|+8*Q>4s`9pfaXrk}p+FG20>b4hqVJZNq#ZPb^B-BsTmt23%)y|z87 zo(JJk;fdjrlWiwkPBvY401-0q_%$GN0>|1xjSQr8gYtBc=m;YGK~*Uz@Bv42!J{Lf zAsv(+2O_k%|K_753Wso;1%|}xH3{Q_WK5)I z-EX|~FJ@Kys;aSSs&ILfxz@FQY4PXkx-#2SkI16U2Y^!PxMcRBVuMG z`y{`f)Kl*c_7;Hd5YRFRyqAHvw?Wq%fFG!&4n$uDx&g=$_+cg}ECa$*h}qQMP<36M zd(kFx2VbR_7uNW3nmj%D>p9Cb9XFmxOsG>CJGcKTXLei8Me3EmbniU3CdeRN)!kh1(f#yzv*Ky07)7UhS&o{ zn(*TI6PDEN^HIUKn8;4+`_dO4<+V3FC6k!U$N6;&H8)CAlLr;(K-<#e?B4K8r_fU} za6qiwnSj>ZWTG$U#;j-$Zp&&tobQl-ufV2YZhl{WQHd+KP5||1p!p+^;{vYi19!4P zuOBGP1-~f4^-ZAUeNgKTgkgnqI>C#n1Y%!3O5wO04IoGMb0LmmUr_tlUkD7Fv$Vd@ zo@QS&q;PzOm8w+(p+>>sQWBwNE9W>z_k|_rL~(vkCm7xASZLl0a4JVgC0bAb6U)Bj zvuSs>lW@G?g&{sfUoy^YqG5&7*k57#^b;&)Zqj>jGg{B=V(Xodiox1`%_+Wl-j8|T z=6#SjDbX@m-Z1$-d>`@${0000cdQ@0+Q*UN;cVTj6004N}a}V%QaL>puE-6kf$}A{R du+TF!1pr5D28z`2Hdz1w002ovPDHLkV1ktRB%A;M diff --git a/root/opt/phpsysinfo/gfx/images/NethServer.png b/root/opt/phpsysinfo/gfx/images/NethServer.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5aad3d9b0aaa516553db2f6bbada1cc0fb826a GIT binary patch literal 1019 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n818hk|K~z{r#g|)1R8bU$^}Q(SG3eq2qC)Kg z8NP^AR$vqa)nkDKJw){sJ!KNqLsTzOd95tW(1fD2vNF181X*5Z9L>vk*Ku^3884%& zf9=_4JagvEoXH$!!S`_1+H0@1_g;IQb7I1g#KPuSunHUpcfdC=4oETv>cDMq1gr$H z(*6Gg6Kw@WU;-!sjo{?&g3WT8e-}8f2E1A)&?)LAa?Tz#T4VlgX;EkZIISS{ZZA(uEIJiZ56gd!=qb*rq-6^wMId?GIc1 z=F%_-mT>|{RZ2g0J!&Hx0+r_bkqU&wFo~x9Ikx_>MjAq+}$Z-jxt^asqk=kwBkg zMkH`4%mi}34iFw`a@s@heoxQ=B`c+lbT&8&pDs^eCOS1bJH6%o_ec;+_Di_Y*V6*tNk>HMx@({`HcB4pMKjz z89@q(xAqL|&FB|@P<$R_!yR(~iI-#RcWU~B245>Sd>Ms;cVc5vGo_;@GI8y8<96^n zAg;i$4|rcjEO-d(b-aWuyp9!tB6=SrEKo-GlZ*w1=zWwbf&tO{ELQ{rqxWN?2pppK pYo-=BN9X5MEtn`mzvnSAe*tNm{xlx-+FJks002ovPDHLkV1g4U%`E@` literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Netrunner.png b/root/opt/phpsysinfo/gfx/images/Netrunner.png index 7616118654703486446357954f14676f0aa27649..7813e272ef24ba792bb795663283664ef826760b 100644 GIT binary patch delta 2820 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 KZ_fSspZ*IV>l&c| diff --git a/root/opt/phpsysinfo/gfx/images/NexentaStor.png b/root/opt/phpsysinfo/gfx/images/NexentaStor.png new file mode 100644 index 0000000000000000000000000000000000000000..9aca266d184c8a811c3d5af11938c0b32c217a4b GIT binary patch literal 1451 zcmV;c1yuTpP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1sq94K~z{ry;qA<6K4?TPeY}(TH0z`>$KC3 zo!SvFDio-ofE*~afCaTf!Ga11C{-w+JT9+~B!nc8Cm}#e(tzR7NFAobAF$p1xP(i% zBnX}UW_B{U+x>RGeP2c@Y;G@Qde$cx{YsA%5#I6&zKBH#ZO#bkc=wH&@R;z@-v-WA zkx7qYKt-A6l_6nZu^C#OxwjPkjwgI`J9gidk@B{0LkSk3gPyloS2W!{?&xX=sIV-Cl<$nH!R!A0@ieN&uFk<*Dk(}%S)kG!hZg%aAn!@X?L~OYmD%C0;qD{B4o@}66G|8Cg^L;` z1^Xivp4;NMmfREOgvRObxM$>tzAar=pMV~39c*lQpup%ELR+bA@of6o_!L>Tx~iBo(;xx zfGqxbrufhvh!R!Dio8S(q2J(ALVOD}CqWE!#=@Wubg+Ewi8!95q&|k{y$7Z2Qz&6) zAYYRWdFpp!@2Ny>tE0PKc<8Ri7xA~t6^}t3R)P<+pLnR2hp{gdXtQ~(NBOA-(EkGM z2T+Axd*r?ersaN^dNs^!;TM8srC)HZsbOHD87hol@MI)UKAmgaxm;x1FErW;_(5_5 zh^Qjkoi{LZH9Qx{h!Ot-*6tGE2KI^yRO;i<=B|nv5rscu7F-(!VNXUQme6aISGJXrJ?~ASCz-AG z3aG}`O=qO^K$NI_+A&OtMkInfG_-ghsErruKZNTOXW_B89{jJ(aalhfF)-3;MkD#e zyK5^-X#f#SZ0T(hIc)AKB=&Dn@}0uTw>**#)i*!DxuH!Q%oQgQBM5o ztb_$r#sy^<^*`W7D#?*i{g{LjD@Wk9m3h|09RrNm7_MkfDhekORRP8~?l9MyPN0}3 z?Gxiip$@|me&gA#eMBrjEI8X~yebMSP|f7G;Kc;w!U*gajOt#AH%c^NV>eC&aiR^_7t*bJgQxr}linSPc%)>zSecO5^Z4wvi zJ_5)3cwFfAKp%R-J6bwVP-_)~UHmpa3`IG1xWrDHNE8B}G+UB_>UeaigBziANR+PQ zwnRH4$ymd~iac_nC8oimg7B6vwE+Y&f@-wPaFz?^%0@7`xd4+*v$Q*;M*e7zQ>H{z zzFo7o;uf5=Fob>=dgpG#kLFyQUZ?p4t2O664e=LEv21 zvAeh-DJk5gEU3i&z=58V#10Q?xf-m0T0ByfYMwd^Zko=6UB2}k1a!dALJK@}RRe9s zw16lnj1pBz5q^mD;^vD}^I%Dr2>R&M1iHBaG>8&=KJ9um$Y_>y;yBj*+0B%eltY8& zy(ZWv(CYOJzZvLri*7oGePAN^oS8#I|J|4I|A&l>e*qLun7cEPu-gCt002ovPDHLk FV1oP+qyhi{ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Nitrux.png b/root/opt/phpsysinfo/gfx/images/Nitrux.png new file mode 100644 index 0000000000000000000000000000000000000000..7c8d640db1ec1bbe2ec270def882fe06cb4f0046 GIT binary patch literal 917 zcmV;G18V$Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n80|rS%K~z{r?Uvb36Hye0{W~%#fS(A1*2Y1ze4SZpuky;7T)*tK=|Ph;`7J|I2;b5xv9zL4LvdD>EU!nreK>J zQ30pZ3D;|C==@k*94sv@k-*N*4&>_%ygpo1sVCubafx7?C!zwoySrew+aV`2i?Upu z4z{W#O>!MIy?gI);G}V3AKCTQve5>pPz>#f9k1$mk_3>{q-3zJt&s%o2Re<0mK;|B>jU$RjSbfZlCQT3?T;(L1lRb^!4_#9Q#VGhkyhS-2EoT z$7vv(^&OK5sw=A?RwjqJxjB|&VG8x<60iW0l8^{1D=Rb@?gtHKGv(Q?FCTtCFvr5g zjfvZr%bo-f!^J%I+#fbJviw?AHOptd&w#?u-mqr@%A}EliR6<2rIWHF?`9uQb8~A@vveGl4qrIIb r($@M?bek3w_?H9)f&%+25C*>ifH=wR(#gdb00000NkvXXu0mjf>pPpn literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/NixOS.png b/root/opt/phpsysinfo/gfx/images/NixOS.png index 054a0b00813cf101c2096e5ce562f7f00e90a93d..c580b5eb9a12347b06e4589ffe12a35befa89697 100644 GIT binary patch delta 591 zcmV-V0 zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4x0b~4x0g0(DkAK z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600EpyL_t(oN9~q9a>6hagt-|u!xiXhp{1hYZ-#~wa0L#LgiNlGK4sEUrBl4| zJbNXt>}UX|NQ!TeR{Qi8{|}sVzls$5M2ab_*UkafQjlT_e<#54=-hT&i~>CtAj=*b znnH>SYXlC5LVpQ#n*%h@vL{cAA;lQGT^+)j_8P$85O)cHVk2B*7K=+2fUge~Aj{5j z&uYM!Q5A&ihnGDu?tgL@+#&$#Hyg;c<{6BzIk+Z( z)v7(JK^Lkxh6UK~%b~Xo64B?H+(-VKwu@|T}C?iE9+zi43Aw>ng1Mx}58i+N^^K(N}NHK+!f2)vU3jYDF dMT-6524B6bq)b}zg=PQ%002ovPDHLkV1iW>@Md;FQs!)o% zE(HHTGi`r>%ZeZ_OBSw5H$^g@H*a!ha%bXX0>RfN@4b7^J?Gu~KJxxWW6_zsKS@MR zeW|vL-Zh_F1$_Ux_xm%t8_ng$3i;;m$;$^Du-tyL^y)3qoloYYZhlz#Ni_YqUel}Z zekgbP*QN4(AGq-~v%Imk+yYx$g#Y1NZh_&cE%JX0?C;a|cE+N$_Wps$$l&6Fx?NNB z-Q9GOfL*2g0&9lA<|a){7~s`azP)A13<2QQ*9kJV2%J|zk^gMLtQG(9391EiP8m9Wtg2+A!7w#QL1}|l9>yY%DYK&>$(jtqh`O~}5ilhKI7gqXc1Ox&mkPC=6Jh--k%}hm!q(Gb+P&>t-T0ODlvQLF2##6Dj7HWvV(3&g}5L2j?L(V5l7k0T}tBfJp0kCK7=>%{WDj69cg0b;I5SPla&y zO-B^KgB)x)o_@tS^%3_b83I#N;ZJ4{-`C^dLPjB%!7XDCl7V);d|s0PVadoqphuXF gT_AUf@+L9%3=Z#p`?~niT{R1_YP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n80xd~IK~z{rz1KUe3}GCG@kKNmm#C@GksuOL zD5)ewhmwLsq0nh4U7{0-TOy%TN>olI5^-rX3RI#%&=B|MId)IJ^X)skv&rnf$uDR3 zyZ+D2?9ObjpQSj47x;y*xQ8tmWEBqKI-cPZ{`C3UHv104v906gcknm(4hy@9Z~eA5 z9P6A-7#lZ8i*(^9E@1^4^Bie%mtJB6Vm#+*QrA9UJBE@5Pm4ti9f>q>nmiqgu8A~g z+Ad-tX~4Ak=~(!PrUB#p#$(**^R;bhY!m0rCv}c;7wb{SHv7_?#4oFrh@DMNV_Y1Q z<|cl%$BxARu5H>LiED@*HP3H(*u8%of%lLr*oHEWZF5aLMeL|~k(KeTSN8jDx({V8 z<0Hy(HTz>n%{$v5n~}!6LY-yUiL-bDZ{6h_-!E!tautJk;iNHg!!o|#g>&$5*9B;( zAt?*kiZtdm%AAA`DrsyfHrC1lOnsGm!5u^y=agfb#Kzh!l=09WhmUQyu^V+dE#M87 zW0G`QfLw5rB04WXZ{g{>Vu{lF!(Prkp`4 zU@g8NtvTS{BY&L!zyXYkU(2WdzZ{BlT_dgSp6)##Us#QY#Pi|<<9+Nvo2={qO>qs^ ia!uEE5BFlvUhf}Ac;YTD2g3^h0000poln literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/NuTyX.png b/root/opt/phpsysinfo/gfx/images/NuTyX.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd37d26469a5fb1366bf4bf1b83460af7236324 GIT binary patch literal 2325 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/OpenBSD.png b/root/opt/phpsysinfo/gfx/images/OpenBSD.png index 84da5c780893263cea9c89be0fd46449f6601ec1..b269f12be10058b947a39b2230218c234f148d35 100644 GIT binary patch delta 1684 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 diff --git a/root/opt/phpsysinfo/gfx/images/OpenELEC.png b/root/opt/phpsysinfo/gfx/images/OpenELEC.png new file mode 100644 index 0000000000000000000000000000000000000000..42b3537e073750ed7de16f232747057dd7b6b83c GIT binary patch literal 1678 zcmV;9266d`P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1^-DzK~z{rtyW77wzp#&Sau^D0v&hDA*)& zqq$8A0KdC@+54sJrZ(H#d-h?s+m(BroHKC*IX(lv+vB6MtJ*9ayHoFUb=5=;m_>1A zb#?W9+1>GNXn5fC{+mmr)sqA59ZtG&2p&@SI1vEjXtT- z>yt){C21Bc$u^5QsW%#vDwQVLqBX2_x;p=Hc6X8JuyarrnwtIPd)eLF4R4OLbr=B(j*Pnkkl-#ZFj_uY5Hnv+RQT?b1_5qg)}(>De4Sn_R#?>WylrXqWW{y3r{?^=F}2=ETBC^! zCiBZ~k1KU+>e{98aqkyW01z4Ud1b31?YOyTIbX2(UoZ&=5ZWTw(l)sxyX1-P(qOzm z-sBE(R%nDV%;=5pkUN|sasCC({+ivrqyP+p6zhH4**ZPkO^5yp z6cm_hMe+)5=RS`-&ki~lQTfH&9~b?RJVhU_NEs+6S28(1PtS~T06bC;8!Ql+WIB^L z%yG4FbAg7X0L%x-Rh)j{rtgxVuvkUmFnNW-CDQ443cwTL8sGqQrnU-l&OmFcoB>`Y z4%2qX>&(-1bE)lW0iGbdmgE3TW#nomS5b2d0=Om@Aukh^g9X}dn$OgCh7NaL4TfSl z3MIphP{9M_DwU)IfuK)NV2vtmGUZbZgT))$IN7tz%Ezi#3%s%PoucS<7Ri(fJ z3F69mj**I~<_TwC^~PA^j|t3*fk-MWh(ZGju$&zD@oW>%!51GXu)Sh|gcy|vfO(FQ z>Rw8x24V$i@C^M{po@&s`6l4^EW>pB(dL!&N_9iCs->8ACO*fh*BK1d-`|~-h7k6bhG*s`tYc#XukQsV!w!cv3Y!d;3CweDqXtYh43-dU zdx+%~{T<>K+Xq*>KkRSBnE_W z7IGAv-C+yMu4*^zaK|M_o1xlKaI%})4GSc8xHpqyupA@@&}v6kd$oq`6$>O%3Ic30 zSSAn%0>D(mV3GdMw}!$&WDfNC|6y1lvBP1F!X|@JIz4@*c=A-kV1c$nUL}RA$`p!! Y0fw_jvR#`SjsO4v07*qoM6N<$f~cwyF#rGn literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/OpenIndiana.png b/root/opt/phpsysinfo/gfx/images/OpenIndiana.png new file mode 100644 index 0000000000000000000000000000000000000000..553d8dc918657f7c0d7ee9c9cdf1f1008acbadd5 GIT binary patch literal 1436 zcmV;N1!MY&P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1r13=K~z{r?Us8?Q&$+k`;VDRmSx5m%{0dS zwPZ2N7PiGdh_E?_CYqQj!m_DhYAeuDCdY-l!$4NbS+QVVJ8ak7IcYG9R^97ruoSb`2B(ha_n z|5<^*+kz@g&Cbcq^B+@>-(?4$#ULaSVv0=dQBXdZjn zT8CW^-z}*g2%ueRo((3BAfuqI7)>pifDv!wP~+lfE2L7Z!{OM1^kRlaM$&H&*w1-? zU#{%g7R_n;F^G6b7_%OzmyEV#fyqYAZk|3EqlNv%@yoC3?RU=nvdy=cz}tw95}#wa z@O#8Mk0ITb3Zu`ux z1N);iv(&5>dtIA@i^5)F?Y|SvNMzb8Br;KXxg_NW8hw(JeR&qE(S3$O7Be|HxmhTd zFnTPu9Hjhmdt@dMx4HtY_okM7F}-`MZ)jjJQ_j06)R;L@r8H-1YWWwLq*iPAE$tnA zG<+rS?(SW9M|Vpyi#;AgXMk9G)hWZU_t5mx=o^gR@{3EaqT#AAo6T?c_4P%TmRIUi z*%?419xRp1AJjMBT=~DDJRWb@V!O4Xj^_o(@4Ut3^0#7|8g0^f)^JozEYKJUKbMr1 zms@SNBPeX;q_Ho8zNsmD;`#G8k$Q>O4H0`m3W9!dw7B( qN~@`hGB!5$30m@+*Zf0}NPhqc=a004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00009 za7bBm000id000id0mpBsWB>pF2XskIMF-;p0~QGo-OplO0000ObVXQnQ*UN;cVTj6 z0B~VxZgehgWpp4kE-)@Q8#GSX0008yNklkVMf!RJ2mN z_!ChRmzZQ%6EP-Hv@uN(?Q9jnCTgcxs*Qq*h$K6+vx1^_7TQ`W#3%$s@TXnp1RmV? z_RMUOLW>XbZtgjE=Kb6^i(0MrUy;Eq`Xk&Z#Q5HbVvIL^73@$RAu<>;6yuR9)QD1q z`Sd|HD^G_EItJdNvp2@PGG7WK2}YGakwHhPg3rouIZVdbu4>c;90$udsf-+)89t!H z&eZTUY9!2W>%hjAHk`3_yrPz@sb83tDvl@(A9~L{d~NN(&#p_DwYsjG_|epYxs_}D zJ>eNxtk^M9#YdHENsGMLP{5~scks(<+t=eyQ!73+x8kbJ_rwk!AuDzqi*Z-wThby= z(TrN>ZhW)aZIhT=(T?BEEqGw_J+Y%OjV)H}C?%Lx`5~*e;&8YJ9AU0EuqZL%GW3>F zP#TLmLF@}*o;R>CIW(}O-R?_&jO%;n57e zyn$o5f^%-lxuJS0m{56yGjl3I@pz0|>g?B%o(!w^%t-frtPVvB5AzJ`!dwN{I`8z1 zRPfT~dt$Ob#swuTCb%5t=8?ATSIUPkWAi)_NvCp53HerGZXTQoNRKY{#O=K|S zVuVfn6jSDTa6e@IAaTfG9{f_u>T-ntOLzL1(kf)|-%-O~c!-$%SfT8E00000NkvXX Hu0mjfS8$-{ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/OpenMandriva.png b/root/opt/phpsysinfo/gfx/images/OpenMandriva.png index 0df0ebf9ae5c030da88d18c10359ffcf839a1357..94348e8d74ccc4ac6dbf1f3ee6a62bcf29f67b94 100644 GIT binary patch delta 1107 zcmV-Z1g!g!5#0!o8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600W#!L_t(oN4=HXOH@%5#^)iSK&zoFG=q#HNs}lFDWnI9py!@K5UasZi&QjA zQ;<@#$g->mFQYb&dC7a;8y%e)$JFtD8OtR4KUQb$GyB}!XRgx2@60*hUTf{|?6dYB zjV9UP6+iz@Lw{_;hFh-GImvH=(Fv>?OqimCS*HzR>ep3?uU&)mzD4gRRKgTp#5XKM zlzx@TrRo)EbjC8Vp8GgQ zCSh^4O8(ZVol8V#8I^)DOe0Dmv~m&7esD0sF==c}<$nyISp>&$g5_TpA!cUH3VGjV z$rz1OzJPecfrD674crMdHu~MPpjVph+uuw`?s$IER5>2iBZN|Qy%CmLR`5EWS*eIXjq zmRR8YOMfeYYQ92iBpNsqDA0mxWVDRS48)X<`8_$3-N7AhT#Y@?%)Eiv=VovRE<48A zmM2NluBU++K(NlS!tcBRbmI=%{rb^yk`!4q6tIDaC&Rn}{Qe=u6K?sl#eah8VH03t zSYcnl1`g#7l3JRc84FobchGLfSnZ>J2+0lHfPYY@#m0T#B9mK+`@|*;%IN__TFh78 z_Kos2vidAG=>0aY!0kv+NF~;Jlkoqc zM5pIgkjoV`>0o*H5b01~AZ8>r)W~ca5OQR_A`L{aX@3R84}jTDqv2TX@= z*ZYm;R-d9b=ZqU7N=MNO=f#W)KaKGcHW96yB6#p9r Z%|F~7?ySlm#n}J=002ovPDHLkV1f_5`#b;u literal 2193 zcmd^=i%(N$7{*^`aVp?ovtFons1wjC6P-##1r(+jM?ld*b!!zFvkEAvpeV*FAeVuF z2y&_AQYla_EtHmC==}!0a0dY|QH&sw51fcWPiYZ$@$**eV(Vy*VBCG zWQB$9b6)7S5CEJ*_6Hq8sylkkpNp(Pwb^Qbxe#_RA{b6E;Aj~frMpDj2jT;V<5fVa zb|TT>a&{mW4f81z*=Kjjo2%P47^uF{hc!Pu0w))Z=1m;cP3! zvsT2?oz65sJO>h*-aFg4DDL6=aV$t;LlPew-vk#pi_bCL&b2sPYIjR)#3!=dF4j4x z@Z6I)F3FJ9zrE^tE!;)0N+7z~TaxG9L%dZOIrgYtvwiVYzm|L>t z*Lhx7TNb3t-LH2M(%8-!%2iaMYo^LKjkS^59GF(;dxPmi?=Ry%&ANw_@na;ypNN`1O%)OS#vW_5Hk9W=Zt_P#!a*lu1*b$m!SIyAAD&ujQ;B&6mk>=V_JBMd`m-QaPCCc0J@UOz%%h%VK15F7epnW{LZB#qIQ$m~pI z3Q5hwXIQ%PjfzW+;;))}sr9_fhPLN%%xdDE=a^1)jND*%UE?Uv z@&+k#Hbn4%166)WZ zTsRbZ828N zcrzr#rz9khGuT#8N0aiwMA^P~y$~i&zVH0HVm`X&b4dWU>Gq z$zNCin2d}>zI}%3$Vgh!p@tEA_}6KHCR&xIe&QE0ge}Kl<;? z!ao2Y+{zp14%j=(MFzhBnA&6IHK_b{y&d?(4<7HdG6j!6CcGU$l)>#*L;#+iZv`Zt ztKoY;D;oipc?8Z*czS#euciaO09p@^Spk!I-aJhMfFpj1eFBI76d4KApc`;;akM2y z99_`Y929s?gZ#*!9kGtPe?Vo!hghuH2Uukz4l(ATU@*wyT znDxH{{8oSl0Kdk@ve#ziyGe7ox6E8Xh__>nMMG8w9&g?a(jLRj0>95TN>UEyc+ T4601_6PgSO4h?GFL#F->x~ywe diff --git a/root/opt/phpsysinfo/gfx/images/OpenSolaris.png b/root/opt/phpsysinfo/gfx/images/OpenSolaris.png new file mode 100644 index 0000000000000000000000000000000000000000..15eefe68e3945a06b3260c164d3e02a9ad13020c GIT binary patch literal 1612 zcmV-S2DABzP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1-(f`K~z{r)mL9kTV)jQvx$Eb^+AnMAB_5> zPbQjp6BG5-{mF(K8T-rTbUNy0*j)C(UAG_H))fY-PSB**~9UEx4oBpX=Q`B2Y<AWobS7u{|XpmM0dK7*X=@V zG(u(7PaZ+cAbVp27;AO1)az@Z+u4S*Q`UymB2RfZH)>%mD3lE4^@tcZ)ty!uSBkB% zacv}m*ZuhWi@V{_@P0Txei-)Qt?<*>5132EWg>hsMJYWe#@wCl$lKeGEheL^_j^4k zyX5iU<6LNea635IW_e*)h`_1I3NTFn0$G&?2N<+uyg}t@kiqhp_iT^6=CM#cSq^P~ zT5>|irlQoh!5t91$%w?->~`4*-QJnwrL{g21!s$Wbp-YfZH3svbl$KTg$SG&)rw)FdMoTZppifQik!ZN01KmV<&LSU2QzRLEoJUT?o(?CL3`sDQVRG(7=b53=kCzTW-BfiBu`|t0DiV^|EM{=i^y-XDaIjYD^h7!AWH!St zrT|Jp#o)YZ6OD8HLu!;uqhxAP-aO!E&_KTjI$B$yr;CR31AffLS$Ul07b)k|9c;UN z3tA^`LrZue?-A#KOLJ7>?uApd#}T>b2p(jlzgOzJ~mBN4*o5!QA+vX zZ2sIx@M(&@wt)ClI%o5vKJ`Xb%wu|u z3cs+)0`C+%V0XGLo?|W36O|tYUv2|@|Gs}vb+z%tolr8%u*kI-vMv$IU|k*SfT$5iBuj)LiNxr z4ks2V97&*Ogor5#5ZR{lBa*OMPbO#biD6i9ps>=5UlYPjjAiYr&=!cIr`Ma|(?fLL z%+=9hwA?t6_lh0j{L{gCoX$-qAhjcnucNcbbb>I-j zR6M~`Z*8}$j6c88LL3qa@ac!tNg-M!UnIka`)@$^l{=XP{N#`ewpROBB=C`zhHa-Z zbLjRCx!E{uO``7Xr5XJGzE*f{T|KZBY2N6fr7 z0%hlOuTx2^W4u_3obY%dSx*d+b3ggpaj3X_MEoXFa+ZE%A1WOp#SP!Rf#@vkoq?Zy}V_dN0FqWpZ|ZM(fkAchB_P=%gEIL0000< KMNUMnLSTY})cOJd literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/OpenWRT.png b/root/opt/phpsysinfo/gfx/images/OpenWRT.png new file mode 100644 index 0000000000000000000000000000000000000000..d163c4113233bd74d40c35f73257c63d0d8d534e GIT binary patch literal 1521 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 literal 3959 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 diff --git a/root/opt/phpsysinfo/gfx/images/PLD.png b/root/opt/phpsysinfo/gfx/images/PLD.png index 2b09d7d29406ba42531fb1c7747fa2ac36df35c7..41cfd68dd24d86ebdc38872b2dbe390984e860c2 100644 GIT binary patch delta 145 zcmdnN{)&BqN=~+md_}$o8?#K)P&_X8j delta 79 zcmaFGzJq;&3KwH>kh>GZx^prwCn^e?aTa()7BevL9R^{>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1k6c9K~z{r&6jO# zQ&kwppL=`z!dO>W*Rjnp*k~u3I04CC$fR+@A$)+uX`%!p8W%noKWNb4ON@R|qkQng zL_(rOBoZ~~2aKp77DFJsbQ@;zg;+CinPF8KbL-pMTmR3!r)x{^+I91TzvQ2Dp69kb z|9kFp&bgJS2p$Y1ZD{JDRZuNd0!5)eph4(oDD>$HDT#Jg6f}TAO=uqCE_63k4$VXe zx&R%84#3FYoXp3J1~9OUrW<+#YT#UvOhT_gy)ZJaWehMhfWfQK9D+Kv#QeAl?SP5z z^e`K~%PcVX9ca!%|Ha@;9dsPO`?MZrlQjeQP$QZ%kW))!Ai=5{PY@-OB$*VEEt*#` z6R(KA#hnT&}Sde`DY)cuQsftlke=ID_4eSYHCWmo(C(mSMR0`ye?W} z;9%L-?d1LNOKR)=m`pa_f6^qP5&HA}J@i9gKlyw<8Wx{gZbzb5m zp>rGBOOSqRGr>P3rsB85d&&ROlX{SWvZ0$6KCqLl77JN~91aILD=NrdT1twNRlKL5 z4xWK~q5Ok08O7G{@J_Nf+$y3p@$bJNH8>(7op3lzqt~v{@bEB=j*e0&G>L_z70WuP znhmsYR2(L1+Wn^JXMiaWA9_2}s}7z+63dtCV{$S?#r}{gBc1r=OB6l#t%!1wV1~tppl1Fy?^H!2$qIQ7o}i8+XK8u&4v_`;;fYW7 zk&41B1dKGXfdzV4Jf@O`RNmA~jgM#Vvg-99-8kGUqP#3&1AJ=D3#+qI^wNZUM=5so zR}sw!@9;FF_vem`<&{|r=GE?&jU+Jx`M|EY&(~6!NEzsZ z4(Q!EfSa^cEFr0?jw~&mq^!7ITrdV(aQ`=J7HQ*Y2Jjeoo_0Y67p@WfWt*!C2A1M= z%|sSgwSK_>6kaS6iS%%nV? zcunep{?ZafP`-A(wgB>=#^do9&aAK9FJg@>0}M>CyH~_1z=wR?us;aK--{|>Bq_W6AX#lTm z{3rA|=rJh0-OWHK6e7RhugbDKsF;=KZ5G?tm%CTt4}~!W4WxjPGBh1fJH+eE4RN{i taUO(zhkk)B1OkE6eO+!|+W&Wm{so6wa^*$9cMAXj002ovPDHLkV1gupb*BIT literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Parsix.png b/root/opt/phpsysinfo/gfx/images/Parsix.png index 9cddb1df4d52de924a099a8a31d8aa94812436f7..4b4671dbac46f0a8eb51e18021257cd0fdace2db 100644 GIT binary patch delta 1381 zcmV-r1)BPi5$y_)8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600gW_L_t(oN1c~%Xw-Ea$L~o5V)>x#Nt92F{#apwQBc$>%7j2iJqXN_iV~zY zaM^>LNsVZt;gChG%_FBxafmvP^0IB@yxUw;+{`XFbjQ@?Af(vcZM*g9_xhaQ-+q6- z+Z{c4?S9{XpMUq~^ZEW=WM5_F|6=gYMRGn8QHGY>FSb6VV67|$q8A@tTHuMt^_MzZ z-(pxR=VEmI`WfK>wAseYg|!m$@g~V_d|LSR*8etto>e^k$wTE#sW z1O2sIL&BGyFH>lv&p#_2aYxvY`E-S3HM><<`x-UC8t@7O zyMi{N^$J6-rd+XQ!B+q`^&VkOr322$lr?ABLxO#Jw zvHR~xQX&&Q--HEe+`G!fc#CmFg2D#l0N;$6{_0UHWEQ(qom<2i6fdOOB0ROfTwxk8 zTFe2az&OAdo4A3j4kmVs4rKA!gk4ye&VOR+k5%auFl}C8`0H}F&Od!vyk-s9#1*p! z_`|-}h3I5JBX%-^Xu5i#G;iN1iKF}VT*X^W*2-d#Uj7SW&Y@?)?Q*Qm np5kIyD@%p@0&H!iQ5pFUV?OI*a(wZI00000NkvXXu0mjf^sAD; literal 2193 zcmd^6Lq`2qs~&~qd?xWn^0^jM+`e;qQJ_W{rau6sO)IcLrQ9iY4Tqa{lh>lrLvZe+On z^Hs(sYt6qjx7xU&6@X2fH$D0U*nW+FvJCUUz=&YCUA|(aVvUIdaaXOm#d8zfp1nWF zaT_Z(S&I;)Z9VRp)%y0YHtq9tZ~yk2O8Z?04;|p{+1t7OyAB8Yn?HIgzb73(;jMB4 zZ}xs%@8;a^`caRYUYFa-_pYGbbEVu1OFiv3?7r;DPuS*zma-$r@O}fyQCsoxZM5J( z$x-i$lRMQ1))x9wRY#1w50gv$UDE^3mY;T3p0o+2hp2qkjhx(&5^_Os{_rr>sxBb# zrLS*BxIdrnD+$FjVxmX<@o&#=6^Gl&!mNuUT-njlouMmkNAFh!+V+Gk$zuHajBd`0 z@qQhucQrOv9b{J;5it~|QxkD)G8AO|5pgL#EF139(OS(fcoi zsKXp5BK2#Tr_&ODzju+Aclpv_jF~FJX)wxjocUP`Ggckto_6huB;kOJ<#jD3xi2az zD>*@N@x&OzBReI0F!s<$tS2Y^N*X6Mlf#;bH&?N2xSaH{IC2puM0Vxsog3#zScht_ zGbXQY?n_Jll%xtpcc=4@z2);K3ccl`08v@#XhD3(os6jxs-hxPTv`4=%&)C1dL&M5FH4nI zCcYO%wUyngtuE=UOsbJow^mhli3Q4s@u?Ny(+5nkujJlB)6?%J1qz3=*a zrd~at?vs!8_l^!cRlVs{4gUl8!m2GhoB-Sb0q)NG!1Vt+n5#qE;UoFfpS1rM0Q9TT zLnp~fe+>YOtQ;NeJ%XR=tXtGR4xRZ~j=@0V!@*#&##r=A^no~GjnTkmSP&Um25b5n zZfXdd*GZ!J5{}?P!~tLg1yfT~BLHw@KeR9#gyaH)13@S@GYbONetv!dr?$;n!OJ zgslTw&hep97(IDga0+2-Rb*s!tFRkqS0|^?*bEvfQP~_Wm&>No1m#WF&_Yg=R6t=A zmE47)05Hjb7!Bi=Vqzuhs3b}=ly-9ur_7;p|CiOS`%X`aUmkqV&_4x(%lDsW-v z_EKmJ1|<`{qxsy=35s!R5)p|OmP@7O!bmbg#EIS&M@4m`T$2DIlgUJIh2iPx;SC5v zB9VyJvkW~Gn9MjPi9|S!uEh`@a+tZ*27fZ+P)@>yU}2oBGk-ok`?t=3Cf Z3byNwbcJG* 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 literal 4217 zcma)93viTI6+ZX>|NZyNG@w{DNTo{E6f!(oAQqA!goM1B$G&&j-T!etcf)RWmkn@c{=NTy z?z!ijdmi7tyL;t|rDnr;0|1ySmo5GpjuY9V6Y+P`wrxQi^c$DGxC!U4vxh94^6MG^ z+w{uCU;27YJDF(f@DR6OLb*pIj^j|0?=AuXdH`eqIx#)~K|X=!K!uN}0+iB6)QE~6 zg$g*MtmP{t85YHYP_6?gQO%$=3-GD^&&O{-+ch7YJ>3PLpY?^OD3ZaR)93LIw84MX z*u&I6I09ef^nrGMnM7f&szM1Rz#=e0DsTl>s5QIgg9#QJNi5O=|2WwgdU@65V1#QC zKbKlT#nofbsKN|^XtA!;-_GxeDzHnTFe%MAGejU{Ido)7#xej=>x3oGuQA#T!BAA) z7j+2h?I(}9?vuO6$Ql9rlLfBZ-R_zg(3xW`)KKV|)Yp?w^YYV_6G`qG&e!i9_S0`; zRcNppsFsI+71@*>!T+fPnfmUFfLN-10_M$eS&h(~DV+MviKG`S7HcYxQ0nuH)4${P z({;=^o5M(vmanaHz;oyl{dwu@}~Ztw}my-(6#Msl0>5L<=(owrFQTnok%(``13vG+SAReL8psP zGAEor-h44@6gZ%YN^;?DxQm57Ze(8RR#}G9gu$#M2mD8}J`42WxS{~$1fu+E7y-3=HDDH8+H{_TVdv9O;K#1*2Sc+utLO;pDq_TxPz%V1&97x)wT3_0jn_|Wl@y) z3<7Pkj0CRx;;3ZevyT5%OQxIVjV-f)w+wp|iOm3U%j!lNA z=D2Q`IQz$&;CPHcUauQoXN@Wd&?zhMIO-W`NeluKhjS53ZRa=}95vnv?WRuS2JcPf zBwjI`|nRogT>3%;K39>ABd{>{JGloeF4D!M0iEQ zSW6B)9Le)ZTOk=6Ad|SOaI|heKIpkzPZs8pf9KL6Ys$=OpOE2Jq9%x zoF!|Qe}Lgg;tK{gXcNdgFsKF+>qZ@DP!+=~-)Rj`FWyZ8es;2@Q%`qO$GrJQ+=MZG zV&qGfAP;0Id49yXdk)v?cybxvv1CBjiR6I2@f?d_l13dsmS_8~x&&3Z7%g+W!74i; zMFt0&I?Em#!mUis%xOXflZ&^3(e`J2s?$52PE!L>uv=94jmaV(^vs%-=46@!Y*DB~ z?I%9vyi#W0N^Z3^lGbaDofC>Wq7t3U=EovD`~ASj8zU*gx(2@SiqoVeKeOg3zhJeN zoV@pvwM{|;YQKHef~LUJ)1yN^coh+BHp-`OFGG`Fgf75iHo<1K6rEbUN6Tq%>ZZ%r z;f$IU8?rjUlz19W`|KXig-}J|9d1y0QC49QUcts;Hu1ntcZRiAPVG-ch(vtk%B4ow zxw+BPbioZ_X1r3%E~S8=>u|4h-~spcto_p6|kOjBi=uV}!C z`Biuh28&E^Bou=|lbP!chNaukL-9XFMp4|S_#P5w;g8KC*i3}5Wb?O2sv9OgjuE+u j@T;oncZ#vKBxk-mbgKVHmf1gHjLIb|7XNYKx8C|cTvyKv diff --git a/root/opt/phpsysinfo/gfx/images/Photon.png b/root/opt/phpsysinfo/gfx/images/Photon.png new file mode 100644 index 0000000000000000000000000000000000000000..9d6e2484cbc78500591af197f2403a8d02288ca7 GIT binary patch literal 2624 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Pisi.png b/root/opt/phpsysinfo/gfx/images/Pisi.png index 3d44955c336b4fac7c5d4a6bdaa2c59b0e321bd5..09c1d6fa86da77ab5836de4ac860451ada13dd87 100644 GIT binary patch delta 1461 zcmV;m1xosn5xfhK8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600jFY6e8FfmUTUmC zO^h+IS|wVoM6t$O6(LG%+h7bWBEw9fOk0GO`(+p|!6z2#7sjEf4VZ(2Kt@802wc;(80$lk4kmT2{kPLu74~Az|_;%SgUX>tIpbI^c>t;HIMfP=#WY5+h}^BEbR7*hbQXk={I z$v}W!4}W4^fY`13oH+q4coO!SP3S%HVR#2xY_RRpO5C5W_0Hmj%U;q#t6W`pIWdl&&0X%&f z@PD8dG5~0#(_epHHUK~Um@WPBoBaOgl3vpR80RlT5CCV012`QEYhyaV&PN}S9Xs3N#P66%N<)bYq0bs@BuJ? zyJ)ZEZo5-%+H{@1%b|sW09u=uKY#$>p?{;R-2qq;KDhk>4Z`dJAm~>Izi?SF0fop2 zV{>x0=va)tEiY9wzX%NgFa_Y(4FEd)ZTMp0Ze2sxH20p{104)70E&+pkr9FukQ7r3K%|RouuP2Q8Gl&n z!P3v<@L;m%JG<9vz?Q)P{G*r*eEi8r^3>B$YCwJosc<_H5%(s>FqTXZ5A&eeN9w9l z0Vs%|ED(T#v@L0;qMZ%Mp4oQUeg~L6ahW|!ZoUox@w;sRek~Y;fdIF?%fk; zPA18y%^rXYy#Xho$={Mb#9&dijDL?z$Y`WP4FIrxPMt8GzR~HVBnplyK#+M;?8KTm zN_kk74?z$~R@kn*zYsGHuL0eq*tW4J{k*D3e5_&6%SNbCl7rs#}L?SVlo3u(m&m~f<4?-A`*Y>9>ziQiQ!(WXX;-|$|rISOhVy01k4CngUZk>r<^ z!Z~3Fm4RdvV>ELk5~*C P00000NkvXXu0mjf#G{Uh literal 2193 zcmd^=iBl6-7{DJzr)rBm$f$$2Befj$z+yFO)q+L_L@p6TDy@!UEedMUQM78M#uKqp zIv}D5rl3SY1Ot)~jzq)+10?L`fK4{UfH8+L7YO$4hKil>Kj=5JyI^ zN^=|MF%AIW7PK}n0)A%@&lp$u4lF#w1Hcu8g+#3eE@12j;DgaFAB}PyJ!aI$Ke_gfAw|(r%fR$fM+>QkVETsi57ECzN>3)hvTM-hp zJR~>}nVhjcWTkBC*>&qfI%d&jGcv`qPq)lD6CM#384(;ENehpTiHeSVH1`bRof#Dq z7Z($TTf-Y^ znL85`cI@1~d*?=ZK-TtMN%Fv4*_wh~Nk6IAX6;YjePHhvNmw2hnzeU-N?Pi+Uk>c= zjx5GD{KZMg#W&nkY%Dx>C=rXx!s4$e@)bZW&Z6&{@pE#Sown`I$QAsJgpaRQo=*=!IzV&y-?MtQ1^4`3%sykVC z%9yOOY*}GrQ)yM*ovQMRvfBH(x}vg&_gK~UE4Y=}_p9#p72jjkJa|}B&aKU@sjXI& zKVq@D&FuU-PNlxQqJjO8T~~|W6LC2Wb@d#6LqRi#C#WxIY^dfm@*0}z4Xg)Gn~IwF z4UhQj7XAZ4Gec3=_JUpWnBT%};Tbtq{Kq_XU5EH_iK0=+f703_Xch_Bq9>1W9?~IX z8F@9*R%XXjZmUSx+%D*BFY6Vs(Kfc>2?uEtJr#Ghi`&e?8c7GzA!)}us}yLZ1QDCs z*(#JHmdX*S1eJAKBwVQ+H6r!hU0j($+AUYgyJU)Pc^9VWR(ADZU6`s{sm3(87VlB2 zHF%d+)$>fP(e_|{J;3Y8T&8$>QJmU;spRR)DNcYwp=_eG5_liwnR;$&hl*0t{KmscwO%qEy8jv^$05Gm*lM1+CYgRcp| z4r7o&9wf?0U>TL_Z+i=*P^nae@F0XhEdoR6e1{^ZP>B%GgCprnw;>jb1ULW)MMRPd zhWw|vr8$!v^q=L1923GM5g`izo(O?uZZz2E+zq$GA{~ywSiglsGjc0dUBFfujApZC z_yMsI`T!|tgi4!0yg~Xv})jAq%2U`7do0hbf58KIJ z;9lD8T&->a^}JR;SN(kjiXbC)04hUO05?S7~*cRg8yqL@;J z7m{QDFs#bwU3;|n)Y&o-LR=a`kj~qRN#GsA1FRr$Nol13MLT(gfTLG^ui`(GRjnEGORZ|Gs-chKt4K<0M|C;kBioD4Al diff --git a/root/opt/phpsysinfo/gfx/images/Plop.png b/root/opt/phpsysinfo/gfx/images/Plop.png new file mode 100644 index 0000000000000000000000000000000000000000..e37eece21636a67a084427450b9274c795d50db0 GIT binary patch literal 2199 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 literal 4217 zcmb_eeN2^Q6#t#~#{O;>w(ABavcni32fwR5$JokBi=bYbr z-se2eSvPBDPONv77eH+8^z7MErvx95Oa87bD7Y$B%uCZ3tOVkY1RvUz88;djnwgt@ z|D614N*P+yOw25C(TRuNNeiekSs*P9Lfim>7)Aal(CRJCF2jvOj&seTj=p$}ihz%b zvf4E743NlC%uA^P&BNSibK3w}x|ih33B~la3UBN=`28E1SA5nRi9Qh^`p^s2%ma+Y z!09Z_uBsKd_yfVLv|(R_sxoZbEeVW*o;*P_lOGmHPb3UIXnSIw=JsdK^++W62_ij+ z`#2GLX_11}O)Bo&uVK`*Nchkv&4k`zy0SF%gKPDhN^0R!h?o2QunIxTJTH7Y!7x5n=zdhHJ8Hyi%rC&;QhaZ}0T1}>BW z2j()D?Q<}x^oFNaOS%iHYYt5RR8=&l5-z(e)og^IMzDtoaY-6{BTbjO8;1ETbAB^X zVIdS{B-?A3JHCRt+f5h>q9^_dKDLF;?He2eO4ybHzmcaHE%O+E+{&o_*@gDvB$$WJ zbJZmW7jjHXlHeNgAguUDAv|w0KYxN;8}|9k$_1^w^`e9AmVlc|=NnY@Dl&>D@kus< zU>|M1y$x7KsLo>?t^*pDGS`lC8m4CwA`c}6?{t0O}bSCVXW$jaeLC<(tnsJl%x z%~#P>(P<Eubvc(K^=@mGRK7 z>;g4^ZRuC5VK!Z{+#`h+NE$6b69oe07JvIyxP6y0#4Vr1!oB)?r(~dfuuR9AX3+R= zoH<8p*qj4*@e$BdExqv%169X5p!kl4-rl!uggon)n<#Gq*DnlbPTHn< zQ2c9P9Cm{%CNtLtOD<|r{%^s&#f0GP!FjdKKV3y#8gMp0{F`f3@(4snfg*NmK0Y|L zzrjPXBc%%7kG=z*I1!GC#fEWEi}!+N%d$&O4PWcexJw4YGeZ8BvG4>sONMBP-l_~) z3{f)$%E_0RFVuwN`!nvk2g1BC0>fdQ-+z57>rN6z4)FUaVO4#8eZK#rh#3G(9ackm zr+W>v-DnucYU_KQa|0Yi%m9He39bosHbgsOWXCbdMuQ9XuX_g=x6?dg23Qs6JCUxx z$FPE%ZM0O%%_i^o!I6jr6x*&QO7(<785{>y$ezop9GuYCyhJ1*VC(=MnjC^^E=k1F z<(V!|y}^@+1en+F)!+)HLo%w<4J`)H9a<{M7EG_Xj zWK9@oV8=cx0^Cu!$AWnPYW$OqgMsR(2wV&1UnpDdSwt_48EEjJebfYGLs=)=ubEJ3 z-Cz*twkz(7W1{CWWyd&PR>_xr!S{&iPZQzTBqBEsDW7_r|NYUFxHPV4+QwBug1OUX LX774n(b|6j(+GR7 diff --git a/root/opt/phpsysinfo/gfx/images/Proxmox.png b/root/opt/phpsysinfo/gfx/images/Proxmox.png new file mode 100644 index 0000000000000000000000000000000000000000..203ac0bfb20f5cdb61c029a4d9257dca13394dbf GIT binary patch literal 1243 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 literal 4196 zcmbtXX>=7u8ok|b%}eq~NPrLsK^BokMOj3`Vh|;P$Us041W_0VVcfuNz)=D?dIS_u zTv5Y_q9B3`i^fqDNDyTekTry8*h2D>yuDv9HMd@X!yM0<`7w1)zv@?A)%UCW-S7LV zUmP)fNU|r>10Xp+Z*U>|w(@d2`TN-H*+C$sYyRNe(SJLpv`wj~Q;LfC;EFbPF4T*E z?d;{U7%xkX3Bmu`TWzA^FMapy!Ku$m;IF>`^Ul#o>DwC_kqBaI*5k|@Z=vqs?vs`$ zqn#LEh{SPY(Ui~IxZUfvqIy)d(gLwLbK>vCWdkk(+eIBbNO{OY?3K1e9jPk%*Kj<4 zX6x2DIm3n{5{$mn9cJHic?De(J9R{gVu$_MG1PAQqP7O^G!zU)#x-4#p6rGz6oY>F zSJZ4P!-e|uAGQ=mwX1dJjJ;LmnqP6azn4bHT|$D3El>}pi$7hP`l1WoN1RA0_1e^= zTE&X=7PkF82IiIRK6<$CgV|Ys?&wtHs>Wuplk^CY2Gf8=mJD8K2*EEDIHOTC#G=sr zk-JSzLwM8I@GeYTd0fqO4Ap+l`UZ+~i3=c{p@+m(}KS`c9! zM)~n|KjjTtP+?d4MjZqX>d-6`rezV#A}DPzO;|A<(D~otKtf(VW=)!iZv6&fNP{0f zIiCiJJBA^5!TfUPp~HLCZcrL`zVrhz5E4fR3Pg@d@zsueo! z*!$$zcI`*+uCBvrxn%-sMAi)hrXGV4jzMS!|8qPPLhWatq3DSx#-{E&fW4{;l}jvP zLXeT5;_7qSk%qA(&aUDXc(#?I)5>B@iAA7CNLe5PBS_kG9T8qyR723^LgJdw*QT}1 z`t@19P$96zxk`k<5gmf`$8-Z)Oyk9Md=}WVZ}s)lCUni>d^-e`m`MZ48aTi{E_V52 zefs5UdwLqOF4Uto6ooE9m7qua5HaJ9}tY!bs%1S9hX@DV&a|yK3L4U`B z8h6dz*i<+;IWAJUkbai*g&vtT%U)7~E%c{FBce345uDW108NX=S&Ie2FsgkBju?%h zA~t+f^=VWlCc;}?jq{3GaHux)Vv^Kf8~|$2LrW}|3Y$XU%HME!_ih|)-W=X*yWvKU z2g#BRYQsr?ixcIjmn`vKqh$sS(dh!&TXYvlb&TSKUC!s&`jT&xM-J|snAZC6o3*DL z#g!-YFWM&dt04oH9cQ2_ZBj!vZn5Gt%7^CW`V{A5+onHUkY4s9et+QJsSVV%kvnwR z?^)UKzW>Jcw|@Qo{uo0m5Z}E{5fX&=Li*Tb)F`Ar7(#H&@B!pyTLD}HH>_NLIPlXB zwEy+E{#4#5_=Nu!?_BTqJ_XfCQd+>S(E;l@R{rcBH-(El+(0RNZeK&2` zQtDwiSVITjUxnC9GZdvsy&X2G#tA3t{kYJfJ-SHY)Dt+T&p%g*z`gUiv>UI+=9&4* ztpi^|U5JV&pfu7TAOQp^7t9;+oIn8vVC@_fU!*cl7fD!`#+6rH@7RaK|exH z?mQMllwm9@D;Q0Vd&bYM#&0h?t)e;oW;0zXeNTEq(2rj&C$YuZ8I+4&)JH8-a*#Af z98I==EVF`Nx`DV{XLFH_lw>5inZkGO!qMS*3(JNLy3NPTs&S5BY7R
", "
" ], - area: [ 1, "", "" ], - param: [ 1, "", "" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - col: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, - // unless wrapped in a div with non-breaking characters in front of it. - _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] - }, - safeFragment = createSafeFragment( document ), - fragmentDiv = safeFragment.appendChild( document.createElement("div") ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -function getAll( context, tag ) { - var elems, elem, - i = 0, - found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : - undefined; - - if ( !found ) { - for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { - if ( !tag || jQuery.nodeName( elem, tag ) ) { - found.push( elem ); - } else { - jQuery.merge( found, getAll( elem, tag ) ); - } - } - } - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], found ) : - found; -} - -// Used in buildFragment, fixes the defaultChecked property -function fixDefaultChecked( elem ) { - if ( rcheckableType.test( elem.type ) ) { - elem.defaultChecked = elem.checked; - } -} - -// Support: IE<8 -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - if ( match ) { - elem.type = match[1]; - } else { - elem.removeAttribute("type"); - } - return elem; -} - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var elem, - i = 0; - for ( ; (elem = elems[i]) != null; i++ ) { - jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); - } -} - -function cloneCopyEvent( src, dest ) { - - if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { - return; - } - - var type, i, l, - oldData = jQuery._data( src ), - curData = jQuery._data( dest, oldData ), - events = oldData.events; - - if ( events ) { - delete curData.handle; - curData.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - - // make the cloned public data object a copy from the original - if ( curData.data ) { - curData.data = jQuery.extend( {}, curData.data ); - } -} - -function fixCloneNodeIssues( src, dest ) { - var nodeName, e, data; - - // We do not need to do anything for non-Elements - if ( dest.nodeType !== 1 ) { - return; - } - - nodeName = dest.nodeName.toLowerCase(); - - // IE6-8 copies events bound via attachEvent when using cloneNode. - if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { - data = jQuery._data( dest ); - - for ( e in data.events ) { - jQuery.removeEvent( dest, e, data.handle ); - } - - // Event data gets referenced instead of copied if the expando gets copied too - dest.removeAttribute( jQuery.expando ); - } - - // IE blanks contents when cloning scripts, and tries to evaluate newly-set text - if ( nodeName === "script" && dest.text !== src.text ) { - disableScript( dest ).text = src.text; - restoreScript( dest ); - - // IE6-10 improperly clones children of object elements using classid. - // IE10 throws NoModificationAllowedError if parent is null, #12132. - } else if ( nodeName === "object" ) { - if ( dest.parentNode ) { - dest.outerHTML = src.outerHTML; - } - - // This path appears unavoidable for IE9. When cloning an object - // element in IE9, the outerHTML strategy above is not sufficient. - // If the src has innerHTML and the destination does not, - // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { - dest.innerHTML = src.innerHTML; - } - - } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - // IE6-8 fails to persist the checked state of a cloned checkbox - // or radio button. Worse, IE6-7 fail to give the cloned element - // a checked appearance if the defaultChecked value isn't also set - - dest.defaultChecked = dest.checked = src.checked; - - // IE6-7 get confused and end up setting the value of a cloned - // checkbox/radio button to an empty string instead of "on" - if ( dest.value !== src.value ) { - dest.value = src.value; - } - - // IE6-8 fails to return the selected option to the default selected - // state when cloning options - } else if ( nodeName === "option" ) { - dest.defaultSelected = dest.selected = src.defaultSelected; - - // IE6-8 fails to set the defaultValue to the correct value when - // cloning other types of input fields - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -jQuery.extend({ - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var destElements, node, clone, i, srcElements, - inPage = jQuery.contains( elem.ownerDocument, elem ); - - if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - clone = elem.cloneNode( true ); - - // IE<=8 does not properly clone detached, unknown element nodes - } else { - fragmentDiv.innerHTML = elem.outerHTML; - fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); - } - - if ( (!support.noCloneEvent || !support.noCloneChecked) && - (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - // Fix all IE cloning issues - for ( i = 0; (node = srcElements[i]) != null; ++i ) { - // Ensure that the destination node is not null; Fixes #9587 - if ( destElements[i] ) { - fixCloneNodeIssues( node, destElements[i] ); - } - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0; (node = srcElements[i]) != null; i++ ) { - cloneCopyEvent( node, destElements[i] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - destElements = srcElements = node = null; - - // Return the cloned set - return clone; - }, - - buildFragment: function( elems, context, scripts, selection ) { - var j, elem, contains, - tmp, tag, tbody, wrap, - l = elems.length, - - // Ensure a safe fragment - safe = createSafeFragment( context ), - - nodes = [], - i = 0; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || safe.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; - - // Descend through wrappers to the right content - j = wrap[0]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Manually add leading whitespace removed by IE - if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); - } - - // Remove IE's autoinserted from table fragments - if ( !support.tbody ) { - - // String was a , *may* have spurious - elem = tag === "table" && !rtbody.test( elem ) ? - tmp.firstChild : - - // String was a bare or - wrap[1] === "
" && !rtbody.test( elem ) ? - tmp : - 0; - - j = elem && elem.childNodes.length; - while ( j-- ) { - if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { - elem.removeChild( tbody ); - } - } - } - - jQuery.merge( nodes, tmp.childNodes ); - - // Fix #12392 for WebKit and IE > 9 - tmp.textContent = ""; - - // Fix #12392 for oldIE - while ( tmp.firstChild ) { - tmp.removeChild( tmp.firstChild ); - } - - // Remember the top-level container for proper cleanup - tmp = safe.lastChild; - } - } - } - - // Fix #11356: Clear elements from fragment - if ( tmp ) { - safe.removeChild( tmp ); - } - - // Reset defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - if ( !support.appendChecked ) { - jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); - } - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( safe.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - tmp = null; - - return safe; - }, - - cleanData: function( elems, /* internal */ acceptData ) { - var elem, type, id, data, - i = 0, - internalKey = jQuery.expando, - cache = jQuery.cache, - deleteExpando = support.deleteExpando, - special = jQuery.event.special; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( acceptData || jQuery.acceptData( elem ) ) { - - id = elem[ internalKey ]; - data = id && cache[ id ]; - - if ( data ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Remove cache only if it was not already removed by jQuery.event.remove - if ( cache[ id ] ) { - - delete cache[ id ]; - - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( deleteExpando ) { - delete elem[ internalKey ]; - - } else if ( typeof elem.removeAttribute !== strundefined ) { - elem.removeAttribute( internalKey ); - - } else { - elem[ internalKey ] = null; - } - - deletedIds.push( id ); - } - } - } - } - } -}); - -jQuery.fn.extend({ - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); - }, null, value, arguments.length ); - }, - - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - } - - // Remove any remaining nodes - while ( elem.firstChild ) { - elem.removeChild( elem.firstChild ); - } - - // If this is a select, ensure that it displays empty (#12336) - // Support: IE<9 - if ( elem.options && jQuery.nodeName( elem, "select" ) ) { - elem.options.length = 0; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined ) { - return elem.nodeType === 1 ? - elem.innerHTML.replace( rinlinejQuery, "" ) : - undefined; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( support.htmlSerialize || !rnoshimcache.test( value ) ) && - ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && - !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1>" ); - - try { - for (; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - elem = this[i] || {}; - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch(e) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var arg = arguments[ 0 ]; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; - - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var first, node, hasScripts, - scripts, doc, fragment, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[0], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[0] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[i], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); - } - } - } - } - - // Fix #11809: Avoid leaking memory - fragment = first = null; - } - } - - return this; - } -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - i = 0, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone(true); - jQuery( insert[i] )[ original ]( elems ); - - // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - - -var iframe, - elemdisplay = {}; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - - // Use of this method is a temporary fix (more like optmization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = (iframe || jQuery( "

0YwHazUo_ zXdK(lC{WQ#H5f{|>fpUC%?C4(K?CHD)VJToS2G{Qgs2@M?$*?O9Uhj}Ip{983!dup zsQPdjXQ^rkbk+o`hpMKEG2h+D-r8Y%IZl7Vtpluq% zxpzuTIX^C1it>q~Qzdj!+e_fACH8PQUO}zeI)oInXN7ReV#GFPWR~Z|NmR&u{>j>Y z!@xXD|2Mvjx5A(C?yA?7BIr8@%lR)X-dY)At}h(FaX)Mc^>Qo@%=8>z=Nhrr{gd)NFu%XOcy(l>i+bXY2l*z z-7>sne6tsZhCo<@;c+3pPVSPSYs%*-UNjjwV)8lYW!+(&><0JTC5oCA5TQwPV9#Io z%JL0CJqq)k6*ze0r_Eu}uw;XhTvDUTiliu?_)9i7J3sBd*)>#lBI6|PHv$Cd>p&!o z27eHKic0f(U@t5zDlaU2YghAhq%*Z9q@|&0@k(q(?1OvW`{>BgS`9~#q9J{FK;-OUB*}PSoH92?Ojb6hFkV9+zq)?Ti zN1ElK!(yUWsT`AIV&dr5y@0c=k?_=;h^!n8v#QJA7mAl#XChUG9L1)}A|)AODYv*8 zecqhK5ycp{TWB-N6y@V{mkp5e;^Dw9!n-n&^zPFitb08zAqhKO?0SVsc{*XdI67OMrrPk(-qc|iCIMnb&$ zS4HV~MuJP+%ijf;jM%qN47k3>sARcOw5)@Xz&LD|Q%ngo>x4@t9JN2&!iqO+j!@Xf<2k7OrK!S~^cw^b2dcE^hM zewlvil(JLKy|OhP$*vfY){Psj{CxI|c)w+4&iJNnOE>>xKKdjiz%8dq|H|-_;PPIM zamRAplzwOU>Q$%V|6&tIG#lkriK-EPKrmB-91*zBtqWtaVZ<-0H4|5pPp8NuF3+EoO`d3^e+ ze16~gCyrlVYsbvK7Bstp*+0JZ{)67a0wkrTj{geyC`=bgVEGmN{~2(}Qpv`}d+9b= vR%I_g-(`yxDKO@;2=hKJ%Krr%U&WuZfv0CVewgZ&|MPDfK6u@rd*}Td{Zfpm diff --git a/root/opt/phpsysinfo/gfx/images/PureOS.png b/root/opt/phpsysinfo/gfx/images/PureOS.png new file mode 100644 index 0000000000000000000000000000000000000000..46b0163a2bdce61ea801ad122a66861bb3b12359 GIT binary patch literal 273 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 B;4T0F literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/QNX.png b/root/opt/phpsysinfo/gfx/images/QNX.png index cb0f559fd253689b5808b77bf690844ddb10cc97..cb22e8383f717290e30526c65387a311e89518d5 100644 GIT binary patch delta 1125 zcmV-r1e*K#Ao>W9B!2{FK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01m?d01m?e$8V@)00007bV*G`2jc?+ z76}mD&thEw000&!6vxkd^Q)B78ltXTXw$?12{Ca&+;vM_xG=0;$)_9S$QOz#?V^JJ8eW{aljNQt)Aol zd0XlXp8Ocb|AYB50iX>%8W(qA9Uj6-mw!OFYt3eEYl#F@Xtt?xt4cr)b*f2V ztsY$9P&Z;N3jQfvhacca&o}UaAMdyX8kAZEB!MB0RMkR-yASsmzZw#t)PC((z-gfe zo1g@Kf^S0tF9Lro=MA4JSd@UuugdT)Z0bXU&?P|dr=Wl#fj+oC!MEXfJ;)@~j>8?; z!hf-@OOI!94Rp)aQHW?W zu5*9}<)jkaYg?Y6<>kk&sw+gSUOz%B%68?wrezP5gwy&7a#UV5-**ICG}cVm#&m*! zI!gif#Uz2P7FV!ijgOf(J2vSsXs-Csw0|lwS`DpWx%a+*ih%Kra+7ra+&7?r@AgLi+u_rq{BMCBO;{S%F)qw8G6wkckvk?J>AY7CF_@-V-=14=w1Q zo1Gf6eHHty2AM$DmZ??Q&JhVHxDKxlX63ASyS7HZ2e&E~O~O~e@}uH|>sRG^z+NjO zOV6D|(wJhwX5J(4I=K5!(4opV{LJ(J-(4&|>n}^vm_+y1QT%6flkW%S{M?ewFQ2hF rk(_q~N#it08mCFpI8Bnq=`phBe4qa&HU!(G00000NkvXXu0mjfst5?X literal 4217 zcmeH}&ud&&6vxkfZ)WmyVyuMv12v^l#B5yn16;KdF$q#cO~6eRAu5Vm>_W*ZaaWLn zNWuR=A<|9Jg`2wQMi2$NE0XvlRHI_rCeu!m$$Ngj_q{v5WMVQ|b<;C^@3}wDJ-_a` z_syy2jy+TDzPsDZs$-)g&%+0W&I;|x>FHHi*NM@WPMY;y5ZsyJzI)92hsQ>azWBi< zH`u?h?9wzv?&eW+^Gs)!Z#l4Y2IgFBIo=s}9lqakR*tqW4D#dOM_B(JIi_*l^VI3I1KfyP4?s>(wAHhE;xCW9OT9;AX>3QG@ zN24gUTAZ2#NdSvwkZ=-9Pujhmne^`Mb_e9KqS%S<#IRRNCK4Q2BF`0I0fkLThn4n> zUh+)`P_9&JTp`_-qXzE+6^vFvU2;%A`R@dE;Lie{lJ+%F2Sex6g}MrH&P~QyY0gIG zW}}DPKs6iZElPb6VptArfK4Fp16~d?fwOj?upZ=eY$t$T;w~?n7bBK`1($RD0$AEVq(KKg0?D?&? zYLAn@1zfQsHrPQ_f0kPU;!Zku1NnnZJLEobX}FH65mBfyzRWh{O&vdOH4KEu$4lkS zb@@#@}$?&%TZNV=zojyH{flNcOZ^!4Qqelz(($X zB9sFBM5`t_^cgOs>9j-pQsGWA<5o>p-`ydX2@QH?D%@4?~6iw zPkPt}q`X<_`3B8(fm%ZJ7*z2JO~dp(<<7Ls7mF##?#QR?+U>8dg}_VlrlvroP9;lIl&q&ffq diff --git a/root/opt/phpsysinfo/gfx/images/QTS.png b/root/opt/phpsysinfo/gfx/images/QTS.png new file mode 100644 index 0000000000000000000000000000000000000000..0d4406b8260efae4b4205c5e3b73ebb6f8e7b57d GIT binary patch literal 1769 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 z z8W!DL;xmghw!^MR+J!BPm5lZ62`hXD z7F^2$jW=K)N+lj>`HmYJ8aN^%LK+?g^&lDq)l?TnxtgB@r`>M%6V1)d7D}8)CYOtT z`1N;kAlUqbQ?L_fKuS(7o$PZ{O-&7XJRXE8HG=Ph2?1xOl8fp^U<_?A5DNp}e*O*N zx=H6jpoWEWKz#11W$el`eaH bh9de4`sb|rcLGn#00000NkvXXu0mjfRw%V5 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/ROSA.png b/root/opt/phpsysinfo/gfx/images/ROSA.png index de0a0b5753fb684f1e1314c5c0c5e50282419c21..eece93ca3988d09c249038b99529b8917c58f2fb 100644 GIT binary patch delta 3104 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 L>5l9F`mz55IF5n5 diff --git a/root/opt/phpsysinfo/gfx/images/Raspbian.png b/root/opt/phpsysinfo/gfx/images/Raspbian.png index 8c2ced53003ca1954e04b7f947127ce23a88ca2a..85e5ad5aa1b94c9bfc25fffad6279adf37cecf27 100644 GIT binary patch delta 2145 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 L-pCz~z^MNKIObx+ diff --git a/root/opt/phpsysinfo/gfx/images/RedHat.png b/root/opt/phpsysinfo/gfx/images/RedHat.png index 2092015736d4abb53fc3c39f3547c4163338d283..3bec990f0b2d8f6475c91c07680a64a0e6417644 100644 GIT binary patch delta 913 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 Rl$!tm002ovPDHLkV1ijx8W{ip literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Regata.png b/root/opt/phpsysinfo/gfx/images/Regata.png new file mode 100644 index 0000000000000000000000000000000000000000..81cd7f277173b0646c3bda9044efe2b65623b0ae GIT binary patch literal 2222 zcmV;f2vPTmP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n82p>sAK~z{rotIloo97wFtpsDo*kFtyl#Hy0 zbsABoR7)<}ExX&*khs`#Q7yUX6jm_7;3S+ehd@k7vQFBxL$@_;*Hmo+ElrwrUD|4@ zlq_o!AQ)nUIoKEs_>7O7?D)Uu{cOh{)akOk(ocN&JN%yKd7tlnZNcM=z2}|cU1$9V zihGyK3wxH|&DZ($`MRJlPZx+OPWxl|-9DePYgu2=?Y>yl?JOq_?9o}piQAui?CUgS z6rb~#7MuwUD0_m=TwMscr-P7pGyITu`Qn^fCcMZ=py+fvm7T7EU0sgSeXYa7#N+QrH{pSM-Dexu@e|PTuu(F(>czAg9BfqTK~~n=_c-ZtwqAr>!LM*#A9V`mJ?a z@wq^m@=VB*%s8HPASLcfiRDbpmy9ib#N%!?3SVqTiJo`+uIVF^y8&J*tYFD z7x)Eb?MW-8hj}D^vjK55w3wq=a#p%n&qY3!cJOYgt0KdF<}-lqhvUOAd*P&jz5>CFG|Vk6Z4zn3E^Pgp}kt z%{IuIY>+q2n~Pd4n|tC1=ZzUVdjkC|YjLL!>JP)Hy%L6~!;9R6{Lx|tPrM~-aia|{ z{?37y-*Q3RFb`?N928BneJ?b8l6pIed%UH&-TnZ}SlqFU#w#I=I-+>xy&y#GPf%_K zWh){1b7z+D<>V?luX-RnIY$9lA#1P%pK6*e<>Y&M>|$C-29onEZujEkKnP~<1Kgd9 zp!9+d8Eqs_NVkePIWJ?5g#77K3;4S}4C`_f+5rzTPs~DEZ{d*F&kQ`TofHd-blwAb zUCYkoJc}t~%?AO@c%qo~Msd@!ju(ILg`{t6Qp%b&n7nZgXRrG(<%-K0v)%}rE<2D}JI#r+j!$tYPE5Wd$UEiI z^P5cE;)LoFJ%9qRFgY>HpddcFw}OMcb{y0#;o#}T6x}xbsEasdL)}#`rko^Y_b_=P zfQCyHfI2RgFf^0MId0Mm@;cog;g_TGQ0XoMBay+2pIP7@q z_1ryCK-=$tP(8_sCAB7w?Bgb%Ah+Ea<9D~HnF6@H4By%VJct3YEr5v92?jgQ!TyiN z=sY8J9fKW*DQN9wJA}vL;vF>;#5kn26ET6J%@N~wx2SmuFTd%5!5)D(oIZ#o4+G$R zwv`Z7$>xhd_4Wb<5Em!Osu`yM+U-96Yb9!0#GyCbxJ9qu=;8+aREY@7kV=_+C>zP+ zqs+XhUo z4Xkc#E_qVKi5Urb@;tkCoytDrUdPbfDsEd=aD)rMNMgf7Wa|5Rfl_O`$bYRw4K^J5 zi<1IaqX5=1wzPpjq94-17xM{ILmC$887zR=RUG+~6+%@)e(XNPRb$9j>)#O+w$7Ey zno{p`X8k;V{$~dlz=U%H?obqgRqAf)GvInOV@?mqoOz)j57~yad z#-%kJ{^Kk%D&k^s)hM#6^bSSM$bP|hJ0`^PM(Y5RGbHu1_;#BWx=+2hJ|4ywrWJh7 zmSzf6Foa>JimXvnvc}}YKJ$d5xNf9t zN9Z1X0GIA8m_J>3zRL&30wP&&l7o;lYo4r?9$*jG^T)#Lv(_{`gM)eX*iuY`;RSFVC*lU!+AuFFiKulc@Bu9hLWD64gCl wR>iQMvc0HK4IP!M?(To~_^rqIc`gwA7bNtd@=1#p{r~^~07*qoM6N<$f*a{jga7~l literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/RoboLinux.png b/root/opt/phpsysinfo/gfx/images/RoboLinux.png new file mode 100644 index 0000000000000000000000000000000000000000..658106d373cdeb8f63be97b70bdcb853148e1ac2 GIT binary patch literal 2196 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 Z;~(!t<2v@?+Zg}=002ovPDHLkV1hR`OGW?y literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Runtu.png b/root/opt/phpsysinfo/gfx/images/Runtu.png new file mode 100644 index 0000000000000000000000000000000000000000..c410e6d9a697e282550f3e8df4fbe006911c766d GIT binary patch literal 1704 zcmV;Z23PrsP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n81{q02K~z{r?N-}Q+hrK$-|^PO#F)4&UU``F z!f58jrf$Z~i|$^7fLF z?X90)xYg_F_WEwBoiX^?wnyOA>LM!D3^uny*eZlkDlQP21Rm_u3opRRmDJ&SJ?X4f zV&1G`i;c}7$|WK~84*kmXk5-_qzM7KwG~AE zp8t{mdm8~1wj-dFB%P&Fl)m&+>Nij-WszQTVr6yy5fNrwF2|bXsU}3~2;eDF0{y7-A`qH^&80^mXoO+T2-Tzx z;iwgxn;{7H`;CN?)4j0~L}q0ktE+x0Ng2gb4vFME!V!}=>?|6a6T~trE;?@Hay~(h zpA4ExQ*`tWgV~)L+!>XjU#WspuSfg!A!w#lA15#VvwdC_F=;TF6v#w08~QO1B(iIvvh-NYQ!g z4*Y>>;g`X=326Wx6JX=6=W-MZ5fK%?91NS_4cg%jrs43Wp`P|)c-#QVum;jGEqdi@ zI$GQu(xRhViOXF|+#FCrrB$G_rx%}`{*^w<3EUw3ar1HM8q|9&*r$z~sa9R2#*Bz2 znF|s~d&Q(22%OccSc;3z4u+;NM+7>1MsWOxP7x(X z>+$NvZwz8}Xkai7;O5{U-aU2&C(d3FB>8s^f(5DN`uWyqq}!_$eLn9O9qw>VKs7Op z&(3yZL@C9zNd}u;ElR`D^F+*9Mxjtk@!jPiymjO!eE#+Km^2KC60Ok4a@Vuwv>={s z+?`x|RwZ@cm4(TjNF z&B8QA71?}TM9NX|KQkzU@J&}N#>7nT*5bT5JwDYq zsa#CREJw!x{670;5n}!4!`D6&C~VVhTBZ!})yhl4S~i6J{R-0QdC`C@ovUjex-tXe z*5Y-IZcW|;o;yk`wat}_wxAZdCb1?t#^k^G`?ihEFl{SQioA%Wj9V-t49x5+6e(ZT z2U4(S7?a`vc-7k_Qex%1pLS9PD7wZ@D+^u${P4DV5x~#2YHh8#v(YljPp;#ie_OZy ySL0FOM&u{2=PxDdCyfE=yu65C+pA@5ZGQn9V*=XgtS3L+wC-}n9ZAKrI*)mb_Q%^!Zu%=7%8?_Iv{ zedhCIl~q>%q}sz3-axc^T6=$aGoRgEk*XlEHGD5p&e(>jJzVY$M*UOptnP~V0(|do z>n~qR-Sm#|!halNORvsIWi4ETZ}0K-bX4=Ywh{z)Uy*@4(h+ zf-QFN0(f8&;tec@KQlBUHUb*Ky-hbE7j*ktAm7*%GI<}o09*GM#*y?bb%J8EsY@#I zx?TGnzg9C3Cc&^tyCUBN?pRF<9(4i_p}_c43eRMCZ)(JDlS(Um`EbXnJL3sNYoboz ztnp?P-hb;(U7rbO6keTzcwHdsAMosoEg7%@=rO*G!rSN6T{Yp1!n?=Tg<^I0*#Upp z2H>3Wr4>Fe9Czw&n^Z>OJz?t@`<4Pa|Mo(UV2tsm6}~M_olZruNu?B?k#N`4h+cxe z1}7j|jX$Z#>lElAECIJCXl0pB!8*q;8WmI@xPRva--3>2o~cWSn4aSGpa)44xeT^W zli3D?+bklcK2Q(psMfFD9%~KDKwZry)d`P485BYhR6;Mvr)H)29B_}LI^lV!hN&P= zDfEEb3FT{!4=(XTt5GL&+p*B9)MB5)(A;TLy9qu!aUrk%2h{D{g$Xq-we-Qai-6kf zK7Vjml#17|)zs-kYyfwAQ=y&JZj6o(noK0MeOEw(xU1Gm^bdCdN{u}sVtOA?Z_q^C zRqGnMWf7=1_VnrqSL6gDRVBR5tO~_yTZ6GhJ9s-<(G{&OCYSP!s4cv}8;to2@h%U= yYPNUB>UQ#$)W{pvjE=}(z7b`W)qf_B=M^_JIa@vidL~!^0000$;J_6Q zNE|qD;KCKe0r3!s3ppT^I1q@e*j6@jvN9X*X0z*^op(<^>e0nl)3dW#%Tlh0+M2)r z{_C&r|LcEL?@zz7@uhNbHXwwQuRVYD1w0?oKhFdeOWj}L;r!r*jj!T~@!j9JKgYxW z-t#YgpODIR{WE@Xv9e4^c=6iR=f3vC_l!rv?eSFkf0GQxJD4BqoAI$44=5ZCZofae zF~~Yvo+q)00vaw^S6Y=Pms;%yl=1oy1H;XK>gdl%`_LqtPO|aN~5%WY4EfM zNy%+`hMB5d$+*YIDeJ-#%SMc34skE}-+91>E|Fp+J2$iKH;5nF;#iL z|CEjobh^-X8!NQ^xMSNkr8tCT`Fk~q4H;4MZ6{2gobXewmv0?)j}8v^3%NFs^!CN* z{)t|x3LfVGg&9!Zu#rzG;#9_5_WS%U6Fr1}p73ICl50PX{LS%r%*V4@&>>>`+lZgV z62`g7WAkViLPRMOLU668X>I`#r_e*_{zQ_CLPDiNQK6!a2Yks`p*qb$67{i^r6U^q z>9N=OWCW8U6H@9R0EL*oMwo3pDO1Q$LV8K1X+AN@g65CMEXgQGN-7AH%aY9TiA)I- zsMMlN{gE@MilxPqgN^$x2n%^zZ_OQ%(ibkwqrR+ zVe7BAUi$FpS;O)PT~O{4CKzqZ@^J{@6!e)#-(nd%WdJYEGcOum_?N|R^n-I}7wq}; zO0;PkRqEJOALy4i*01lb5e>SEsTmXKz77=CHj1%s{|=Q}^z*FIS}UvfE`Kwvt^qo9 z%}+Gla}~Sk+7-`o0-dtZR@Ac4dOv%;krU?_>fz5uX&VM`XJC0|0NlU#^|gc1aIK{U zd;N?XxFqyU^jheg+=*Q9KfRGCxr<3SE{r|`tMW8I?gLBYrpWtogl@ngW(MvL**H77 zRmO?HEbM`%C-_?S`*$rPJHRCDKmlE%g>{z|RO+jCf}2Xl31@uP2L}TlG39U`rB>IK z@$_?&5ZR9y<6_KIFE@!qrRZ>NjVw4m#ntGN_u#%I5;!R31n%R`%7h8@%*ba3@;GIj zvDg^dk_&-Y0|?A85iFJ#W4<)d(2$Ju7J<^tx$b{>Jwul<&>?~Qpw2WLt}C2a003}&U;)G_bpNNA0C_3D4+k-31Tfm)r4abf2{v7?j{B*Ti zt+X1e>yN^~sRF!yWAi7k$s)s8!$4RH#{rGkP-QQlxq~m~v&*kG-Md9Tr;0l6H~Sl9 z+ifg1TC2V?)6f==e zS_gpfXnjddR0Xx^Vq*~~MQ{rgI0Oa_ zW!ui&>td;(4>5oR+#%68!gsa!g9I)E+AfzKit zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600r7fL_t(oN3ECJPgGYF#{I`knXe-Dq5_d zQG@~$%0;dY!&PoF12|k91so9M7P+++ij8J`uo~sYPwgv_Us4G#r?3nGAfbLpscSwR+7l$eu+Jc%KY3jc^Vy7 zq^GC7e*u+M#nRLFP-0WFGBy;J%F+^vPS42lQcPy&Vmhjb$*A;pw#(#nSY~Di|C12U zMH`*%-4bXCs^Le$pyXwpRWVbO5gD6^C^?=_jE7_8$YkGu z^fxrAh_AlPkldU+@m(p{U%=XWRE<$^FQZX;P=Du_+diLUpUqOQFiePT0T9`9>VO+T zZ+H^zlGf@PjUXaO1qg+k91$)7FBgXOnn6zZOz3Xix$G3(+QzCHhu9&Hi{fwA5o!cr zv;1C>wE3%42+;*NWH?;{00K(lVMB)k_gphZ2#f#~5f@;(At^v8YsO~2FHde3 z`hWBqQ(L!g6gqukkAUxUzm=@a3^|>a>KLFVAm#=@^kQj6PMkK*k`6(Bw1FdS16d|G{r0C4{JCNoRPwbR9kZ6T0M$No0RhzQ6qY=}t}k>ZZi z_1MQdLE$2hE6P5KnBVsZ=<6BKO%Nl%+;?Ce8NA{!Q89ZlSmm!)0gJOU+P--`nUf;Y zf(S+8vDNK>lt zm#YB0$0njVPikBOP>Z*0L;z&GfQVp?_6)(3?p_@s#TZ?UJrIsGw8+r?W<{haplb-@ zJhpMrI7We|o=kB!BJMH|ktrB9LX20oasFnFVk12WL74g7AlwqrlyI#fgnyh72Z{Lc zW1o0;Lb?=2IgAn8XsEW)F^-3bAkzFuBACZ@Ph* z6M^yme*NTv03t(bM6wT|d{xmIb8^4a$B6Mn@)36p7<6|wYrgET8$$-ni4MhuK|ax_ zeD)i18`z@oyc&{g0x(A2A%Eg9Mgj9^uv14o2jrHkMFA5rh!AJMIWv+j9--ZQt_k1s zdT-<28Dc|jgIhpbHWhvJSfX}7))7q<>_{Mj?@PY2Z9d?dAb=v74G$|ZhaogVFoY*u zL2^&6aJB3-P>k#|9sU z#x*hE4fn-AMhPwdP|)poWcWDs+Ha%m=POzlR6TXVO(9i>4juG7yJz8jfUj%XEFe9I g^4eEXUw7ayv1+Xj6c6$oz5oCK07*qoM6N<$g1e6hYXATM literal 2193 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 diff --git a/root/opt/phpsysinfo/gfx/images/Sabayon.png b/root/opt/phpsysinfo/gfx/images/Sabayon.png index 8213c2b35868764bfe0257b637027e4cbef56302..bed8c2a8e04734618afe4008e1c90969e4854281 100644 GIT binary patch delta 1293 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 delta 3898 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 literal 1925 zcmZ9M3sjSJ7{(uiOe+lSP>CU^5!ldHw4nzol1tFp;44?42b(~dLz0UKNSJYvsT*=p zQq%}=%0^#5sdEWod`L>hs`OxfH z%Vzt4UYWb?A^@8~eUt92+?V{K1ZS5D^y}?=R zu+)M3_M2}xavk4!`yIX`--+k6oWE?j({kr!F7GcZm#YgZk}Eq9|^p%`bVtE z^q;UHB69_4p z`^DiIAw|z`C|(_~3L8}~gdUr{L5c7)h&Vgv>*I)2W0Mk_$}BdXz~)j!RlOWmViHw8 zcjM``L1IMLScacOOvN*sD-e5bdd!(uBb3-u8T@6?^U>$#N1j4l72+E4O|@C9+B~Kb z@io|5i*M`a#FbfWsm8X3^&wy3yGA6`y!1^463)+!KZm5+>4_TCf0)$ zG(*}jb9+6cE!c71EV&6gTCr1uoo(hRjo5V&vI~%DBQ}LY-htE>q;|fvLxbHqq_-pE z0@8JxW1>vcx-54!A+s5o`g!t3D_Qf?ncAoJw#3H8Agjk_x5jKw=W|(Y*mni{yXWlH z;lO1a?AW?3e)hh09O}iP0UR1dP8V_v^Y-bHdue*k5b`dYdCm`<{4qwIL>$7vO z;mDYD$95FlMA20g{$zf{fa2>oHu#ES2*<~8{EjSj7f#$l$w+FN9LiCff>E5h57q4j z#X~bxW3!aEar$?hxr?*6_GD#3ec$}_O_bk8#V@EBw=BJj%3t?oe~-!uRNX`MYN z+B?%~$1N+ytjq48?l;umJ(P2BM&0iwjrSH-{`C5}U!i&MV_puL#?2chI92z}G{2#B zB43ebabXx7#c+vce z>bl%}$R{i<=wq*3UQTUFdrBV1$mD;a;mY0kay}XId6#);z$J zBBKmlc!x7vMR$xRK)HLrFnv{txh++}u0` zq`1V*i7esu-vpk~W*9%eRP0h~!fuvTeOHZCG%nu9Hv$Km}|4g7+AGg`%awh!jdB;s7=R zlL5hz2WUR8pg>tyS5w1=NF)^D>q!7@Kml8_vyUkXlqyxTMq?zx!X(BmjDTNoU?@9J zzN$yp%o3#$(UL$hM>jReh0VlFxT#8(3hnqpg!A1_sJo$yQY;ojoXkLx7i;mw*wAC5n>5 z;*%tKdb(Vmks)=aJ6hY>*uculYQf^S-gK0Nh9@N@Nu~a){r!bPKFvEU;@C_AMuMus z!o#DY=z2oxH~JJ{OfY6p3n39<9(=wx?Z-Ong?NuyQ@2w_AbTYG!kMb=OJCka+7edyKnWf(gS$8Ktxjlk{4 gy8BpD->1%}bY-jFDE)pd{g=So!^gd3#oEMw0F!z{bpQYW diff --git a/root/opt/phpsysinfo/gfx/images/Septor.png b/root/opt/phpsysinfo/gfx/images/Septor.png new file mode 100644 index 0000000000000000000000000000000000000000..a797ba67f8c13cbc914fd550b81a1aaec8702170 GIT binary patch literal 788 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 literal 4217 zcmbtX32YSC8UEhP&g|iHeJmIoOvs_CZkx7{Ac&xLVk<_i+%_U^QLCs@rM4hdqM#I- zCW;a%k&sZ;q?g(vB}hp{L5iv>hpR?$nnZ}SsUjMa6cR#FFc_Tp+VzfSc4l6`f9$2Z zUIUBze_7LilhDhP~^cLYqTJhjuJJs*$4 zg@_h#ZqTx+pfE?_d_n5~c?Lsc%gwZ!hImGR16jw=47e|$O{A?xbje(4t018DN6z#Z zh8SRhsSqOoWKoeoF=#|NLE@w5vY4vxz@}IN4YFR`!&lU7x_~TeLXI(QD*~~Cfb9Cm zvpA5wh?l5EWcqng^S|O3af=X&e8hfs6mIQGd_k#*EBpm`28q%kTImvg!Kz<_A9n9o z8Lz>?itNVX&kHWMYnM-#LiA<0IJXOyCp+xeP`L2T@;H zfNjyYG)D{;n5{@qEyX}JM02{Yj+ST^>J?Q6Xe}lq}x7^J5&-D2?VUfls)fjL7+tx0hIvKLX9+g2Q8EokkUq( z$Y*gjcN||F`jMU}#uRSm8^5V-#+{7ZIL)USOaTKZuiN4I0cKcwB@2|NqU@mI z=d}|83mPgGrWS&?5j;@}T>4Fa*mljl^&=NZ9bd5lJ8N4pK#-(3jJ^(;%UT$7%w$oq zm}-J0=TMw+k+MjXa~26(tQ!fAwbMGQXpJSoqs`p!Oye)-|A}dl6+MI4xT6HmUePoFPaRMLrJK>Bm<;;=K0=eaj3 zJ}xD(&YOIjG`pFn>x&P^Vq|l9Z;8Cf?BWL7Mss>4_N?f`^Iv{StuI|u`hD2~GPv&?YC|m6}+CcLMl%e0csC242~tPb^+rw*BZ& z^(b;U#C&F^E!|{8ZVacr0`j8i)tY!wV#7$`hV*B#huOvuD{o~4WXfP|yOLb-ZBW3B zdjTiy6q>HIt{fuD2o+0W{o3zEx2Ce`3IfM@eF_|$S$qmbU_2pbM{$U0F-jLnxu~j% zC8$-%G+r#WGLX)`pr@us@dS@LS2Cga@MaS@7jQVp;!iFKumDwsFIHo5(uGO9IC21& z7BjA}0K-_nbe}#r^&Yn8bF@Z?+58MnWlvz&=pXQ1YM)UK-sW*QyI7d?1(5f^aDlk? zedI2k#*=@43J>vr5HUtsE6aki8Fn^qRLOtMpy9SwObrifW}{MHJ&4`jMI5SIi)Rz{ z*j$<^QbMJ)PP~ub6?~kH@iKdI1VbnH>whnnUF=7txY$|zK6;eN#?oCJ-*ALAK8Co} zg6WwL@cY=UxQ&;9q>zwwqk}_d6352h!lOrj#*C_>Rl49Ro8sfd33*Or5DfhQedk~ zaN+gg>-#_Px(Fm|sl5Z`X6K2MgrwEEg$LMCLHU{k*X4p2w`iAH@HcV6H6>TM;Hp_r drHub;+1kme?H{Z=(JVr?^bPbrcjtE={V&u;1}p#o diff --git a/root/opt/phpsysinfo/gfx/images/SliTaz.png b/root/opt/phpsysinfo/gfx/images/SliTaz.png index 8dd42935bbebec3d2cbe2ea820bcde6c5bba8765..3fb1aedce208fc460531500c2442d4001289da0d 100644 GIT binary patch delta 1609 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 diff --git a/root/opt/phpsysinfo/gfx/images/SmartOS.png b/root/opt/phpsysinfo/gfx/images/SmartOS.png new file mode 100644 index 0000000000000000000000000000000000000000..459283ca0e547644bc633d0dd647a45b5de22c24 GIT binary patch literal 498 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 xw#rU!>z(U-{M{JNnD^^+0Dy!50Qvv`0D$NK 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 literal 4217 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 KMNUMnLSTZYKGNy{ literal 2193 zcmd^){r=v6&U-Q> z*xv-if&c)R1O^a7;nf})#>?TEz&q6m0Ly`pAQBNi0?Pnna0TAP+RWV49J01Chp?6= zj+SQjRyH=a)^^qob~acmTYCuWWN8OkVR5T)SbMDTd)6QxyUN)L`!0UvS{&-l)p(D$ za5!hj4UX3MHSWHS7*8k6nl@N(?dK`Lf`*LF>jXmYOW868$9w*AD zJG|qVt_k@k_u@Y#M{P;UjE$$1kR90Z>q&>QJ?O%1N4|@omRH7OeA0MFlOumjbpGN{ zat^$ARHDAeP1p61r9p4J?{)2!T@y!f9_2ZWV%|C;ML z_^oH(DIet-&z;;GX(ctL_4>pgdOsB0wXYj@5#I?A=sFAcoGbZ0joZd5kzXtHwQ73O z$ML;&cI_-1AANDKr6ht;U3x&+)mfbQxX@iy5)yT3*rj>KP~MJT|50wQPirsj8 zo~GPiU*g@(%~0@;e%z+lbJq>>Vt2@Y_vv`5zOeVe8$eN_i&jgu*jqqRbz zp1uV#f&PeKN54TTzuAH2{6gpk|$wYl1x#!P^^-;GP<0czOGj(KY_uRAE z7+oWS-+p;qvYTF zW6H3MHP=Xe{&V`QG;>H^mZ_eXDYS;>Q=Q6=F9!{RuHk8UX8tw9N$vdjFUNlBA6IpE z^RJJ0_jYOfJ32M@Z>SzTQE_W;O=zyGrw4iZ8?~3m9_dDI3LZWi9+~RCr=J|@8NGjR z?m_3+#FGKT+@0CyzyC2iKl7Wd&%qGn4@eCS4g(hc-vt&KHp9;WiWaah1pqJ#WGp-D zg0TYtBbPwJR#N)VGJB(udF0Jlsz-fljc#;wwEpFX*Vku4jY>D5QuW`id0kjKJ?U4e zD$`O^b8|VI^m8-+Vjig!m8q$z*@(_LoSRF3{yL(+(wdgG=!XF@J(rWsd5w6g)m9su$n=Vs8dNeES!u9d%;88Rt*r{?MMoiNml#<7Qfg*NQF`TSIbZHZptJ7(gE~?eC z8EhCRYUmOxmVnaIA4$J7U0;k?&<-OFiq7*ZDykH%>cxQ4QYJMvG~-1NI03ewui*0= z+Pf4Q&A@ln=x9Y`Xs^YL;g#x4O1ZErv=a*w(ek%$EY7HC2k zah;dDTP&p-X#rQ;MwG{<7J*1mz{*Odp`q;r2X`+w@0T6mYt$Ko2Vpylbu2kK(!zAR zGtSG+l@gcv!Vk|=-#~URbXrWLC4|SAy1IqG3V?}sS6Xag6~O+Om`KoU+uJC!KuX-i z-vNLx@X!d{ltoL9iHO`~Y_cuD*>ri-D;f9!-bb0C5)nTPKwGxwtgvu=1aK Iv~54*FKa{${{R30 diff --git a/root/opt/phpsysinfo/gfx/images/Sparky.png b/root/opt/phpsysinfo/gfx/images/Sparky.png new file mode 100644 index 0000000000000000000000000000000000000000..6e58344b7df73445f7cd5453b2ccd1671112454b GIT binary patch literal 2312 zcmV+j3HSDiP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2%SkpK~z{r-B)RF zQ`Z?ilB~s+7uguR@0Q2L!DcU|EKeDlGGI~@2!TRF!i16`6euapGLuMd8(`8*(p`B$qTk+%aSF_mSnB=>wT{-slhZfli^3tjOOay_jJE= z&-Z=jKH>ig^%cjcOBW7NBbSd3rNw{M6#i)ko0s z_WWfRd#Un<`qHIZG&I&@&5FmFRjcz8un`oV`3%9gdIGkqu?)CM|=I!sOlv#`ar{Ej{M#lTl+GU^5jUoXHflR_Lyzj$z zXy#%AHO#VTZfk=~;=|^b))iPScD(k=CXLZ#!H;I;sD*@Y?Nx0-N_-?HPfA0IGJ$yz zxo@_14-OvM$M)ImXuNV6`}Q9d?BDw?t<`o?+%I~~y|}5pj>qTy0L`sN*!!Ir9v&vE z2{1G?#DC{LEI$VX$%BxTFaaT9a%OsNTKTfo+wZ1y%oLCuYgmX75D);j$BQq^4$}IT zZb~Q=qJO}So4T8bj*3HLV=J6?7epcvSfYx3U;sw53C5lt^jb`Cx(DDJcELr)mey7@ zHR-8}%B$*%v-|E67*l~WrAKI!#Y_2oKG0`RVd~_muv#7b?kcLjLR@qleEwkwiPlDw zi3Il{IVm2gsmT~Wemvr1BcTWaBa=(Y$AyJKDv@AFEP_}pW)f2uj7r7W1Wp}h&3!&z z#*#awfeA4#QBNJ#D^QVBOrDmfYw zlF#YWG7y`PhHaZ)L}HYP`OT|uVBl!R-|!2NEfb-JM8IjD^$bMV2xO zmVQ4`M8fEsTa&Yu6PUO}B}z(8CEp-!*lX@Vm?Dy|2WgN3q5uhOre-wM*W&_Rj+nSa z1O|sc_tc^pg4_#6cZZHLboF3De3n`w3&!B!Ai50g$V`+mZFf4$ zt+v7Wk?|8Lxs*ljq-a%&@+S;WfRp}4tCNn7OXVxyZ0fUFE(>G^ zeG)1yNzT}8R^+ePI_l7=EH9>`V<%EoRpkf|W0`=U1j^?p#Y#4%zgdHqU)jOO`uy*I zrrXWKltRuj&#v31;=3R{_os}>pjSEUHr{;V5)vSfNJY5JMa-oi(TUj*h-HWj^)foW zkqRJ&bT5))-M+r#w$JXzQ)$?RF5LS;nC&}o~{ZL$$>5E4~vn3j{uB&Fq`qwQ9CQp!a2r=OMLnWb}? zmUbUyB~{;WwF+}pb1@{4^S)4BaSprwuzOUz8#TwM`v`D2@yQ3Yd|V2ZkdVY*2NE*F zL`tbth@ikgBCQbG<~ulYU=Q*at6(ttL6X$Xv!Mv)RLeG#K*@YI5?QtF^dj^fwWZ(!~z$l=47F! zz72y;7kYZS&}Z|I;67s2UbtN@L`MV`7>o`zSBRWJk&*L&ZzsUv$)`7Ibhl39%;^gC zg)gf4qg5=CB3LfNgoq$wy#mx-X@-!faa(sAIXOy_8XsIFu!lG(cR+=NgfNP*f%#64 zhZ-Ul&7G$A;=UAU8%i`+8k%5ty4AJyP3Y(}^Q|c+-NE_0NF?M7R1`oyWaJcyiVnl< zS@VbzZocYo6YrRk9gS_T{ZVl0M4`rD6{>45)A*?9=zZ}Hj zXUUl)B%^?w_hd_aPY(}^;1dqP@9?6tryJ8JD=~HIOqhCX{Ck08&fQgxNc%K*_ z8IGnq?Ff>ME%qo)7A$%}uzd0Cg8aN6A}w`1f^>O%*mgpU*5@x{=SdLJ^40J8j6$O6FtSi!r<4-)L_+ zPkH+7l-Xv3d(cCwKY*MAGK4D>O!8xSe1K05y+>cW)<*eBk=2mmT)%b^^Yis@j&jN0 zzWGabN^V-gl4V;T_+IdxK>i77)Nj1XZg^oGOU;|X9zVE~9=SCN*Q<|yzkxY)>CRGn zckg2Jmn>$Ve(DLf{A|&f!M_cpy1pBdQd0Mqo%P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd2Cqp(K~z{rwU!A`Q&$v*V-cbPA!G$X6dV@> z(Fz^KrAEPhaKWvPQmdeX*1-|bsyMtNmMSh4>uANL>R7k2h=QP~0RviGMyqv1#RajT zwbnpL0!hfwhSnl!T z2MX)owrz_S#wh3dJ7Zg@7wnaNB#^q=o2OQ zW~3NX`$%zdrYpLO1sK@d57t+0)12GzxYa}DSU;sZ^gH~Z+w(EZ-}_)|xC~2zoG?)A zhzS$IIP2@J--dOTawC0($c**@j*kG&e1_bOb1*-AG{y(GBCM}B?CtGs2M``QM5%fC z3|FsQMsZ3oj%;5E7&K&B^Ah=(Ea{a~>Tq-(+rBj2El9G(MkyCK! zP&!twS^+PS6TVwD%Xag?j>qFpo;ZSxq+WQDC&#nGKx|14#qNxCh+md~ATKEveLmK9 z09(fSap%?rp!SR$hTq(PM?=ZPsJ_+}5uvW=y6yV_I zWcW!sz+K44r-}jlt)H}R3k~dzSCwVZKDmOjJPws5I|0p~fKiK@=T9-)-wmqyosc+6 zfW3$Iwr&>2j2@vp9>1V*+107Zzb5~R#Pwu4nCkRs$V@`T7ao|C>#1L>CYD;P?(2fJgPd_{HV&jaGtq=R8ySjr_B;&fDnR-iPb`m%dCyYt`HIM1?eKLX?fLZ@ z$~*y(Z;Y4;HbJm{Bb1Rqt7)m~V?2;O*Bhx*dZ7B^8l!c@cWY52ht=@gI>4m+i$q9( zi5poNSSFeP$o>J)(rVDcsIJ07UuXOr)eDOha?Bjw1!}e0$2#m=H%00&AB-LxNaHdQ zCcuPQ7Me;y#`?4jEx(gD6Kn&mlITD=ddvBk*hh$2gWYiV_VsrwLu$-e_{p5GFL4PP ztkE@!ldofCAa60274lXy>lnoE(8SBIYn%{y(Va0R&30pipHv_19_7l{17Gr6M7sC9c7~E5W$Pr#|cS34zrztA-b>b>dk5THC za+r%mc#$haTzFUHpUbAyQslJRG}fG%6{rb-o^>U2@I1#IWyyhv9^4Vr26^CMvJ}Q& zLt4&2)e!;Ag(Q4Y0u;%}L@-}+$FVd4t!oFU_HRT36VecfWlmT@EUSP#WyE-WAu3M@ zusKSG%jx~0+Tab{c@d1cyp{o~vps=gDH#J00qopo{a?g5{FN`ZkC34(XAhkPYz{PA z2?Ss?5rkfg*B7Hulk0?+neKS9-x1ZPooPHV^cP&9Q98bPN36XvlY|MNNc=A=KP|$_ zFkjp+I!Rez(OOr8r3_lq*1%YrgHpOHmt|nV({g^?pkDEZK6eG5$Is z!5du$z(U)ON*=1cfqV)p%s?O>Oa9 sPhBunaroP*$lf#=aUm^TMtHox0UOb@r1a!~x&QzG07*qoM6N<$f-3xK!TPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1$Ie9K~z{r#h3eUQ)L*(`A7W0zW@^xG%*Va z@e(6=35rUlF=67u5D~IO62(M_8oWnL#IPv30b?6;W8I)D-MaO%OV`U;Z(A?h>21BN zUAJ~Ow()h()0{)wa|(tZ;D=An$$QS;=hNqX-se5r0pPKsI`}A&Z~kt&SVlfGkGMF4 znQ0$H|MWu>4)_t9i=uM=ssh=?3p-8t7X8v`|DrmFE%Am19m&kKcMrOniOQ;H@q7h^hbFgn;&j~Jk zJnlu^SOCXH{LJAI5yy-n95zOo+M&53`t&{e7gYJqnt~Wl^8AECfKp#r$zv{;#?QWK z9GMVgfkUHyh9v4tAsjSDIPly02o4U$u}`1m;QRVBMf!58G<$MbEaZ?`NGk<+aBBnh z`6L>**X)Gd#u5ZcNRY@^&N#da1!OlinWfEDCcVCnbYY8$uWsRXcnyaP%d)_6Q=Xq~ zY~4``PzLT|6UI!IgP(NRWr@;EoSO{ud;gch`X&b^fd<0@qJ<6qp$Y-ocJyF0o5FGD zn5x7FW*;1j1$pw7jk^%C>#(JkVVN&N_w?&aB{bnxJg3Ra0;(BEZKr;7Wf`Vaj0Myr z-W!=ja%Gh#UE2aWXER)w^`=-^VICPyv4|vKj4jIo!EAwRO(8(dB9~4=7Y^c-%Yu`x z36`iPK&k!S9hHl+bXQPuo_FV2lHMIitgt}+?KCE%DfL}IO@j8SX4;M8-Vv7g!ev9t zOb|c%JuFdcbs)92Rwh8pLK0M%zqsdFgaqiGmPitKS(9M_v!@tGAs}_XZr3OpJq9#5 zhq)eT0{Ycw+#b|f$I1lG`$QHfEzH)LCA_5*6#`U*B%rfSavX&KwM?togbte#r>6#3 zg0>hUU_ut4U}^#{XyQ1ajic9Wg>BUGV1ZBEx3GMtSk2W0e(*<7Zx+e~ zdg6K1XuZ57(%TnM^%8#stNoS6mZmLE)$@RNribK5SImLXYA~< zq0t^L6WGx%Vt3CB3#ewGv<9jPP+dp@v^-Q7H3LH|A_-iLWEBFm1W&XFSfFYR&@Lbe zZ9q^6EUXvs>+JR}un%B7H_v1Aj9PZ3Ku08joxN6kIv$d@VRt0Q0Jj%9nqu4ILP%;D)6*!9MASUd7ILbyl4pGnHwJL(T3od zokJp}(g$deI@EY_N>zZyYHi)jfl;jtNn8j_l?m+Dnefu>36|K^E6D8E2M|o9`9xF* zNT;DS8^Nimn`rP};lMO0opis8qj*=i&RHM{x=I4nz9oUKaF_+29~eMNIr#gY7Q|L_^2BuCk(k1@m`A21>X)09L~AsRrv@x6P$@wIbQsZl3IRF| z>47C1kOlsVn#(4C5L9&3zF#v9;dMhX3&bvcQGx`-rS3Q`UpbXGQqdnxr=e{l$kRXvpf49t0uZD}1_)yR>m4zuu z>=`ObP+fd8?&6PK)on;0rFN%{yHuO47bjfBz@;LkyyI!(q9pbUJzSKpOxzQx%*027 zW@s%IZo~9ttSUg?1GoBbLeqI2&9~a{li>=!9j?w9LpyWY(1o-5PUcHpkIZMiBWs@Af({;6_5~IP8PX*wFPZ0&1k>eQU;CP rkJ5K3tI|It5(zsEhg z*FU_)Nww`ZzRg0q-cGmNJ-@xQ?sOvt`kz~*Pb#%R6kf4sC# z%D-H~=T^zOTEyc^&Ahd*u7tj?W5M;Uvb27|v0%p7Yr*eb$kSxS-h;ucX2j%F&bMgB z(rUx%q`9kT#pQ0q-dxVIh{LB`%+Qa)r(?<6Q_{3%$l+YizhuhXS<|7& z)_&Q)y2r;mOa@&cM{+)zHqP z-RQO2)xOu<*U`|O;oYU*-Nx44($vwQ{?Wp7KspR6S<<_y{ z;;rN8+}GBr=+eO9*RtdAyyD%@-qE$<_pRvJ-`d!{;`rFz;NjcawC3}(>EY1e=i=Pk zyyf)8=+MOF_2k~&&*bC3==R^?-qYmj%jwz0>gDF)-^A_i$L`$6?Dfv-_2K5}>g40k z?CHtw>dfxr#_;6j=j7e$>&x)$-s|kr?)mQM=jiI^(DC%w@ATd7^y=*C@ayU4@ayC8 z@$>EM?eFX1^7-!Z?e*{OiGEd_Verc`S1Dk z{Py+q`TXwt{Pp_%^8EMq`~LX-|NH&=|NZ;?|NH*`{1#x;tN;K20d!JMQvg8b*k%9# z0+&fdK~yNuV_*P+$ESAeMg{w?GC;ty9di~eSiWF63Rp1bFi7tC{{6e=PoFSh(xizK zdqJQb2zqDl-+c@ydEwTPiiqH_us|;t7c(2n}|4t{RCV}+U z{zHJT;gSw7{xCfLb14NZYk%k8zn?eHojrT*9Z+@~ufvPq4EMjBOaaR}zWw)WRiG!( zRqp5h{X4|#aPK3-)dySha#A3YUmKk)fG*bR{PpiBukrC)42Sp6E66Ke)RW}<0Vrwj zRNCUA)$;S-Q4!Ccb9^zUs|C{VK79_XqS${Ma>M$yC9O2qk)objx+xKTg8$Alw{;8 z>H^sbk&OTF?^~5b+rNLSL6S$Axqx;a-mwfM`FUE<^?%>9K$7cOV}JeI%q+fm2QX4L zfhC(<FKKmPQ7#{E5S`rfzlU80{ zo}HN)7YA~cj*hIfaQdzt3=Ffn>XOr9z#uXtB*4`YEURWz(+o_04-%|A{Cpt5+1bw8 z+Qh^}S6AQGsveYZZ(DJI0VgL1GN^~9`6X70GV(wm0|h{40w_rX00#h>m$v$w`Tzg` M07*qoM6N<$f`3+~{r~^~ diff --git a/root/opt/phpsysinfo/gfx/images/SteamOS.png b/root/opt/phpsysinfo/gfx/images/SteamOS.png index ed61bc38d84396f159cffcd079c148f9f6bdabac..ddd679efda285d0152778552f325a5e731728e4e 100644 GIT binary patch literal 1591 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 C_wYIZ diff --git a/root/opt/phpsysinfo/gfx/images/Synology.png b/root/opt/phpsysinfo/gfx/images/Synology.png index 06662d59eb79df8695da96d796745c06492bf83d..12e27184c58a43f89428691bd1e7b89a6d252560 100644 GIT binary patch delta 1166 zcmV;91abT1AfXA6BYyw{XF*Lt006O%3;baP0000WV@Og>004R=004l4008;_004mL z004C`008P>0026e000+nl3&F}00009a7bBm000XT000XT0n*)m`~Uy|2XskIMF-;p z0~QGo-OplO0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE`KmCI2$xh*Z=?n;7LS5 zR9HvtS4&J(R~SB8YkW0Py3vIzyJ!VHJ1U^!7sgbDLKBSeU;6@;>lzb24ph|T3f;AWOE->4G;QHL;}hzfz2 zLzqv*gn%SQuE~7BoF*_$AVc6-80u&ah`c<#K%SH73CcJxkbd?$8$YJ?WX_V2KzXM* z|5OB3PX${8G1u^iS3gV1I_a&PCAZvh!WIY9w&EH36|H zwiOl3k1L{hS93iYfI1w)HX46d+xUlxb=P{+BjAcRftf$hcxedBe(6HHnbPvq=okvl zMunVsAYy*#3S)Jpfx-(uY_9U7=rZw}59c0)^@6_S7-rIC)&7JYdm5uCqOR7nQRTy8 z_X}*g9)Ht1cDvXzh!s3}d+cpm0+>UiSmY$IrqYi!=e@{Wy+NTT2(`5VYDZHBJ0C+GY{!SgakNI>=>Ev4e&CkTi{8Nz#Cf0$ z0se?P>{jseYsQ9?#KJS3=ueKKf0!O10Z)syp?|MCg&HG?nzmsLPiqpZu9!MZMK?^X z<7w)_l9C2I>#@9csUd=ShaU6vZ}ol?2*^N$SrZzI&UTH<=lm4G%3p&pd4gQ6k3<(U zmp0T|1Zqi4?KSY3yBV qiX*!O2(X=kote;G@$~#BF&6J@dUEpOiIb#ofR+9s}OA ztA7ibfNQI*B$P@}$C>FR0jO^uvI;u%9u7Mb35c;-ZZ0Ziozk64nYoG77~U`k3V1qQ zzxxfwobk3}zqKA$|LM_2zj6|gns;$OsrmAVHaaPR7+siRveZ3gP5TL7LdRO#i`WQe zmxZwVZk#dC#J(mlOjjp$R!jTx_ipV4X@BDc?3a)Z=_CXs33KM zBX|6z-4B|Wb0ml@b#XoZvz#|f|uXS>7L=m{{cMkc;#eCnc`4?NLT@kM1& z*Sk|^{RJ=P6|*dlc3^46D-?OWT33~&-7jDW#Lm}M0S)PkZGH>*Qyzla_ct?@#((zm z9WV}#4>IN_xRHyDi+y}YICY49e0Lms4(0A5iDyu|8!cTs{u=Dtb_CKF+nlsMMq*$x z*qg|Px#l%&W42DV@hsT-);Np6)L@!`CNSlH%cuNeQs)rn6Z&d4RhQFlLSIg868XBG gi;eX4yi@%Pu-Sf5ODqUi00000Ne4wvM6N<$f=GfHAOHXW literal 4196 zcmeHJ-%ngc6#mZK9}CM~SP)x;O1Eg6qCPZzXkyeD8yX=d#F+j8{tv#GKI((_cz2j$DN}ib9AOVmX94cM&KBM zeFzBY|8C3dA`Y3A;}gJ%sW@D9JWJ(z7r?WY`+Cq+L9(e9*l&DlLpsc zIagadOeYLl>3Ig-f{*Vo7=8xpzCh~AF#Z62xp0`qRksh%_U59oUi#=J`Y zBCIJAH486N=ZE1uf#(Evpr4N3;iLF6JdY?R41z{e+VuxYl>M56Dw4v_oaw0@f)`w* z@D(bX6^UL_0oe9D#IdBFKzy zQqPwNLk(&L4ih3zol;fCxy3CWzCne*a=occ(jYwll7z*JKy#U5RYrD#5&0rxd3MXw zjAjF^V3m7(>1hzXcbwbc`EBaaRGA)FIY(V7{QOVOH6FM|_eYmkiJ7Ix9j07Z6f=S|mTVD~AjN#Y0l%ocLz!(LeAM5w`5()OFzTtzC{CXCc4FhTTD$t|M;D@9z8;^S?VV z7~a=}Fn_!aqX)b*_C@@pPIPPFNfjOR{9oJWpn48`?%0821dbem3oF-e&VBU#hg!um NS7xU^x%}=2e*n(g#~lCw diff --git a/root/opt/phpsysinfo/gfx/images/Tails.png b/root/opt/phpsysinfo/gfx/images/Tails.png index 4058145ef3f0283d83302af6d7da12e735f5f6ab..b0900899f6e0282513dcb0fc594cf85495fa1de7 100644 GIT binary patch delta 1160 zcmV;31b6$95s?Xy8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600YoTL_t(oN3ECpPt9Q*$NfQmz-ER`x#TjJC32rzVGd%JO<`GaYLd9Mg_VxKEJ-9P$3p6j8W0Bw2`)EqDA1fWVmF z*8E+&U&4Kg9H7CLptIEeYaEmql|yeUo5VQ6@n$>MB^Y9fqtU61d;!+?0&dU8;FO`OM)>b9J zw9f!UZGUauqS;s5H;M|oECOIM_NBz$5WnwaJrP@6rvDm17DCWr@1lrZsm2*7yjy1M zADJYv{qWBIe*s zpa@&n_$YOCc8kYMUV`VvHO4)FnoUdNJO=QzAb)Y6A_r)IWf+C^@0+Qwdw}+=Pci}k zxgWJbvyO;;<^Xty@UhS(r;YjCr^o?{Be$hcaY2P>GT1*v8Oa6O>v}JzL~QYha#{1I zR$4tjTKvXYkmKiKZi;&DQ{(`JI6|y!JzafbVs7?R5eSzfcwV#;0#v_lG$a54Fpj4~ z-hVfe$UT>Q2gpvlFN&|F7b(~Aba;js$I;0#fMr?=fDB+9JzJ*ZBeQ%5z!4)kmq5z!2PdkX;YF(dc+41ftpjivbI<7$s* z0^qv=^70q8UITz9532kR03gO!Q18!vuYV!1C~-NkeRODR;|^s~Y*e;?0VG)W(R9U} zqslnI3dwIUPFTnVw|ans;XXwUbd$EPOcYJA#ozb_7&1PF9GHtGy5|1^zmK?2kpnK}=$ig3@_oR4iX5255?#ZofG=+DQ-9<@ zCkHr%crodk`b%bN(bS#-PT}oW+UDNC($0HupCSjm&=cbS0FB7Z!~AmXBF24+9GHte zfe#U#6g)1hbbDiRxKEJ--2_kI=$tK`hB*Iv8Lgfdqpjs|pCSjk3BJH*JO6I*#b00e ajNeW3Z6&;~NPGYQ002ovPDHLkU;%=9u@`9o literal 2193 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 bQwYJtFE%ccDqQ_$B@ero%NH diff --git a/root/opt/phpsysinfo/gfx/images/TinyCore.png b/root/opt/phpsysinfo/gfx/images/TinyCore.png index cf72da44b4429b7554e47040dc9158286effa3f9..3b18b959fd6b41f6c3718b4815058bfc25cdf71b 100644 GIT binary patch literal 1193 zcmV;a1XlZrP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1R6<1K~z{r#Z+%-Rb?E0&Uw#y&%b-Ni)-t; z?cUwpd+xdSrc7%QL@tt`5<-i)q(2q}Y0-xYT`8puWln=k8YY;msZm2$3v$e;G$@xr z25tm}(U(B_;+F^n(N51jYd5PmsEE_x**SaO^FHtMdw#!nh@$9!g_2AXN-{|($t0m9 zlZ28?5=t^jD9I$DB$I@a{3~4B1 z!>RrRt&?jlk&fK@x&fHQ$9UNH#5eHDN8ps7g;jk5dczoG%V}7dNjP3V`+t|6!mYwV zuaM{ku!HGLKu@26U7ckSvq)8EkP7!Qja_gnr)lbI@@HWOTY>B<$iiFX&yo8U4b{?| z0q?pYZkm8wIu0{|l!=SAt`-c%E+rirCAaG&t-09&z%v+;%o?F9Tq zvK zRG2u#gErRU_I=#Umh?GIxXJag5;~rPm7RrX{0Q!nZLDmVl@2f&GuCy2y)?89sl~5w zZ3J#O3cu?h3x1va42?ZKXTUAL7Wd2wuR!Eh*9}PQfWWw6V>?VdELk~h^cX&RVB2e9 zww+{)ra730IWsF@cRb2gY@q=y)-^g_fRW$Ks@cL~KZkJ*M5z}tTthR1K;icIAc@vW zY(V4Sxz$T-#Zk_~BoDY?TKJH?7^<}Zmbsqs_c4`qFq;oTwomhFQoQgU_f4~auV9t? z5gie+0fz^{;Y)kO_ZeyqK@|4!{Rhs-1)#GW8;CzPOOJC(FV0QyLZXeED(89EM`Vfv zCos$;26-L#z*u-3T6)5;a12(9Sil#igatKwH5mL`zJG8jzsUgw!uk6CdOO6MZs1$qOj@ zqKSq#jSqgr7@`pClL-$dBAS>GjG-8UP(xdxZ779ym)-feU!KLZ;jJM+YGQA8=FZHW zd;aJA&OLYb{ipk%%!jQZfPCM!tD6mdeDlNZVp3b|;ux3_tYWTn?-U&F(j7w#~5?KFZ ztKzS2#St+(nT1{NL9^%R{%$Z_hQ+7wuO1dDK36uXfEOifP*sX|`d1QB$AIa6?| zM}4<;iW$_UMhi5V&Co->u2rhI0^TwYRspV{4~71j2wbCRH^JB2++pYjSf;Q(-PYwdPK}6<0dUqU}KybDOIdah4?uYi(8@^TW6av;^v zxII7F$Oq*;&ux}5AD1*iV;PFZV7V7!n6At9m_WMi>%l9Rpv7s5xEV%I0i(z1ODSm$ z4U^p|aJLAfnuuT?j&JF@Lh0#3E>{xZjzE2SH~b|A+#I9wO`??WkA?QGl@SnDaYwj6RRFd$x%wxDAHIF1wll{5UW$d zt5-kFfZfQ5PcAyhqV5-9SP0wJ>xzrN%ghm8WU5)_F6EB2HbFD}S9qAv`H)jr5v(L~ z-d<>4AVRnwD%+_50N*#*f7;?L zGF|`k8|HVdqs9Ct;`n|bp@TF*6~*uy0@HfE)ShRIAI6G}@WdnJRSV@x(xizfwm;T# zBQH}KZuV*Mq_%Ju9HzLMmf9%~Lxux6gePM++X6xJVl})I=f68-E!6|iMRbNl`zAPU zF9{Z@moRby%1l6e$4JZ09rQj&XI~4@+0uiaaCQuZ_6=|dtrH!9Q+gMC)l2XmTsJqq zb0>crn+2$!eRgAyj*b9L5452CDA{hEvpeth+KAxB#t0e}GyQJ8H5SKBwc91!5WQ*f uoAPv?mlwt70d!}E7qQ0Dy!50Qvv`0D$NK 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 diff --git a/root/opt/phpsysinfo/gfx/images/TrueNAS.png b/root/opt/phpsysinfo/gfx/images/TrueNAS.png new file mode 100644 index 0000000000000000000000000000000000000000..5a72723f8af93d768a4b10532d6cee7dfaaff420 GIT binary patch literal 1039 zcmV+q1n~QbP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TV(%C6GNNFJhM>l1l!(3T!H7z1SV+Vcf=0m- z(Okr6)RUlyBE(>?h(7PXJ7Kcf-B}wV_`{nJ9{AfWmEH zG0l6h2;v@6kF-Ej;R+@WLLZY2QzHWu9!;o#?a*1dUsQ9L1J^K-3oT4Gq1P$|kD4_5Yq7lW_iyY_%>Uka}>WDHS z^D`kIdcZ4K1AD2Xw(98gOp$>M8YQsJ;Mh-z`hn(XDpXVWu5uJrk7TYO6uo*5>iIs5 zyfvBN5iKKUJ*yNPEe0#LHP7|brV)%LI+m^QG5_# z6QqGgx+r`bY7OjxDvYIre&kALL3{A#B1yg0iC8ZRCxf0VbLmk3jEDyj(%hH95lqOG zMUS*bX22BCVhYzASPiNC_P7$7Mp#DkIxGOQ^}Gt7f=JSX1F(r{d7%W;p$9pz6tojg zLJoz^B2{66o~!9hQ7(##;xXXr0Tg0FXS@+cdJ%fU4T^tNj^cVHYsKr$*{H{1G6p)) z&<*pTwX#0C3M)(u?PZC=+HOli_!ZWDI!TuY4~jsI;!s!%BbD;e2PlGU?G}oU3tek8 z{PYa8n+~$Q-v<|=dg9oXpcSfptG8e*X&a6Q_r;=Du3zz&uo+S)yj#VUY`hB``zW6} zWb)v(Qokq-_c<5=*%US>p{vN-(6Q@4>%xY^VBG$oRQNWGfeZ@kM6F*luA-d-K{>Xz zmCk$(ca>6cO1;z{nly@5L@MkmwgJhpzk>df>2*679x5G0?_ekNrRXm3okD*DuJmqj z>_fEN*X>88J<{1fhN6o>FQz}NKut$5XFA*Pcl>qxufHM7`VO39FaTBHNk9Mq002ov JPDHLkV1o9`z!(4k literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Turbo.png b/root/opt/phpsysinfo/gfx/images/Turbo.png index 4d040d9ec59f24915686de517d11a8dd4d950014..60c39d7ed9a37c1b82898a8f97a96385099a5b52 100644 GIT binary patch delta 924 zcmV;N17rO8AhHLLB!2{FK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi00007bV*G`2jc?+ z76}mD&thEw000t}D6{R3l8k5|a_;w)$K@GUkE<{14 zTB;y|lA4*hlPb2g_@~7)6Z7cgo6Mxe#jh>jy=TtXbM6bJQmH98^=C6w@i35UXX6`% zib0?X29$n^q<^!Ajc)`h27$`&g`pRqTpJmCN-EOD=B)=R29Y0aQ1)#Y?y6K`MVLo= zVGLLEo7ntTpdth5`~j&z!8hTfe<3YxG41_qeq5-?keO|g^j^(?R}J^KXqMlW$)#=< z7X=l=KuQm-twNP$qzj`gCJHKsfn2U#`u~s^SVh`NvVWK;s8|651AXZ2JyfNyZwS}t zMkJx#U?8JEh>3|R8EYKseFyt)JyfiK{{93yx|8VW%$Dgfv887ihBMt@Ac)d4Ud7mV z>!D&jNF3}JCy6rf=n?~B!gU&wR#3$inC>|HUJxoq;q8AY=TT#FZ6a%*fMFfSgZx$& z8-$8+fPZNnlQQcy29#s4xy_(r9FUVs%CsK`47^0H)Y7FzMFytwyD@1E)-Nn%wYMYO znhE^{sr*2FTohDfAiFpwhtNl4iqDX7F8NpVwZ()i$S1W5h?%4_%;LkKBEwr$((^a9 z|JE&vky)7fU7Z2%Xg<&4!=PdqFznNkWU0rgdnLgvOgrRPDY7zf<4wu^yzWTfwz??>63I8ZSz^6a>&rUWT1r=LC-UWm59(;vVVILchf{LwDeu%pN y|5+Y}oP4|F8a~IyqM+h>z~r|hOm9vJe-#0V)RY2~^oPX&0000rd^2m{!o*Hu@s|1ZrtwsI|69HAz=z<{r(9*+GmGEKLfgh8*f@U+4o*xm52%$r%X?E4fDTK&BfUVR2@VhQ@XqP- zQsw{3%5ToKdPhOnf-37Z>KWTZy&r4duZx&5AS9r7>`9Q_0cJf7Q&9iBi>v$*wOu{i#_)jQx1nGE+ z-`lhXF&iuGG96CXU)z+yHY=6b@UX-x zG!(n2aVP)#F8`=t4dnkMW2L^)El~CgvOaGJ{a791p`AnF*gz?56=Vl&TK$v!?U`(o z=$mLz$S*;RovAz3M30R&(%_)~4G-Mw$`l-yT+5peQ6r{P^(Ev-(HaPY)xmJ{asTL}#m+h7CyCRA?fa=9FScp9$1m7tMrST$Gc{5T2 zO7_S=;)v3E8T=3!iuJ}*z^`;&1F2DeL(W8v!?HGjX;YX)Z_Ugb!?A&448V`&Sf>DW zu5etdC8(3aewnu=0pNF%f5DRj3G(!XrT3;pO=rgXDTR1`v)lpAq$B`-$OL~WM4$I{ zO}XuU0Lyt^YGOic0z@TX$8Iu9FV$q~82It4?fO!ZVS(jx;>FhS8=WV?zwHOB15yLu z3oB~^|6+Z~05SpTc*uejot|@j>d7wn4d~)?U{|wYB;{|#PmFfTUeE_c7vQA(dARG6 zQN|pnG8vF45geE2lq|~zM6AY~xW>b>0r2Y`m*KKp*EtFmx!E{lj$_#X{5Y09E(Q6k zFt9l%uJN!U06g^2AF}K|leV7r9*r4i&2p>=fFFm{7gC507O&|;sAQ=a0KeJsyR7}M zK~=_^Pd3Vm0c3*FxE$4W*?~><>jHq^N?wGUo-$3E?f3YLTkk%m#{5f6+XKngk^A-> F_!lX9O;Z2> diff --git a/root/opt/phpsysinfo/gfx/images/Tuxedo.png b/root/opt/phpsysinfo/gfx/images/Tuxedo.png new file mode 100644 index 0000000000000000000000000000000000000000..db4051050bc663fb84203cfcb3374adbfcf67d35 GIT binary patch literal 793 zcmV+!1LpjRP)N2bPDNB8 zb~7$BHmT?0B>(^dmq|oHR9Hu~m%mOMK@i3*kp>D|{wJlN38F{g8S)Y-1H6VyIwK(> zB!in2C`ywkN|6$h1|?F`1SA9!B27$?XaJJ{iR66Wdd^u7b9Z}i{-mFLJF_>lx3{-D zE`+L5sZ7*rwFU4Td;~wiUvLGE!6sM%3+yYm-Cqbe4c5RV=mo;Q>tI^KWLLRd9z%d8 z;8R*jLg2ki#bWV+gbfpJngZV>NFMBhu-QPz$KXV6%oE0(l{B{M^*Wz?6v-nPJANkM zY=Bn=FTsn9w7_?u2eA{oCNKj}dpQcpu2u4gB}v&=wOXAVLGrIEsSm%7|E~fKe&<$4 z%?02FM9#!Ez?b$Jth?lRdhT$co6NSvcS5`C`M!vm*S|b_9K3gePe11wQ_<3PTyICV z0OmOW?%$R(j$_H?g!Tbgl&0>R#tH|(gT-fz~*UR9IG@a1SQa@~Q04%XAXB_V&*TCir?bXO0fcp$t=UGmRj^yF>k!Rl*vlH4s zJYN#eGHu0?aLszp^hMHsgDwuhad#e|aVwxfOJZ9-!gtRD>Rf)UK0Ym%oWe+0`6ex% zJ;|Mmknag*{-LDr3rSc3Tgk8GzFgF3Gf|8uH^VB=sOu!Q3Q)&ai(pOV)f0DW_q?*0y!szTu( XX1-53PGC@z00000NkvXXu0mjfPp(<4 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/UOS.png b/root/opt/phpsysinfo/gfx/images/UOS.png new file mode 100644 index 0000000000000000000000000000000000000000..e309a0d71aeea9f18c3aba454f86660e0f268814 GIT binary patch literal 929 zcmV;S177@zP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd0}@F@K~z{r?UPMRR96^=pG2#si$*a`ZPT~_ zCt|dIRz``g3gOfSuc)j;7pxn5;E;>*0Cg*+goty7`_Z*Z`?^Tweow5w=lx1kAEJHhG z8QLk!&`w!~cFHoeQUoK1wZMO#Deqt~V1XksonZ{KBuYn;h|s z{fXxs`!~w@SSclu)n=8!MA;e=6&}WGlMFRV9^aAl_DDJ&Nt$DVo1?p7kJd)6++c2* zi&7sjBCZooZqj|7TuhOuweO;LOcBwGZk~EGLKx5;;8z{baQ#zKt$HkXEty-l}mxRps%fH_U**i-lMOT zHi3jTffqH!3^sg0zc-s;FdJ`wHciniTxyYCN4}Wmg!;xX{~@FmJrH#S;{<|nyx};vpS+|d9^~qb1CEM5ewRO*TjuhQ z{8T%AD?VwA@egeRr$mXqwxX+j7ky3lOlP263y6A_F&N4qr0LFJ1`W~AsCrdR>FYK) zrSkOuS|L9+w;0^j$Nw`uvJ|&ksAp%ji+4=+azw4r{cPL=OYnPI=x;n@Chw+fW*fz+ zX(&)1az(hfB|LP??b?(3l8NMIM#VWEYvcDPj9dMd0se`584TC|MzmG& z(68veukb_^^}~wlm(yHHmUBriH!IVmNs}hc{}y-yIlY%0IU_tp00000NkvXXu0mjf D{-mh& literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Ubuntu.png b/root/opt/phpsysinfo/gfx/images/Ubuntu.png index a0ea4a4e868e7959179e3995ef9c8d8af9995342..7e9f8b62448c78d4d5efb912e333ed0c8983732d 100644 GIT binary patch delta 1249 zcmV<71Rnd03F--u8Gi-<0047(dh`GQ00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE-)@Q z8#GSX000DANkl_nd7aqW=}vIFhi&dN_9ODq-a&JC?E5v5ik0%RG$V2OKN+ zVbL~MihOPYb$?%d5!bgKtTBzWnr}yvPmwGHbOr?Im7Oiuak0{{#)!hSYc9hZZ%!pR zTil{$%%zT|bGg_NtWn`iF-IfF pQ9^2S?s_Xhoxf}}CShQM3p>rVz*ueFo+!2*&!_p&jt9tQt>zU>mo`2ry7&vXJ} z=8Y5_|9=h=B6mdxmA~qv;Me`+?|GB_FV<0T?11)#@)T8$?xpgV8!|D5u+1(=vjr6L zH(U-uCDQ>^e%uX7wJ{4!Sv56AVa>Cw z2FG?g+^GU=V{0VvKVDAZ=|MfeDu`;q-^Vh6IMfJ5yTku{4XZ(}7vRnmuunPFTgIEa z;t>p|Q+Mt;+}@{9_;Y%}a(>(^^AS2(02~9#DQ1k)^QRl$L@vBX|E>J6iwVS|iY*`9 zp?|j|=f|x%OXXC=3+Rgka@m8}V!h<9e2n~o)o^1`;fPhoZKSD3d<4CZdRUFf8x!Hq z6ws3vD!l$Ba93Mt{filY8vnDmYidj%PEAgO18F?msRCf+#A+*%SDTV@slmKr2fU-! zR<#AceP3_HWc;ILr~sOD%lUAgOo=t#j(ZxUgfe0NH&iuhjwcG-K+G@i8p2nN}{tF3o4l}@eqLpxh~cDjEGlm9XbK2;_G#i z(Ac>rRqQkwgQh!oA&S6fcPzkJ;J)!F7U_C&-?Y)^{pQd^dIol zEz8EQ!5ZVB`VL_kKQX}@gAo*V^IFYZ%s8wu1I`E(@eCH|E(B*kT58}++S~xfv2hq! zVYV*=f9Lr!SV&G zjrh-`2?wMx2W1K7avlYWHHV_jWLz^jhXzKQf;>|wngVf6WjuFXDFKm<+wt*Zcv^FblnpwI0Y53p&MS%O&|CcVZLyoA6)1U7oCQS ze}HcX!KG*6yJ1Lq1X6w;xfh94Mj_Q)q=tvo#v^r!XmdK+d<|{MKwAW8YbN?28*R@; z+w;(le6-`b;?WJoliP}(5=C#RqPI-ZCsaHuSM*mX21LriO6A~h%AqRdaE)@LR{6Y6 zIohb4c%Tw@s{ZI!{rN;S-J^QduYNPCemka~A6H8z)e^CKVM@I?tzLSiUVV$L&10KO zm~;h`uVLUi25n%l6hq_~0^%r$D_~rS;3@^KR^b>%EKA=koW+w zG@D1}cV4`(X$fB#-CxWp+!O6;ZT&p6VyJx8KHB~6+|@GW72*4as>%GW5ZYho9S4HO zI!i4A?!BwD>ML4LJGWArs%J$%aA~#*zUAqCj55%iGH-2ZVDgw(PT{xh)SJ3$MuXN| zsKY)$bJEFY%xU+P69FpD;^(+A^R$2=c*?l^j%C{yB5bhJYO86SE@Gl{HXEyvk!o8k zaS}M!Z0MH2ZXBYBGor$_i;d{N|C)DGnEX}V(H0BSLjmH8)dnKdyxOqiVneSS{_;Aw zpvu-3_7Af4UFrow$;@jfR$;J?t$2^Pr>(Z;#oz^%53+Hk*M%MU?5zYZg6&X-lacMaGxgpbZ_X`#QU&7x;V6HG>zlH zMRwf@oSC~^uRCDbWD%L_#VuQ2T+5G(GrL&G3VXU}pHSPh>9lh=6tLCu5ZkpIw;~UL zp7_7V2Q`ahPJOZMmxGtOn#X5e9?hc1+6UP=OB^`*{*vCIG6!a75yLupM8xS!@_4A& Y!O)ePMK}eEhz$YUTs&C~%rj~K0<776CjbBd diff --git a/root/opt/phpsysinfo/gfx/images/UltimateEdition.png b/root/opt/phpsysinfo/gfx/images/UltimateEdition.png index 9eb8f0bbbe5e8d16476567b70d36d0173b0dc9aa..baeab3bd8feca06eea06a8befddfa217e1206089 100644 GIT binary patch delta 1542 zcmV+h2Ko7s5seIx8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600m4*L_t(oN4=M4bChKihWDSTGdgHS0ntyQK!OM%ebam2%_f_kO;AFTP48kz zAf%~aWf%tw#zx5~b^H&=(im=#rslAeRg_Bqz*+g_x1YuDydQigpG0MKh16A6NNs(Mgd-uz z%E?rNt?f|>H8m;`2-P>%NoRM5bab^#e_u>i*H@lO#COurdnP8?xml8tby|(%EnXHB zKba5OgP%EM2y%+XU|AiPp1sV2juFPSA2;iO@NZJV)ZgNn4{k37G`L$N3@}(;StcFL5hXyJkrh>ph`WC~OioW|X!_$LDnFP%KPSs8 zmt^a&yW1;pXX~~au^K1l$bI}oTGGL%0fo*D_J1o82#|YVOphb&197=XDu zXWrYoorkzvH6$^L_VjjZ6(GGmWXg_CM}NYB%d5+J@WG?|3C2dpN3=({a|?@~cw>?a zBY25=RDi8P2!|lR9_yflIPl}mA9P@u4;ee?0ttBm-8q-Q%+#Dd(eAo|3WFF5vWJSm z8N#3&FkD?*rLlpC-xK=Tl?@q>4|((C35jRpm9@+A!O0We7{^RSh*AN_&iyz--hZXN zpZYHWo?L#(K!h3{8XnZvX_pzOf{V*b`tXo&rU-^0!+3gjN=pv8-E*i+o$7y zzVV*|BnOD~^~lWJw8{i2yJRn*twRXI^cYH!cF$9<8(@t=Y7_bKfZmM?8=tT5iNw;S zMfI9^lLx4Q5~xn4cpLGaOa{d1!hh0&komy9@L92V@q+dkLdH7-DAxmT?$>+0jb@Ax z@M$X0)!cf2R-i0Kk)DT*?~vhc))O`(ISV8jhIzqAE~JCd=Jz*tMFh$1JGGAF#2+OH z#Vh+>_SO>)esk?>ZA83O5TW)72N{efBog@ItE)*wsCDAY&$(l1M|GV!jDM4GWIYca z-`)QW36}seA8!c*eSrj}Eb)r$rHc_JE@mC0^biQL=VFrfV-VtUNYKfsbuPge6=T^=hjYC{Nggjc9rO{NPn7eK`BB6PceuAS}KXf#Yk^;efYh1JOh>sWd6HH4sZLX z1o%!q2}tmCB0sH~q~yeJUVUw!X8>}%^Slcv;NIg0-^uMjlOmB&0`Ee#HS*$1 sFL*`>)4@XrG>P4FJHdDI|3gaPAC**B@@oWF8UO$Q07*qoM6N<$g2zwA^Z)<= literal 2193 zcmd^8X;4#F6uwrcQ=QSy^jG&fj?;mPw7{ezGfWJa5P~%DFiDL@jD`m>c|afuAqfEj z4_Q z)WjqjospQtpfi$_lJ_!Fn0uLNKczy0jjFgrU9KtCloqSYDoV;UXlY5Y7A@75RF;*Nm6uj& z%StM$v=wDoxwaI=%291aWjR_^fmQ0uF+(MW8mlTRbjB)Or5-byuqsq2>3^Zl}YGyS*+?joat-)Zm`_8ZTbwt@Yt`^|b+C z1MY9|`Rf|$8*2lN^#Na9LzBOuz9rxfH2NEw0*%cLO)ZVhtxYW_np@jiPPDgnv~{(0 zoM`WC>*#9l?C$6~+1Y)n>(rU<(>*88^q%hNJJWl%r|(?v+5WzB=g;;JoI8J^f8gTz z3xfj}FI^bCeDTuN!7JA;T^+i7ZTRZY$hG0op^>rS(eaV7>!ag0#;)HSzj5pO&50Yg z@7$c2yme=4V)E{t`%{xs_a^U7Pu-ijJ3V`E=Kl2TgP8|&vkxELpPPU9=<(eAlShvi z=AS%$yzuPF(_a>zy?FZk<+B%y&tJZJvH1Gst2c|U-@bbD>+83_y&)#^zn6C#<7EJ> z1G04HKJe%NTQ<4h#StCYC`sZ<0oXDeTWr*jOmMYSR-TeuMzwahPnmw6t>-Ue%hN;SeK%B;v6l4h7M|V$Et~S%-fY!HA9d zk;Y^vuy|P<9vf9ydO|2<(huR05JXAfWuP(+pTUDUMi*Yc#)yui#YWO8WR6gxgg+Tv z!Ee=1uUPEuQDiuh%i?|;HnNr!YQWTNGLs)2$z21zsM+Q6w@t196I><-5`MGl2GJ26 z>au9;X!kOO!HeD%JGDYzR<{dLom{Mi2@f3yT8U7C{4EXu9zZ?rT-yTx4#faK)_(O~ z8~_2X&?_}WUM3#^NJt}c_yeHJ>jIu=pN}{%u9Sg}m&;(bZi4)Xa+PY5Q&KL zH2@KqFxTo2Ch=Pb*&;CG5!K=~6QD$?1HL&>Y2PFi2a1sMD!-;uatA0-=I3$gvEzWeM_IT75bX z7r(MbAUZ%}(W9Ubmy!Ni@uSr?%FLh?Q!VmY;$m z#P4F0NR%+*l~yDmS7NADDuNIV#1#;U?UB^j=+F_cq82fxi&2TW2!s$PAd%v>$F8O? z=_ad2j3{VvDSXza#4E;;KMVagOB5?llnW=Y(>4+}*tv}ufq#lS3?Zj}008zeF*g5N W=KB|u|H$i03nnmVOlo%mzx*%s`*kG% diff --git a/root/opt/phpsysinfo/gfx/images/Ultramarine.png b/root/opt/phpsysinfo/gfx/images/Ultramarine.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd0f65a3514a245d38b0314f8440f73515e7e2c GIT binary patch literal 1049 zcmV+!1m^pRP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1FlI#K~z{ry_a1` zR8bJeXGQHQsVk|QDQX&$7-i*#T7E$EVM+R;DFpdY&lVN+pij|@J#@>!QrwghwTBEd zL9!&X575-ywIC2QH&cq-R5U-@)6BhhKU{a+>$>`b|MAYS%*>g4&hcCYxB|!f;24Hd z3O0ZN^&S3Rm=#U=$S;87_u`n3I)d7T@LFFBpzya0|*!|^&Q6(zS| zhU!F>U?Hysj{_VB3 zX<>N*VsdI*gkZam5mcIO5lagY+x{Nqu9@3Hok+HR9UjtO6ZFp4D>*^2DTf(L2RJ?* z$99yf3r;SyFf*_V9b{N{fVSFtCnqQeln1Oj=5TTFLq#`0=QfFk45nZ9kyrtGL9YI z3eOsI!PC>SboxH&;q19K&<;?DRe}FI6#f`V5srq_k&#Dj%|r zhe{sVU``fJQwb1lc{DvAl%6d3`Ek%tn*-S=w@Dt^D6O}lEWEuvrKhF%_;^EYO*Uko zSX~iRfb5qS9OMbtE~_PLIljK$Q1>VY&KE{Y9;Xer4k|KK|`dySM$!1f?2GEDv($jNO6y?)uMb(xWo3CPK7hRG=-UCD|>uOsME%JIW7 zag|KxhE7n7=(q}+`LGaM7Ge=PrK*hGuk2>?^Q&K&wBX7sx){ZvSn`vbpc^vBSD}mt z4%VN2bPDNB8 zb~7$BHmT?0B>(^g0ZBwbR9HvtR$EM5MHq&}(&!snj6V2aq75O9t-c#?Nt31qZDPFC zM19j5T12tZX!XIiYMTh9ZfG>#5|b)W7UX6t*wqSHSSql~N|!AwdjXd2orcQ-`}=>h zGiP_%3k$yZ;Fo;KIWzxlX8!NY$@|ZPh_*3{Hpy)=%;vxWb~FDicFS-Z13TWrG_S0z zkkjL(i7C&z^o8a`Mj#T2(CX?c9?i@xGHmW(r!sg?xO`OB<)OTKb5`av4OSOi2t|MV zT>}kS#>6|LOoq)3>~K5NyRfi8?Spf4ZXinAo35ozthoOtGc7GGiEI|DjY?jBmtOp+ zmJkE6n0LtV>w}GJ;Wc9OQoWG`Pa3@RRL2NC-C;`MzD_e)-Lr5J+x~{`E4ug9D#2Dm zj~Hjv%JA92h9%5MC_G1c!62q0%o3R< zGuWsTtLU@%wB)UWH)(!;9zk*fY@hwGS}WpA!;h*VJ7t>mV1vD|nwbqy>(t@Zh1NH0g{rDC0?)E*U&gz#PLicMS!#)&I=T z7y}j;7pbLhl8PEeQ=0IuMiaSj_=Oz+pSKcv;c(qIDh{MkAk)UdgB6&)?!?wdMe+vT zg(*(}!vf~H21E7oI;}qhyIy70L9X zfI4*V@OWHyP(V&`tIL^QW$kA`2)=5 zAg>@%cEkJ)kcQ;pvu*C3PAUL=q-Bgs`8$B#$OOb_zI0hD;L*d!$mbWw3hnMh0d08e zzZP%2=KioII|TTB2&gzEbzKifd(VReey3k?C2#SbeOBDA^o73=7yDNQ|wI74SmaxYmT_ zzgV6W>Q=(KP2lyqQc@f8V|SB&BS`_ug>TA(DS#aM7(YId~iM z>V#X^B?4#v+_4&M^|kdaO4b*d`7(VBJg|ewYDm6>hFF^FjAx}99_H>>$rbmuo4DAx z8sO8!l2geaXDLFG3~bd7nKl_b@fjQwui+*xCJ>B$WH8tFmy=%V8cpHL-4?QY;z#E5 z`-S9G0WB;=xe%R9mkOT552#Q5h^QiZ626ECg6DKpz;pHYdM)|>6Q|Wt;mlfGuUVg(}J$<9*)bh)##%En~RLs z-B}5n1GQgjtFJoytx^c8$nEEp4fnuf<_7)?mPG;2bUITSFB1!EVi(XuLjR@%c%}}CRhTAyUxsZ8=soNysTPVZ*k2J{3`v(_ljUs2P Re0Kl<002ovPDHLkV1jClq^bY_ literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Vanilla.png b/root/opt/phpsysinfo/gfx/images/Vanilla.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a37a2f84e87a62c3f3672b70affafa43633514 GIT binary patch literal 1246 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 literal 3599 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 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Void.png b/root/opt/phpsysinfo/gfx/images/Void.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1bfdc9725f215382cceab1406ca10e77ec0a83 GIT binary patch literal 1202 zcmV;j1Wo&iP)N2bZe?^J zG%heMI2$xh*Z=?oFiAu~R9HvtR{u{^R}?Qev;v~rlzk!2ImF3G!5$tS(9?CZ#ebaBpB>wL^w7-4A-ao0|XEb-RfVR2)0WbP{+w%#<0VM zgKjM;)yx+2-gy*l+fyYHbjwGr5PrpxdwI2w2 z?52MG(XSk&Z#*u4+XyM^G_TbnEz{ zmQz;NRYGq52|kWJU&JIQCnAX?329rkP~GwwAH!-{I9sX0-dySF5@ay6F@joDi3Q;T z@bWe0O)7x!!NUcnq_hBuM6biCQ^#;@Tr3|K8}|aF%hF-zi#zGPsRus65W#(tb|U@z|IXhc!bLK<^X z|1}u7=1R>>rM8T>58?1S-6=7 z@7S{o#06QfYwydT)|B#FtN0+B`lZ=YZU*#0yP*>{MTGM<^2UcUQ|MY#RR&w5+=9vV zH+@}PznD>OUJkWM-${Gam^sG|`;{V2oB&z6)3kBYG9>gyrCJ3)O!UIOqyZ3kZ zD=%S-<-6d=`{Qrx{hF}2^V5Lydvno-2f1NmvYWtm*9yU=^ zJGyI4p(lGB-v7KLsEGe!)%Oi+C!(UKc2y$2Ftt6gTp_{aFmPMk5H!)hS#hNXdd9og zF1arpE*r{iVNu=nW;orhfs-xePx;#8Gi-<0047(dh`GQ00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u010qNS#tmY4#NNd4#NS*Z>VGd z000McNliru;{yX02@u`SVqE|L02p*dSaefwW^{L9a%BK;VSj0EbS`dXbRaY?FfKS7 zG)~w600YcPL_t(oN9~q7YZOrw$MY@J#=Q1D+0E|E&hE}WvOy6vl@bu_R4gn7BPa+K z7FtLoq7tx4lR|=GA!!suAr=uaAc%_kRj%{9lXG__Gn*ZQU}N#;?w)(@IsfyxXYSZ{ zyP&@1bN>wg34a`jz$?#DXPb3p`M-5O)C_{bq;7mMnu=W6g<_Q*)m`C&*+fHdO(toEBaQUUw7dJRpC z{pD^gc77OA5!fkKv|&%)@xe%h=0z0NJW5%q}HFUz~RSgMP(+& zHQqZx#Mkuh*G}LJ5}S>N zk>8nX>wk#F`3b)l$cEgEG)P4NNR;6|5PYbVW3seJO@J&&w2a_)vz0_Wz_r~fRMd8P zW@I)}69DTC$CQHAwJdeBUsF%*x_a1g)MDE;R}-?LH(##~&C*Z;K`pJA97h-pLmG6i zoXIHrtSer8LM9Tx3G_&;2ypd?5Pt_^T*`B$mZ=EhDj_)eg^ zoPUxahx9q8tYvN~&;^D7HIqYf#i-@-vAVkF8$pg?Ie4LNX+o4nNUii8QyOjvX9x=0 z>_6!?^&WC5mmz>tAs`3nTKxwG8Y9KJL%8^nW0vBN>o} zdeIyV8H{20MsMJJ%PyHnp6$vph#rs!$$uNSq63p?X;jWZK1P5$FA-F8d84p*7GR8L z7kYHI=&_2N&#^cK^waJ6ppO8hkiAF~(riM48h)~iW)BD34gY22|0W9br1`{|OiJp` zjam1fX&arE`E+xJ`64z!C2FsZaitG_RSKXrN#jQwm_>W5oW5RsLQ@NZW1L@u%Niq= V;ZPF8awh-)002ovPDHLkV1jxf4A%ev literal 3193 zcmcImTZ|J`7@k|F(@tmF&g^b?ySsoAjY1^on=dAdi!5F?fCPdGVM)-KfR_YK)ObPh z#gM33gPK4@V?;3uJ_zv=-Iy3jln32NVo-ywu*E-#$4XXc#$ z{{8>?&%Cx_c%2eXh8c!Y)(;JC!gCq3Ldr`mSY?D7rrkN0km)REwAhqt!gr+4a6c)F*a-3mYpkC zH}c#U%pwLB$-z^)==r3^_T9YfsN+05GmGEHp1UcjWy(d)^-gxm3%zdKX=k9!N&lwv z71tR`=mVE>Km$L|4?up$gwdnM@p3FzYE-xIy`6#YbspLwGm<9>FhkOP)#|WQ%tT~c z@&~&KT#oAoD(z5eX~6gVabJQ8G>!DE?d(J}gwSHNGq6Moz{jfRO12B}?Li*%*i;HAz5d@U z-W`_NnaZ@#T;FbK0Pzo*)ska{_`n~DDA@1JnY)(uAtnHY<&7Qs304ApH~S3Vb@`kNMnhlPNF+IUcD3wZBt4V7ZOvLA{Cr6bX(L%h@2)@ok6l z#)b6d6$4{s*QS}En`k7m7^F@-p45l3^NnjB**RVBWlKiM`@dFKOxLvUa?q>-x}W8T2wi4>r`Nz>mhdCQI2 zyHm!~$u4l1WgFcF>biX|T`B;gmvxmkj~8ORRV&-KvNG2>I7R|WdQ${eVUVPnV5J6JaHP#be!|C9ln5T7I6 XyKU^&-KVtLckKGL!-L1yjJ)zc=CagX diff --git a/root/opt/phpsysinfo/gfx/images/WINNT.png b/root/opt/phpsysinfo/gfx/images/WINNT.png new file mode 100644 index 0000000000000000000000000000000000000000..47eeb02d10476f0fc35853a98e2bd97b9c8e20cb GIT binary patch literal 1794 zcmV+d2mSboP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd26IV7K~z{r#a9VzR8f(i%}(h{Ts1p>BK35yU#L0Qyb zj1l4z6+;k%(3$7CZ~iQG28C$qOHS^cx7>67eed1>N8+6SuSnV1nMm2$nfT9|qA2+V zjFktNvQ}s6CjmwM1!yPeiuyC`Vc1mxrj}jj^K~I*!;_u_7N#N* zP*tuKGOp`N>T#z2YJ`;}T~TT%MdV}Qa11VnC@)zk-c#iD=7Q{b_~!zQRmB4-FOn@` z3V$RokFRn%d86GS#{9i~TzW+gvPpsf+)VM)rAW!WNrAgyAMDZ4@R zcx1Bj5oO2dzYHPOqMs?>+~f6@Zv^4_v^0)50$*oj2m<-0xPT}!t1@E(u>MCWBuOiA z7KZ>PEFMh)kc|gQOH0#rzd8kEyL85GMc*4xd>+5&(>SmUq8eu9!5+~aXdj~MDKvjnwG@D0b&TdUn9>ijC=w`dR zEr}9G@kNFyA|U8Z7El=%fQL9ue4=4tPrwFPKynUv52C6lApE_sFBtv>WMR4yq`fXH z>sjhg#0gVGK=(c=1Uzbv37{<`;>Ex~L&N~U29hHGXdZNWcM{i5XD8 z4MG;Ja5`sEeNKOO0@p}?%2(}FZ zXTxs?P}P(<(I9nM5djz%#A_T*KH2RSV^jm^+Ia_fc-~+)caCvz$3ym*0A%na-Tw)? zEZ;yPbY0IvFfT}2VF$y`0WQOT4rn4G{622ngi{bwyC^%mdV$NuZ;}16z*i6D7*)aw z6daev*jV^GMLN(>{hXI@HqMw#MW_cs5HCHKmR1w=`^RZa8vzkp5F`X4b!E37ByjKZ}3t-AogAUaX)eW_IXmN3|13@=dDYHBfK2H=VXp=UmgwO zv^OLRu)HtEsw&+{0-CobWH)~P^JaJ=g7uu6o8(< zY&ty6=#Rl_X%ht1RmlRjZb{65vIm4AsJI|wA)SRPfVSh#h?o$*55gc1-w6Kz@ICw~ zk+-BW6I=0?-MVE7`Z@@(Sy}`Eo%+8Dc)KZH2Y@z^P|5`vrFVYB4-W;(0SM!BU>5;p zKpp1n$CE#e#bF9!w{FMQMTpbW&v3hKE6;aV3WD1Q%6!_?Tt07Z4&Sie!B3tr@y(kO z1t={MK1u2VBJoy)4Mqae(}z|XK5XcaL39LXU=0PJo8WLX)Vi`><$mArguquuNpbw^ zh;9~D!j?i=?oOXwc;%LYAOK8+5Hm>M1dyh1f7m0y@9>|(>8Fp&2D*-Tidl&S*N7cb z!0#`i=Z28=2ns?;qOVr$^8mb+yV2*FuBzifJlUH!ek|tI1(-GwMd=3-gsBT+0h#hC zL@mVE@z_FD9i;p9KEQ2wd5wb5xtP<6tX+)Ghrf;ZM8kx^R09eXr8l1NHw1nOWXr_F z$k$J!v2b644=D3UxF%~jsQ=uk#3SCrAU}k4O-6UT(Wf#dtW#CB7?U=FgsLLGfRtlI zD5@e(KkRYXkyz3-vhtc+mdE80FTpD|N@EXq57Y>;MeBgOML)6xlScl(XgFh%J>}n} k&P2-2&P2-2&I6bJ1pK)TEzRzbDF6Tf07*qoM6N<$g2$yHu>b%7 literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Win11.png b/root/opt/phpsysinfo/gfx/images/Win11.png new file mode 100644 index 0000000000000000000000000000000000000000..0d7b8ac192808b0d31f34de2a04c56fe3f15a5fb GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=Dh+L6~vJ#O${~!CX%l$B+p3WQmUrf?mc3Au&JsQztT=lKf|U zE+OI1f5B7gtSLq%FU}-16|wR3SS4IxT+Am?dSC@J+a1OeQzvRqapl^^&t14lppJ9+WW4%w**UTFl_->gTe~DWM4f D1iL_q literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/Win2000.png b/root/opt/phpsysinfo/gfx/images/Win2000.png index 3147daa15d1640ad4e8abd2f4407263ff9c0b616..1ac8d7c6efa6ba27acd37f115b6a6f9de50bc776 100644 GIT binary patch delta 1087 zcmV-F1i<^`AkzqtBYyw{XF*Lt006O%3;baP0000WV@Og>004R>004l5008;`004mK z004C`008P>0026e000+ooVrmw00009a7bBm000id000id0mpBsWB>pF2XskIMF-;p z0~QGo-OplO0000ObVXQnQ*UN;cVTj60B~VxZgehgWpp4kE`KmCI2$xh*Z=?nl1W5C zR9HvFmN95kQ51&HsJIk|QqUzR1<`_8EUA;3N*1BT!4?Ebx8fAHEVD^2ym$8)}IyGV8FW6Jd~Jr^b}O1 z#d-FgzeF}@fLO3%e>rrt6I5}{0fH+?v4`P*M&kV9bLt8ei4LY}t>e4G)B9+S` z4IR4*E{+sKHy^k$2G{l#+15=3ENFdiFIeV}q($u0ZGUOl`5ig>QInU5*uH43paO_6 zA=fHX0%B0LL`XtxfzouUIAmWvx+i^W(Os$qf%GUY}#VD5njhGg&ij(`J4 ze(A1^V)BVL=o6*;CjwmdLB#X#opD7%OZ*1@k$+>;P}=&rQ?oa}C|GY#Ln0t1wmIZi zcWd&t=vzgY-+bubgls}p`ckPEhScqL?maNke>Jj8bWCiUmIlO#kb6TyzVd9##`nL5 zvbxP$GoRdl)swDn&^=M;xVmFm#_t1K0o*xbBk)E7_~5vYj*=q4x4_zRp!GSE^ zqJQ_?Gzi2Vt_np@ie6WWhI+!S^}u{fQvxCpJm-vRK9@bDUeL+|UdL=QkhS(>8VXN4aAmF?e1 zmfzOpg0q4iw1xkJcqRKUdMYq)WP|fWHaJgYgY!cnzX5PVdE~&+OFRGo002ovPDHLk FV1fo0cY@fYBwF-%z!Rt{LK`p8K{`SRYO5$w3X>5JiqV0dtYAW53vc|c;U>s z_q==W`OZ1ty?5S!`RI#1J09C1B0a-HgU6uvQo6R|H+}l_Z4vvx@ZjO&r>HJH-_)VXc;v6`eNAwkRIVLYI zVeCS)5lBq+)_+#ftzaG3v~QTunggET40|@eqdC4SIe$`E5@(Od2=p9;ADNA1-Cxq0 zb|d^o!0}eTS~?Gi=hoM3o@d{hh^o@0Xa_)qq`)HjY&{~P(b!Op<@Fe zs>!7dK$-w()&p@EeSGCLnevB(e25W*0y2Q52c!U7W?#3gKo@@Qmm5Cp^>`o=Fa&3S zupgeNCIC9+tS8fq2tAt-(zOj>eqrV!u`890N~~0Pwbje6E39ZbtV!R6FCV)HXn=qCV9&By6~u#kMzhY zol@Aca8X9wkG~`}?Nr%Uz7XE36gC9sRX1=z&i$ck9`FEH@Q1aGv0(u-!_=EPnj=R7 znq%m@UE&+^A?3@gzY)w+e9`mOY1jZD>R9y&=&A7m`OGiKg`=D^=w>4PR%i$_kEC5`r_Zq(mzT7%)pYo z{z*>eu*qB<0^L8RqBL2cQgFpVGhkA-xc(WvEF=X0+_Kt@L8)>>IE&Mv|^L6s!oA=-%ZBD}$Qihsn=Tu0;z3TDQE zRgq8A6&90^59dyDt%*!P1Uj*q@L;55>Kfb=jO0&Ze0Mt)L!iw z^|cL~wQ6Tz?1k{?QD@}iHx}i)1=g3Rp)9+fN2>4W=UQi>G+#sQZAKn#1(REqeh-C- zv?!X!KBn>YBjFUWph-NYpTc(_=reMj1Y~A9y&gHUu#gF(=UlhRN28%}tWH626Y}_( z^b?Q)WzwrO*&hYr;(Z`62+JC4+P~4zX^ah+T$X^`;A6!M0oVfs#t4lwbs0sXryZFL z&VJNKOAUvwV(;XQywo7S)~A2job zao)O*leLlzx N4Ieo=c*%Y9>_0?K6D$A# diff --git a/root/opt/phpsysinfo/gfx/images/Win8.png b/root/opt/phpsysinfo/gfx/images/Win8.png index 96f0ae100c5121340c25376211bda68920ab5c88..157d35307adcefc5cccf919eb757d12d199aa154 100644 GIT binary patch delta 784 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 UY`b*yMgRZ+07*qoM6N<$f;}vDssI20 literal 3211 zcmeHJT}TvB6uvWeXa8``(8StABN0I)jlhZ$v^95$OwxxWf}|8oA0(54(m+TsjO-!9 zTC6aT2!fIbDk4D$BT+C2>LFdtpVBs+{hOaV(;0W!wb5lv3VQG?bLZT%-~GOG&Ye5E zttG`p7V{P}LdfE<+m6CLRk@5bjAGJUH{A5+juw|9S^4B1vo=D+RA(=*M<}*mxu~0& zu~vj)G99-3vJ0Q6)R-?UCCf74{+%i5{Zm^P&}{F2&?3*M>utv!%}k>Kv@57B<5V1B15*SwM@T_*148a*!aB zvfdx?5J4o0+(C=Cwy}CS>C(sw0t5FSz7VzsLBI-*L?pLF@f;VF(Fr0e@>m&#M1H~9 zUb~c0<*Nmrbw2uF+$J*EAjv*iVW&7AMpoc;0`Vh><&;u5o>NL9gy#5UnQd#UQSpYS zzX?F@Z_svzVdzBz5VS~=2q=LJ(0N3G4FtC$qycq^f{;nGO|2_yL>^N(P~px1KggJL zvc-sXI>t<4*`UW5Lwu9KW(c!s+{_lqZ$dOrQ@oCTFIyHqe+*~6)QMEk*3#{XPZ2O3 z%NPL>tOFcLF_OlPmQ*W0Ld(rJJ@cfy_wE=~ks_BjoK^uM0%vZ#j-w>#zL|zxv7Rw- zv}}+lV_?pa!lc^^R4Y}}=baC(k8sO1LIUpLp@x^!n8s!X1zQ0!Y1~))uGECRdsJM} zrf_tso{a62#?uow>@Trdv$Fsh+Ji~gHy%t7ct1&+pFBXu*zyK@X3Z@QOaKCHa~&Brrb1 z%0697S^DZwA5A)`G}I@?qUL1=qNPhUu2*yX-gf5fycEsS1+lNFEqy{NJ@ zv}YT$b1r7*Ao$zzx6JKw9jdvdVv9VcYe;!DOCl$EHRv^9)&(@1w%#Jm7UiSi-sXkl P^9s;WSZsS-aI*Oqlj-bA diff --git a/root/opt/phpsysinfo/gfx/images/Zorin.png b/root/opt/phpsysinfo/gfx/images/Zorin.png index 215ea8af00685fbd17f5bacc35cd4267210dff87..ad9b2a3bc10af368657120228ba06355b926bf4b 100644 GIT binary patch delta 742 zcmV0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01m?d01m?e$8V@)00007bV*G`2jc?+ z76}mD&thEw000%v)Q+cjKy#F&6#`8oqg}lymcb-s!%Z}RLlt#Ev_XquGu-q zw+z4n^R!Sg;D5Gc1SZFzV@&(u+BId0c?YN%fWdObuwOb@zz^mfprYcoWdg}p-h`Xi zr443S4TXw|+m%_jBaIj03#*|}F(*{a2^Dja4t8V=4Re9!lRnXIzX2=Qx^Jv!^gfWc zm|t>#1#CsD|r7&vBA-=mGD*nCUV_0F!z1H+OCV2y})oS4*{Z%2hirx)>SBg{5 z=63_1Wq)qGz;p4>rw9lOIe|9cwX^a35wi)jAO81?pU^%-zeSJ45FLsjH9E!hl6J72 zk8$XD%&&vHGQM7Mjl)h$ypjR-s4t8?YxOu^boL6+J+Ef=Ea;7%F*s`yPdj)GsF)Kf z=7frhzQX}~xAzbJTd*1m6%{ni>a!*qj5b(gHD44eD%c65NIdgfhi|DmXzn2lhgc1T ziUD1DX~N9wpl`}g%sW6u3rv1jOzZN9;%m&)LPd+)lW~|e2HzJnI-umE3;+NC07*qoM6N<$f>An4d;kCd literal 4217 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 N=<`SZc=(4e{THBBVe9|^ diff --git a/root/opt/phpsysinfo/gfx/images/dahliaOS.png b/root/opt/phpsysinfo/gfx/images/dahliaOS.png new file mode 100644 index 0000000000000000000000000000000000000000..8c5c831ec66e50f9b96cb0c229b03d5d43b6977e GIT binary patch literal 777 zcmV+k1NQuhP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@Gd8K`;w1n80(wbAK~z{r?Ug-i6j2n0uN%XHXd!}-(k_Ug zm7uO4mDZ+H|Ah)_sh~wnBlrVE#Kz8q6akIoH$((eh*$}tVj+Gcj?bH%yWCvQ%+BoW z3W5h7mf3mFId|^Id&96%oC-UOli>=?LD&BNJ3;danqGx(@DpZX(q4}@Xx_2rKcFzy z;Vw*=Y&>DpuI6eOn@2W4gJ`!L6xa`E;he)w(6r~xBU+Ao;N^+~)}}lVod->?zB1<* zc#Tt}@p8pAYf~PGW}r@^VYp#!$^+3qF@UeI1}pFkUczVav?;9zpuO=Jj>9fX2}LhV z@_YznN>u}CHGnTPy2x*-;qb1*QSI^j#&UA12Vm#?c9tZ*)BKXj1_t`W@IJ|pJOtk- z5{L87`6J%fw%X!M*g?)^$Y)YM@uy=_JbJs%YMLOl;d&;m9n_Sey-n&wqGN7-kWG8; z?I~+~QGdfV338ugwIcdZU0_{_bfs3=>$25r9OT}~YNcp7<|NY5(Ss)v&#hkLAlKW_ z5$%sfiMpUQ@z!6g>YQ86MnSH2y;oB_rS85cl#ysAv_W#=Cpfq%Y!Kw^hF4Z2XMyH> zO}Z8Qsgt0Y@RnnigpNsT1vwWWucc|9FHVF#Cfgpo)NEkjdzr z-+~9A4OexX#YhIwhW`VoHGpZjF0q50t!kY$@Fnna#W8C$Tu>m|w&$2)e&9K88#Iw) z%C_^nW1-aHMjbTM-4ShD)2@qUySI-!XsYGVOe_vR?IHXIZpT;!eY|9Y00000NkvXX Hu0mjfLEvfj literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/elementaryOS.png b/root/opt/phpsysinfo/gfx/images/elementaryOS.png index 263d4de4a4c427914a88d9bfff56ece26ddab399..f50452a5e5ce7c627eb3e49f21cdd8309f7c30c7 100644 GIT binary patch delta 1176 zcmV;J1ZVr(2cHR$7k?lK1^@s6b9#F800001b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^ z1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9a%BK;VQFr3E^cLXAT%y8 zE;t)BPS^kd1Q1C?K~z{rt(SYKRYeqskC~Ov9!e&Gq827P8p_pTXbo7kmesU}X`@w)xC=K7}FB z5Uxo*;am6zHh;sD&>Yg#0-l0T;9vL#?4xQq^0(j;IGZjI>n3;<#=}H-7Vd&rUBOjz zAXDH5$R#`9050cPXaFVM3>rKNyI=v#h0nqF7eZ4g$^X6t7vOzp1etQ?>){W0%!Wvv zU?1!NXIH6*;Ail;1C7-e&VYSq`h`n%9x9DL45wiU=zo-Hx(Cj|8=+P%2jNO+BTIkRcBgnIl^T3rzde^><5?8BCF3WD%2JxP|XL|ApxZQ>v8U#9T>rg9~eQRT9 zv0SUc;Ox7FTAf~p|KP#abED?)yQws`o}RJTF6= zP^&LzZhv@w9BSwexCkRctxjXWnM?|`{F(r6S(dXt1BPu#YNlB$&N$X~xB?wQEuWm- zS73V1k{Q*>4Ygv%Gmpo*1q>&bzZ&%i_xFKNOP1TIJqMue!fNm^iPaXIeeFKwP!sqb z)`VKRUIQohHE25=GRrMQGSfN26`^)@x%7+S2!FJ+Aw}ktvoIaBsqGK}%Pd5?7aV~3 zJC9xgGiZ-cOIBkrr|bu}Sex1o`S}A2k!}Ms)|a7{tx=E^MX}6^I;N?(yA9|=(01Wn z*kd7*OS%{Q!>u+X$WG1qzVo~dDYCD3z}zs}hN3*!v>nd!Kfz^*H5uFnm$y>xv#X{v zd4CN{lY^WII&?5rlp*iHwOzOy>ZL|>C+ILIp>)}>!>8dG{0Ld$=AOIk8ux&5B}($V z@Rp^G@W9K(Ix7`2WLyQGo3Qi=4;me)8KlV@l-sKD84w#+I`aW!X< zJOmCx46}ZaCQrcGpi{c7BcW35z~^Pp+<$+w-bNS)OW_A_20D+=EQ{B#SD_Ew4_;ng z29ufl>N_4b#(a`i!2zguzzqlg>`eVV42!_qkbCcQBct?AB^vic9RQU}UQ+4U4`)D< zbQ)hsyVE-m&wC?d4$OzC@C10OX36WCH>=95TP8i%)9fd3udbKc!!Kap+Q^hK?tjOK zq1MZWYm`2696WsTUh6`l&>@Z0Szv0eRvLQ`OzEcGtgua#`~3o#h<*p-*>3~e)8w=J zz|`w?&i{H=q&a0Sc^2qsMuj2imD{gj+YCpU1|~B1*>`@0HzDggvT7L>UO4>>_Z;_D q^Bee?X4y8+`QDKE^;4%p;eWj8@e%ZusmpZ$0000^hS64_#Ncy4J;s5{u0d!JMQ-1(J=GbNc00JsWL_t(|UX@d2 zuNyHC^q7w?%z4br%#3AbX72x2W1kYG(Nm@FC)+cc-SzH}{|L^gn@*+DE*1O=n2M3X z3~XcuM+EJ}r8k42`|~=EX|6Vf;ZXhsJ1mbyS4U#>@Ii`9sL@r_nA47DF)g)7-R)Vv zws5N|0)MuIY#W2^!jqhx;!^m2w1uJ|eh%ZTiTi5^mBUuQuPAek?!o0mUB{$MaO&Zq zB&v*1CkYjn8cg{FVbY5j81c2VUVC71#XBp zrZiF0c%w*DVIyzr(_M2$iPtw785n|YcEw%H+JEG7uFEL6NK=PmIcjAXKU0>tf^E0K zNW*dH4%V7o2Mqz+4!hZd93|ue5ea5dR0+=Yqg`h4JILX}5`02m<2OriHq|p>4zwGm zZ!IB>lH;sn-?z`|alM-xBClsk9P`u^nW7|K*p^0i{p9Jhz!3Fw6hs=PNS?_vqK+m#pbw)tYJ$@ zN?HG}$)oc_*EjFVL#?&AtPH!wTr;5po=a>w%A#Xw+pIukFm6C^U2WdJz7F&L0Rb8{!z7s==>Px#07*qoM6N<$f?2$g A1poj5 diff --git a/root/opt/phpsysinfo/gfx/images/free-eos.png b/root/opt/phpsysinfo/gfx/images/free-eos.png deleted file mode 100644 index 0cee49009ab81c13a6d5e7064b861861aa295ef5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1676 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 diff --git a/root/opt/phpsysinfo/gfx/images/iycc.png b/root/opt/phpsysinfo/gfx/images/iycc.png deleted file mode 100644 index 4a92f700df78dba33d63313b46a64d8752ca0138..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1636 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 Hu0mjf`>y2) literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/images/pfSense.png b/root/opt/phpsysinfo/gfx/images/pfSense.png index eeba67f8698e6388f6d6108954f0fe4670c2f863..0042992202692dd67bc7793dbe06473fe5c46649 100644 GIT binary patch delta 451 zcmV;!0X+VZ37rIxWPfmBX>N2bZe?^JG%heMI2$xh*Z=?lj!8s8R9HvFmQ8YlFbsvA z9s!2tDB1Q_-S$>p=2%^(l98<+o`I5>elu?puq-`fnEtxFAfH=QM4bZ2=R`~Zi zPN)L$ITyHZTYnyGu$6>3+V|TpEHQwOADX~IPhXZxE*){c zRkLjja*m2KmudJxc~%@_ax delta 1084 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 T6DNi!a58wh`njxgN@xNAoF0K! delta 30393 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 diff --git a/root/opt/phpsysinfo/gfx/logo_32.gif b/root/opt/phpsysinfo/gfx/logo_32.gif new file mode 100644 index 0000000000000000000000000000000000000000..86c1b5e92796fe4eba2137c2c6f9fae8e6d99d0d GIT binary patch literal 1285 zcmZ?wbhEHbRA5kG_|54JY79JeLXF0Ej?X5J$*e>CQX?#ZOWWkbLPyO zvt-edHLKQa*|cTPu02PN9XWIA%$aj%u3Wlu<=T}yx9;4zcjw8YCr_R|dGqScn|E)% zeERa`+m}DT{(!wcN{sXnQ2fcl$iVQQK?f8Npgh6A@t@&;poGVU1qYis*#E6ISh(x3A{zd4940Ecp5R)_WcK7l;Gz~@88ZQv4+|6>8U;AE-1__Q z5G#+I_aYHN0fmFT($WGv9tDZaj7*Ab8ebb6H%*cBW)8?uQgvfEsFrm6-3CVoMnUG7 z!+o|cUHuHQMHLtJe%ap0s_}wtgLTczCkzrrH+CGD`ICcLVjB0Oe%ZuM5h+HVjuVB4 zU6|f;+jOkgPCd>grkf@)aS=;X5R=*sgBctWCE^Fl#m|_}74cPB$RZr*QP{%0k+Z>p zo$1j5#xQoN2@6Wf6djKUIKKGM)VPbajG0eT!?cO%Q=^6}FaLrQcY>HICODVK)>+)^ zb%>k5%&AwkLZQ@wt#uKD%oB#DZUecWQIphf9AIPr}?# U5<4!<3H*PIS1$O^!opw;09hF!X#fBK literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/logo_48.png b/root/opt/phpsysinfo/gfx/logo_48.png deleted file mode 100644 index 2157475bd6154053ef5ef9a1e2c207e147a9efdd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1819 zcmV+$2juvPP)vxSE)3VtjBDUiQ(4ed$9>*<@d63}^yLtub`TrqwKwcBn)o zR)>EJ48zR*clH6e!|Bn^Q%d=Z&8h(SEzA0o5aNk0g!tHToMIE&5-iL5vu;_|!D18H zDh$JjX@Dp;k*&gU9HGCczYl;?ikAY438fUeVHoJTUTiK~hMrERm9Fb}y!AUdT{NVcWLLZ3!Dr@zPfT@`P+fjM8;fCnM{W1>1l?BhPZR*4mWPxAel^V zC`N@sWSg3>s;hAV0a)}^N}h})7Xg7)P&MB z)CS|}4<8cj=y1!aPd^2v2!8u5!ZZOeVln35f1ltt-=P2gJHYh1zfdZbBAHB*&1Nx8 zlhV>s%FD|Mg+eaDmX;P88yh)&`ZRa%-p%W8*4C1F_uZTz!$AM-H{{F=N=lqi2&b$J zyP^U#4bQ!MuCEgeV(;EfptI8@58(ajC$jN4_Wu1#0@hyxot>Rrym)a{eQj+mCr+H; z%$YNIJRZW~Fjuc$<>=9)q*AE`Cru;$!3Vk7{qY}YDU_B%f3EJA)ICt(G<|3g;B*Mv)Cv&92VU*9e@IuohaP8Wfs~ zIedM6U>Lc&i3x;ZVAa&*`8qpyVpmikpFG*RfF<2( z0vZ|`TzhO8X>EEMnM}In%zN)KfBZPkjvZTjk*1;6IiGD=Kut{zM~)nE%eQae&NV7U z;Jfeg7OwHe8>Bw}oODYIRwPo;yUbT#CEL`rW?R7mbY180;ls4Iw-XL8Tq9+(Svr;l zApmV^is08@BNz8;0HtY|_4Ul1I>p?nQiab41aew z+T`ShLJAU4S64?}UELpce*E|`mo8nRySsaRC&$4vFo0)Z0K2jhERW!u#kS(W z(}2EglI&f(3hrNY0m|!jZ80}jaQ|nLwJRx6q0oj~qw@PPUw=JEW?A%J4s-v0tXE!H zv+bD(uwHwO^oJj!KX`!m-aX{#C}MVYAqUnpoL~^EriSd>Z{w7e0Sm`&Pa?7Ac%J+B z@r;ZVwurX_^S}WR0;{Gb?@TXD6Q%2`qpwofTZB#G_u#is!+KRm5nF!Dm ziG}22#iCRm&uZU?5ApT&p+9)As!dKzV7&Df+TInr6x!@8^3kKb>}nh86Y#u31p>$Vj=4r~`M1r!@E1r!?^Y-g!osnS!@IUlob^f|Fvy<28aQHVl&z##)S}n4Fm%J_&>u$tqKO6D$D=?002ov JPDHLkV1g)AWeflS diff --git a/root/opt/phpsysinfo/gfx/next.gif b/root/opt/phpsysinfo/gfx/next.gif new file mode 100644 index 0000000000000000000000000000000000000000..97df05a6966873e2cdc1db5fd251c07757124439 GIT binary patch literal 893 zcmZ?wbhEHbYFD*?iXHK12 zvTVtlcW(C(llPkA5%{QyU6fm{;DSOjGmC__n8Jev4o6w|1Y}OEU}$3O;^bH{ o=f}hb&u#@xxdelTMNJHx8hkHi1}3?5xvOifu`qafsDZ&605hLRw*UYD literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/next.png b/root/opt/phpsysinfo/gfx/next.png deleted file mode 100644 index 53a34751539e0861d217c648481b6ae428958fc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+u0VEhcT6iS@DW;MjzhDN2vdL#HfV?D67sn8Z z%gG50O+_pYPaA(c{qghZkq^^zoF~UuR|~EB<#~VG!dLHWigpVh-P3ma{OcKg zO{qI9ynuYFD*?iXHK12 zvTVtlcWS5u1>e= zexELE?theT`}w__KVL4K`2BgF%)3BYq4(*RXQ*%8_2jafVg97Q_WJK6neMX)hg@5% UC3`P92WTUMr>mdKI;Vst0MtT2-T(jq diff --git a/root/opt/phpsysinfo/gfx/reload.gif b/root/opt/phpsysinfo/gfx/reload.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b73329f9c118a8ea46c2bba270d838a1bd49baa GIT binary patch literal 935 zcmZ?wbhEHb6krfw_|CwfoFG5v!W7FIqnMQ;ep9@9PPEqVFG*h>pSC@^<=-ETEEU%- z+t!2iLG!%wHl*bpOko%WqaiSiLO}5+3nK#qCxZ^iPoO-(&e6gk%ptO3LBhdC4o)qO z0}~z|Y~hj+NpP6B=r9YrvL3?$L5F5$J_(kH6%5MmEpm=gIvffM4@^;X-&XST6T^v# zY{mO>4s32b(`!iy8(2_#ButL^3%VaH2WCpD^U)OZxp@C)2#hU)y+@T%ZNzJigNk%37 zz-WYJwT%teVfiEI+B*@v4ey@58(ld4VY_&5-ox`e@AKg+0U-I`y79bmuw_~y6+4rZ zBG5EdFDS+@M0OSE`>d7SUDOzKZ&h*4eB1iX7tOd9RiYtW2mQ--bUahxr1`i{RG@dM zL#}_X=DDO1{;UI$pFu=dLYT_=5d8WC-sLfjr7UO-HKMAwa=!>)kEhvuwre zuW3yF@ZxFCkI*+ad|5kOX%5zu8IQjhan)UqgSrFGA_0nQFn@Z08DSEUToCSz4Z1ls z&fDbq$T&7|6iq$_uDI$@q1_kQ@dfqk*0>{SDL6V)94@)ete)j++*>bIc9sj}Y;R1o z#OpH+Yt-^4wfv{nern^iVag80r5dH3``O|{VPwu;JpI{*9FW*4h83tp3T&|M&O*^Ys7w`~Q)c z{+givq^kamlm7qz{{R30A^8LW000gEEC2ui022Tc00RUt(8)=wz3FNR*x8rS2w;UM l%@CB6(7Xlf1jG9hY+=6(01`W!K}IYZkI1BQ$y7!F06Vd#K{x;a literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/sort_asc.png b/root/opt/phpsysinfo/gfx/sort_asc.png deleted file mode 100644 index 6393e0e43d2e2f4425b652631b3f1822e2071c56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7T3?v)swEqJsmUKs7M+S!VC(K#9UIO{L0X`wF zfByV``TGCv{r`HW{JVDZ|ME5ePM-Py{rmsVU;h98{eR+&f3p_+Te9k3&*Xpq|NozG zCwwCPoBJg|Nh61AD=&ee)a0r@87@w{{8#l!GnAE?md3| z_|Ba>|NsAIfC0syEQ|~cJPbM@0gxHYEY1^7damC4AdBi!88%+tGsK<6ecEZZ9+&b2J1Q^Q9S_#I^rsY2WEqS*$C>w#eJVMx)BbKv0B{!5RSG3qm;n literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/sort_both.png b/root/opt/phpsysinfo/gfx/sort_both.png deleted file mode 100644 index 7a1c3785525d5849c4f777230e07207d283bd874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7T3?v)swEqJsmUKs7M+S!VC(K#9UIO{*0X`wF z|Ni}Z^5n_;_wRrF`0@Gk=U1;@{r>&?@87=<9z3{r@809bkMG>M^Z)<<$qS#q2WsIh z3GxdDa^Zl%_JvX#P$JRO#W95Ada?yGGrPnAm8O%S%;{Oj56n28mfvRB|Lz_~a@6~K zZ<$lQ-ru{+kSKR^Z}oSz8Jq>$e2lK!9cHlaDt|w%QR~CKy|>v;+3cv+K6B^r?&SyX k3an*L5Br!zopr02k|Y^Z)<= diff --git a/root/opt/phpsysinfo/gfx/sort_desc.gif b/root/opt/phpsysinfo/gfx/sort_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..00e76f437482b02251233dbee9d05152d64b3fc9 GIT binary patch literal 129 zcmV-{0Dk{RNk%w1VG{ro0J8u9{QUpv>;JpI{*9FW*4h83tp3T&|M&O*^Ys7w`~Q)c z{+givq^kamlm7qz{{R30A^8LW000gEEC2ui022Tc00RUr(8)=wy*TU5yZ>M)j+N1z jXhUegk~RfLq(jgZsNe-dqaYta!vH!k0HFj469E7_EayIx literal 0 HcmV?d00001 diff --git a/root/opt/phpsysinfo/gfx/sort_desc.png b/root/opt/phpsysinfo/gfx/sort_desc.png deleted file mode 100644 index b768c6fd2b886b4c8739f62e75dc8d5b40aa3ad7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7T3?v)swEqJsmUKs7M+S!VC(K#9UIO{L0X`wF zfByV``TGCv{r`HW{JVDZ|ME5ePM-Py{rmsVU;h98{eR+&f3p_+Te9k3&*Xpq|NozG zCwwYu;P_{+Ofa zk9&J{*i-HHR&y?UyYMa74$fVb1!=tUbAAfl * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: autoloader.inc.php 660 2012-08-27 11:08:40Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -22,7 +22,7 @@ error_reporting(E_ALL | E_STRICT); * * @return void */ -function __autoload($class_name) +function psi_autoload($class_name) { //$class_name = str_replace('-', '', $class_name); @@ -30,8 +30,8 @@ function __autoload($class_name) $dirs = array('/plugins/'.strtolower($class_name).'/', '/includes/mb/', '/includes/ups/'); foreach ($dirs as $dir) { - if (file_exists(APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php')) { - include_once APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php'; + if (file_exists(PSI_APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php')) { + include_once PSI_APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php'; return; } @@ -41,19 +41,21 @@ function __autoload($class_name) $dirs = array('/includes/', '/includes/interface/', '/includes/to/', '/includes/to/device/', '/includes/os/', '/includes/plugin/', '/includes/xml/', '/includes/web/', '/includes/error/', '/includes/js/', '/includes/output/'); foreach ($dirs as $dir) { - if (file_exists(APP_ROOT.$dir.'class.'.$class_name.'.inc.php')) { - include_once APP_ROOT.$dir.'class.'.$class_name.'.inc.php'; + if (file_exists(PSI_APP_ROOT.$dir.'class.'.$class_name.'.inc.php')) { + include_once PSI_APP_ROOT.$dir.'class.'.$class_name.'.inc.php'; return; } } - $error = Error::singleton(); + $error = PSI_Error::singleton(); - $error->addError("_autoload(\"".$class_name."\")", "autoloading of class file (class.".$class_name.".inc.php) failed!"); + $error->addError("psi_autoload(\"".$class_name."\")", "autoloading of class file (class.".$class_name.".inc.php) failed!"); $error->errorsAsXML(); } +spl_autoload_register('psi_autoload'); + /** * sets a user-defined error handler function * @@ -66,8 +68,10 @@ function __autoload($class_name) */ function errorHandlerPsi($level, $message, $file, $line) { - $error = Error::singleton(); - $error->addPhpError("errorHandlerPsi : ", "Level : ".$level." Message : ".$message." File : ".$file." Line : ".$line); + $error = PSI_Error::singleton(); + if ((PSI_DEBUG && !preg_match("/^fgets\(|^stream_select\(/", $message)) || (($level !== 2) && ($level !== 8)) || !preg_match("/^[^:]*: open_basedir |^fopen\(|^fwrite\(|^is_readable\(|^file_exists\(|^fgets\(|^stream_select\(/", $message)) { // disable open_basedir, fopen, is_readable, file_exists, fgets and stream_select warnings and notices + $error->addPhpError("errorHandlerPsi : ", "Level : ".$level." Message : ".$message." File : ".$file." Line : ".$line); + } } set_error_handler('errorHandlerPsi'); diff --git a/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php index d7885c0..a90b8a8 100644 --- a/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php +++ b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php @@ -8,7 +8,7 @@ * @package PSI * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.CommonFunctions.inc.php 699 2012-09-15 11:57:13Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,12 +19,19 @@ * @package PSI * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class CommonFunctions { + /** + * holds dmi memory data + * + * @var array + */ + private static $_dmimd = null; + private static function _parse_log_file($string) { if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { @@ -56,24 +63,32 @@ class CommonFunctions * * @param string $strProgram name of the program * - * @return string complete path and name of the program + * @return string|null complete path and name of the program */ - private static function _findProgram($strProgram) + public static function _findProgram($strProgram) { $path_parts = pathinfo($strProgram); if (empty($path_parts['basename'])) { - return; + return null; } $arrPath = array(); - if ((PSI_OS == 'WINNT') && empty($path_parts['extension'])) { - $strProgram .= '.exe'; - $path_parts = pathinfo($strProgram); - } + if (empty($path_parts['dirname']) || ($path_parts['dirname'] == '.')) { + if ((PSI_OS == 'WINNT') && empty($path_parts['extension'])) { + $strProgram .= '.exe'; + $path_parts = pathinfo($strProgram); + } if (PSI_OS == 'WINNT') { - $arrPath = preg_split('/;/', getenv("Path"), -1, PREG_SPLIT_NO_EMPTY); + if (self::readenv('Path', $serverpath)) { + $arrPath = preg_split('/;/', $serverpath, -1, PREG_SPLIT_NO_EMPTY); + } } else { - $arrPath = preg_split('/:/', getenv("PATH"), -1, PREG_SPLIT_NO_EMPTY); + if (self::readenv('PATH', $serverpath)) { + $arrPath = preg_split('/:/', $serverpath, -1, PREG_SPLIT_NO_EMPTY); + } + } + if (defined('PSI_UNAMEO') && (PSI_UNAMEO === 'Android') && !empty($arrPath)) { + array_push($arrPath, '/system/bin'); // Termux patch } if (defined('PSI_ADD_PATHS') && is_string(PSI_ADD_PATHS)) { if (preg_match(ARRAY_EXP, PSI_ADD_PATHS)) { @@ -82,13 +97,13 @@ class CommonFunctions $arrPath = array_merge(array(PSI_ADD_PATHS), $arrPath); // In this order so $addpaths is before $arrPath when looking for a program } } - } else { + } else { //directory defined array_push($arrPath, $path_parts['dirname']); $strProgram = $path_parts['basename']; } //add some default paths if we still have no paths here - if (empty($arrPath) && PSI_OS != 'WINNT') { + if (empty($arrPath) && (PSI_OS != 'WINNT')) { if (PSI_OS == 'Android') { array_push($arrPath, '/system/bin'); } else { @@ -97,97 +112,74 @@ class CommonFunctions } $exceptPath = ""; - if ((PSI_OS == 'WINNT') && (($windir = getenv("WinDir")) !== false)) { - $windir = strtolower($windir); + if ((PSI_OS == 'WINNT') && self::readenv('WinDir', $windir)) { foreach ($arrPath as $strPath) { - if ((strtolower($strPath) == $windir."\\system32") && is_dir($windir."\\SysWOW64")) { - $exceptPath = $windir."\\sysnative"; + if ((strtolower($strPath) == strtolower($windir)."\\system32") && is_dir($windir."\\SysWOW64")) { + if (is_dir($windir."\\sysnative\\drivers")) { // or strlen(decbin(~0)) == 32; is_dir($windir."\\sysnative") sometimes does not work + $exceptPath = $windir."\\sysnative"; //32-bit PHP on 64-bit Windows + } else { + $exceptPath = $windir."\\SysWOW64"; //64-bit PHP on 64-bit Windows + } array_push($arrPath, $exceptPath); break; } } - } else if (PSI_OS == 'Android') { - $exceptPath = '/system/bin'; + } elseif (PSI_OS == 'Android') { + $exceptPath = '/system/bin'; } - // If open_basedir defined, fill the $open_basedir array with authorized paths,. (Not tested when no open_basedir restriction) - if ((bool) ini_get('open_basedir')) { - if (PSI_OS == 'WINNT') { - $open_basedir = preg_split('/;/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY); - } else { - $open_basedir = preg_split('/:/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY); - } - } foreach ($arrPath as $strPath) { - // Path with trailing slash + // Path with and without trailing slash if (PSI_OS == 'WINNT') { - $strPathS = rtrim($strPath, "\\")."\\"; + $strPath = rtrim($strPath, "\\"); + $strPathS = $strPath."\\"; } else { - $strPathS = rtrim($strPath, "/")."/"; - } - // To avoid "open_basedir restriction in effect" error when testing paths if restriction is enabled - if (isset($open_basedir)) { - $inBaseDir = false; - if (PSI_OS == 'WINNT') { - foreach ($open_basedir as $openbasedir) { - if (substr($openbasedir, -1)=="\\") { - $str_Path = $strPathS; - } else { - $str_Path = $strPath; - } - if (stripos($str_Path, $openbasedir) === 0) { - $inBaseDir = true; - break; - } - } - } else { - foreach ($open_basedir as $openbasedir) { - if (substr($openbasedir, -1)=="/") { - $str_Path = $strPathS; - } else { - $str_Path = $strPath; - } - if (strpos($str_Path, $openbasedir) === 0) { - $inBaseDir = true; - break; - } - } - } - if ($inBaseDir == false) { - continue; - } + $strPath = rtrim($strPath, "/"); + $strPathS = $strPath."/"; } if (($strPath !== $exceptPath) && !is_dir($strPath)) { continue; } - if (PSI_OS == 'WINNT') { - $strProgrammpath = rtrim($strPath, "\\")."\\".$strProgram; - } else { - $strProgrammpath = rtrim($strPath, "/")."/".$strProgram; - } - if (is_executable($strProgrammpath)) { + $strProgrammpath = $strPathS.$strProgram; + if (is_executable($strProgrammpath) || ((PSI_OS == 'WINNT') && (strtolower($path_parts['extension']) == 'py') && is_file($strProgrammpath))) { return $strProgrammpath; } } + + return null; } /** * Execute a system program. return a trim()'d result. - * does very crude pipe checking. you need ' | ' for it to work + * does very crude pipe and multiple commands (on WinNT) checking. you need ' | ' or ' & ' for it to work * ie $program = CommonFunctions::executeProgram('netstat', '-anp | grep LIST'); * NOT $program = CommonFunctions::executeProgram('netstat', '-anp|grep LIST'); * * @param string $strProgramname name of the program - * @param string $strArgs arguments to the program + * @param string $strArguments arguments to the program * @param string &$strBuffer output of the command * @param boolean $booErrorRep en- or disables the reporting of errors which should be logged + * @param int $timeout timeout value in seconds (default value is PSI_EXEC_TIMEOUT_INT) * * @return boolean command successfull or not */ - public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true) + public static function executeProgram($strProgramname, $strArguments, &$strBuffer, $booErrorRep = true, $timeout = PSI_EXEC_TIMEOUT_INT, $separator = '') { + if (PSI_ROOT_FILESYSTEM !== '') { // disabled if ROOTFS defined + + return false; + } + + if ((PSI_OS != 'WINNT') && preg_match('/^([^=]+=[^ \t]+)[ \t]+(.*)$/', $strProgramname, $strmatch)) { + $strSet = $strmatch[1].' '; + $strProgramname = $strmatch[2]; + } else { + $strSet = ''; + } + $strAll = trim($strSet.$strProgramname.' '.$strArguments); + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { - $out = self::_parse_log_file("Executing: ".trim($strProgramname.' '.$strArgs)); + $out = self::_parse_log_file("Executing: ".$strAll); if ($out == false) { if (substr(PSI_LOG, 0, 1)=="-") { $strBuffer = ''; @@ -201,42 +193,164 @@ class CommonFunctions } } - $strBuffer = ''; - $strError = ''; - $pipes = array(); + $PathStr = ''; + if (defined('PSI_EMU_PORT') && !in_array($strProgramname, array('ping', 'snmpwalk'))) { + if (defined('PSI_SUDO_COMMANDS') && is_string(PSI_SUDO_COMMANDS)) { + if (preg_match(ARRAY_EXP, PSI_SUDO_COMMANDS)) { + $sudocommands = eval(PSI_SUDO_COMMANDS); + } else { + $sudocommands = array(PSI_SUDO_COMMANDS); + } + if (in_array($strProgramname, $sudocommands)) { + $strAll = 'sudo '.$strAll; + } + } + $strSet = ''; + $strProgramname = 'sshpass'; + $strOptions = ''; + if (defined('PSI_EMU_ADD_OPTIONS') && is_string(PSI_EMU_ADD_OPTIONS)) { + if (preg_match(ARRAY_EXP, PSI_EMU_ADD_OPTIONS)) { + $arrParams = eval(PSI_EMU_ADD_OPTIONS); + } else { + $arrParams = array(PSI_EMU_ADD_OPTIONS); + } + foreach ($arrParams as $Params) if (preg_match('/(\S+)\s*\=\s*(\S+)/', $Params, $obuf)) { + $strOptions = $strOptions.'-o '.$obuf[1].'='.$obuf[2].' '; + } + } + if (defined('PSI_EMU_ADD_PATHS') && is_string(PSI_EMU_ADD_PATHS)) { + if (preg_match(ARRAY_EXP, PSI_EMU_ADD_PATHS)) { + $arrPath = eval(PSI_EMU_ADD_PATHS); + } else { + $arrPath = array(PSI_EMU_ADD_PATHS); + } + foreach ($arrPath as $Path) { + if ($PathStr === '') { + $PathStr = $Path; + } else { + $PathStr = $PathStr.':'.$Path; + } + } + if ($separator === '') { + $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT.' "PATH=\''.$PathStr.':$PATH\' '.$strAll.'"' ; + } else { + $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT; + } + } else { + if ($separator === '') { + $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT.' "'.$strAll.'"' ; + } else { + $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT; + } + } + $externally = true; + } else { + $externally = false; + } + $strProgram = self::_findProgram($strProgramname); - $error = Error::singleton(); + $error = PSI_Error::singleton(); if (!$strProgram) { - if ($booErrorRep) { - $error->addError('find_program('.$strProgramname.')', 'program not found on the machine'); + if ($booErrorRep || $externally) { + $error->addError('find_program("'.$strProgramname.'")', 'program not found on the machine'); } return false; + } else { + if (preg_match('/\s/', $strProgram)) { + $strProgram = '"'.$strProgram.'"'; + } } - // see if we've gotten a |, if we have we need to do path checking on the cmd - if ($strArgs) { - $arrArgs = preg_split('/ /', $strArgs, -1, PREG_SPLIT_NO_EMPTY); - for ($i = 0, $cnt_args = count($arrArgs); $i < $cnt_args; $i++) { - if ($arrArgs[$i] == '|') { - $strCmd = $arrArgs[$i + 1]; - $strNewcmd = self::_findProgram($strCmd); - $strArgs = preg_replace("/\| ".$strCmd.'/', '| "'.$strNewcmd.'"', $strArgs); + + if ((PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME') && defined('PSI_SUDO_COMMANDS') && is_string(PSI_SUDO_COMMANDS)) { + if (preg_match(ARRAY_EXP, PSI_SUDO_COMMANDS)) { + $sudocommands = eval(PSI_SUDO_COMMANDS); + } else { + $sudocommands = array(PSI_SUDO_COMMANDS); + } + if (in_array($strProgramname, $sudocommands)) { + $sudoProgram = self::_findProgram("sudo"); + if (!$sudoProgram) { + $error->addError('find_program("sudo")', 'program not found on the machine'); + + return false; + } else { + if (preg_match('/\s/', $sudoProgram)) { + $strProgram = '"'.$sudoProgram.'" '.$strProgram; + } else { + $strProgram = $sudoProgram.' '.$strProgram; + } } } } + + $strArgs = $strArguments; + // see if we've gotten a | or &, if we have we need to do path checking on the cmd + if ($strArgs) { + $arrArgs = preg_split('/ /', $strArgs, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 0, $cnt_args = count($arrArgs); $i < $cnt_args; $i++) { + if (($arrArgs[$i] == '|') || ($arrArgs[$i] == '&')) { + $strCmd = $arrArgs[$i + 1]; + $strNewcmd = self::_findProgram($strCmd); + if (!$strNewcmd) { + if ($booErrorRep || $externally) { + $error->addError('find_program("'.$strCmd.'")', 'program not found on the machine'); + } + + return false; + } + if (preg_match('/\s/', $strNewcmd)) { + if ($arrArgs[$i] == '|') { + $strArgs = preg_replace('/\| '.$strCmd.'/', '| "'.$strNewcmd.'"', $strArgs); + } else { + $strArgs = preg_replace('/& '.$strCmd.'/', '& "'.$strNewcmd.'"', $strArgs); + } + } else { + if ($arrArgs[$i] == '|') { + $strArgs = preg_replace('/\| '.$strCmd.'/', '| '.$strNewcmd, $strArgs); + } else { + $strArgs = preg_replace('/& '.$strCmd.'/', '& '.$strNewcmd, $strArgs); + } + } + } + } + $strArgs = ' '.$strArgs; + } + + $strBuffer = ''; + $strError = ''; + $pipes = array(); $descriptorspec = array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")); - if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + if ($externally) { + putenv('SSHPASS='.PSI_EMU_PASSWORD); + } + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) { + if ($separator !== '') { + $error->addError('executeProgram', 'wrong execution mode'); + + return false; + } if (PSI_OS == 'WINNT') { - $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>nul", "r"); + $process = $pipes[1] = popen($strSet.$strProgram.$strArgs." 2>nul", "r"); } else { - $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>/dev/null", "r"); + $process = $pipes[1] = popen($strSet.$strProgram.$strArgs." 2>/dev/null", "r"); } } else { - $process = proc_open('"'.$strProgram.'" '.$strArgs, $descriptorspec, $pipes); + $process = proc_open($strSet.$strProgram.$strArgs, $descriptorspec, $pipes); + if ($separator !== '') { + if ($PathStr === '') { + fwrite($pipes[0], $strAll."\n "); // spaces at end for handling 'more' + } else { + fwrite($pipes[0], 'PATH=\''.$PathStr.':$PATH\' '.$strAll."\n"); + } + } + } + if ($externally) { + putenv('SSHPASS'); } if (is_resource($process)) { - self::_timeoutfgets($pipes, $strBuffer, $strError); - if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + $te = self::_timeoutfgets($pipes, $strBuffer, $strError, $timeout, $separator); + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) { $return_value = pclose($pipes[1]); } else { fclose($pipes[0]); @@ -244,7 +358,12 @@ class CommonFunctions fclose($pipes[2]); // It is important that you close any pipes before calling // proc_close in order to avoid a deadlock - $return_value = proc_close($process); + if ($te) { + proc_terminate($process); // proc_close tends to hang if the process is timing out + $return_value = 0; + } else { + $return_value = proc_close($process); + } } } else { if ($booErrorRep) { @@ -256,7 +375,7 @@ class CommonFunctions $strError = trim($strError); $strBuffer = trim($strBuffer); if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) { - error_log("---".gmdate('r T')."--- Executing: ".trim($strProgramname.' '.$strArgs)."\n".$strBuffer."\n", 3, PSI_LOG); + error_log("---".gmdate('r T')."--- Executing: ".$strAll."\n".$strBuffer."\n", 3, PSI_LOG); } if (! empty($strError)) { if ($booErrorRep) { @@ -269,19 +388,74 @@ class CommonFunctions return true; } + /** + * read a one-line value from a file with a similar name + * + * @return value if successfull or null if not + */ + public static function rolv($similarFileName, $match = "//", $replace = "") + { + if (defined('PSI_EMU_PORT')) { + return null; + } + + $filename = preg_replace($match, $replace, $similarFileName); + if (self::fileexists($filename) && self::rfts($filename, $buf, 1, 4096, false) && (($buf=trim($buf)) != "")) { + return $buf; + } else { + return null; + } + } + + /** + * read data from array $_SERVER + * + * @param string $strElem element of array + * @param string &$strBuffer output of the command + * + * @return string + */ + public static function readenv($strElem, &$strBuffer) + { + $strBuffer = ''; + if (PSI_OS == 'WINNT') { //case insensitive + if (isset($_SERVER)) { + foreach ($_SERVER as $index=>$value) { + if (is_string($value) && (trim($value) !== '') && (strtolower($index) === strtolower($strElem))) { + $strBuffer = $value; + + return true; + } + } + } + } else { + if (isset($_SERVER[$strElem]) && is_string($value = $_SERVER[$strElem]) && (trim($value) !== '')) { + $strBuffer = $value; + + return true; + } + } + + return false; + } + /** * read a file and return the content as a string * * @param string $strFileName name of the file which should be read * @param string &$strRet content of the file (reference) - * @param integer $intLines control how many lines should be read - * @param integer $intBytes control how many bytes of each line should be read + * @param int $intLines control how many lines should be read + * @param int $intBytes control how many bytes of each line should be read * @param boolean $booErrorRep en- or disables the reporting of errors which should be logged * * @return boolean command successfull or not */ public static function rfts($strFileName, &$strRet, $intLines = 0, $intBytes = 4096, $booErrorRep = true) { + if (defined('PSI_EMU_PORT')) { + return false; + } + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { $out = self::_parse_log_file("Reading: ".$strFileName); if ($out == false) { @@ -297,12 +471,18 @@ class CommonFunctions } } + if (PSI_ROOT_FILESYSTEM !== '') { + $rfsinfo = "[".PSI_ROOT_FILESYSTEM."]"; + } else { + $rfsinfo = ''; + } + $strFile = ""; $intCurLine = 1; - $error = Error::singleton(); - if (file_exists($strFileName)) { - if (is_readable($strFileName)) { - if ($fd = fopen($strFileName, 'r')) { + $error = PSI_Error::singleton(); + if (file_exists(PSI_ROOT_FILESYSTEM.$strFileName)) { + if (is_readable(PSI_ROOT_FILESYSTEM.$strFileName)) { + if ($fd = fopen(PSI_ROOT_FILESYSTEM.$strFileName, 'r')) { while (!feof($fd)) { $strFile .= fgets($fd, $intBytes); if ($intLines <= $intCurLine && $intLines != 0) { @@ -322,21 +502,21 @@ class CommonFunctions } } else { if ($booErrorRep) { - $error->addError('fopen('.$strFileName.')', 'file can not read by phpsysinfo'); + $error->addError('fopen('.$rfsinfo.$strFileName.')', 'file can not read by phpsysinfo'); } return false; } } else { - if ($booErrorRep) { - $error->addError('fopen('.$strFileName.')', 'file permission error'); - } + if ($booErrorRep) { + $error->addError('fopen('.$rfsinfo.$strFileName.')', 'file permission error'); + } - return false; + return false; } } else { if ($booErrorRep) { - $error->addError('file_exists('.$strFileName.')', 'the file does not exist on your machine'); + $error->addError('file_exists('.$rfsinfo.$strFileName.')', 'the file does not exist on your machine'); } return false; @@ -345,6 +525,76 @@ class CommonFunctions return true; } + /** + * read a data file and return the content as a string + * + * @param string $strDataFileName name of the data file which should be read + * @param string &$strRet content of the data file (reference) + * + * @return boolean command successfull or not + */ + public static function rftsdata($strDataFileName, &$strRet) + { + $strFile = ""; + $strFileName = PSI_APP_ROOT."/data/".$strDataFileName; + $error = PSI_Error::singleton(); + if (file_exists($strFileName)) { + if (is_readable($strFileName)) { + if ($fd = fopen($strFileName, 'r')) { + while (!feof($fd)) { + $strFile .= fgets($fd, 4096); + } + fclose($fd); + $strRet = $strFile; + } else { + $error->addError('fopen('.$strFileName.')', 'file can not read by phpsysinfo'); + + return false; + } + } else { + $error->addError('fopen('.$strFileName.')', 'file permission error'); + + return false; + } + } else { + $error->addError('file_exists('.$strFileName.')', 'the file does not exist on your machine'); + + return false; + } + + return true; + } + + /** + * Find pathnames matching a pattern + * + * @param string $pattern the pattern. No tilde expansion or parameter substitution is done. + * @param int $flags + * + * @return an array containing the matched files/directories, an empty array if no file matched or false on error + */ + public static function findglob($pattern, $flags = 0) + { + if (defined('PSI_EMU_PORT')) { + return false; + } + + $outarr = glob(PSI_ROOT_FILESYSTEM.$pattern, $flags); + if (PSI_ROOT_FILESYSTEM == '') { + return $outarr; + } elseif ($outarr === false) { + return false; + } else { + $len = strlen(PSI_ROOT_FILESYSTEM); + $newoutarr = array(); + foreach ($outarr as $out) { + $newoutarr[] = substr($out, $len); // path without ROOTFS + } + + return $newoutarr; + } + } + /** * file exists * @@ -354,6 +604,10 @@ class CommonFunctions */ public static function fileexists($strFileName) { + if (defined('PSI_EMU_PORT')) { + return false; + } + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { $log_file = substr(PSI_LOG, 1); if (file_exists($log_file) @@ -367,7 +621,14 @@ class CommonFunctions } } - return file_exists($strFileName); + $exists = file_exists(PSI_ROOT_FILESYSTEM.$strFileName); + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) { + if ((substr($strFileName, 0, 5) === "/dev/") && $exists) { + error_log("---".gmdate('r T')."--- Reading: ".$strFileName."\ndevice exists\n", 3, PSI_LOG); + } + } + + return $exists; } /** @@ -381,7 +642,7 @@ class CommonFunctions public static function gdc($strPath, $booErrorRep = true) { $arrDirectoryContent = array(); - $error = Error::singleton(); + $error = PSI_Error::singleton(); if (is_dir($strPath)) { if ($handle = opendir($strPath)) { while (($strFile = readdir($handle)) !== false) { @@ -419,12 +680,12 @@ class CommonFunctions */ public static function checkForExtensions($arrExt = array()) { - if ((strcasecmp(PSI_SYSTEM_CODEPAGE, "UTF-8") == 0) || (strcasecmp(PSI_SYSTEM_CODEPAGE, "CP437") == 0)) + if (defined('PSI_SYSTEM_CODEPAGE') && (PSI_SYSTEM_CODEPAGE !== null) && ((strcasecmp(PSI_SYSTEM_CODEPAGE, "UTF-8") == 0) || (strcasecmp(PSI_SYSTEM_CODEPAGE, "CP437") == 0))) $arrReq = array('simplexml', 'pcre', 'xml', 'dom'); - elseif (PSI_OS == "WINNT") - $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom', 'com_dotnet'); + elseif (PSI_OS == 'WINNT') + $arrReq = array('simplexml', 'pcre', 'xml', 'dom', 'mbstring', 'com_dotnet'); else - $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom'); + $arrReq = array('simplexml', 'pcre', 'xml', 'dom', 'mbstring'); $extensions = array_merge($arrExt, $arrReq); $text = ""; $error = false; @@ -441,7 +702,7 @@ class CommonFunctions $text .= " \n"; $text .= ""; if ($error) { - header("Content-Type: text/xml\n\n"); + header('Content-Type: text/xml'); echo $text; die(); } @@ -450,19 +711,20 @@ class CommonFunctions /** * get the content of stdout/stderr with the option to set a timeout for reading * - * @param array $pipes array of file pointers for stdin, stdout, stderr (proc_open()) - * @param string &$out target string for the output message (reference) - * @param string &$err target string for the error message (reference) - * @param integer $timeout timeout value in seconds (default value is 30) + * @param array $pipes array of file pointers for stdin, stdout, stderr (proc_open()) + * @param string &$out target string for the output message (reference) + * @param string &$err target string for the error message (reference) + * @param int $timeout timeout value in seconds * - * @return void + * @return boolean timeout expired or not */ - private static function _timeoutfgets($pipes, &$out, &$err, $timeout = 30) + private static function _timeoutfgets($pipes, &$out, &$err, $timeout, $separator = '') { $w = null; $e = null; + $te = false; - if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) { $pipe2 = false; } else { $pipe2 = true; @@ -481,66 +743,30 @@ class CommonFunctions break; } elseif ($n === 0) { error_log('stream_select: timeout expired !'); +// if ($separator !== '') { +// fwrite($pipes[0], "q"); +// } + $te = true; break; } foreach ($read as $r) { if ($r == $pipes[1]) { $out .= fread($r, 4096); - } else if (feof($pipes[1]) && $pipe2 && ($r == $pipes[2])) {//read STDERR after STDOUT + } elseif (feof($pipes[1]) && $pipe2 && ($r == $pipes[2])) {//read STDERR after STDOUT $err .= fread($r, 4096); } } - } - } - - /** - * function for getting a list of values in the specified context - * optionally filter this list, based on the list from third parameter - * - * @param $wmi holds the COM object that we pull the WMI data from - * @param string $strClass name of the class where the values are stored - * @param array $strValue filter out only needed values, if not set all values of the class are returned - * - * @return array content of the class stored in an array - */ - public static function getWMI($wmi, $strClass, $strValue = array()) - { - $arrData = array(); - if ($wmi) { - $value = ""; - try { - $objWEBM = $wmi->Get($strClass); - $arrProp = $objWEBM->Properties_; - $arrWEBMCol = $objWEBM->Instances_(); - foreach ($arrWEBMCol as $objItem) { - if (is_array($arrProp)) { - reset($arrProp); - } - $arrInstance = array(); - foreach ($arrProp as $propItem) { - $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";"); - if (empty($strValue)) { - if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); - else $arrInstance[$propItem->Name] = $value; - } else { - if (in_array($propItem->Name, $strValue)) { - if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); - else $arrInstance[$propItem->Name] = $value; - } - } - } - $arrData[] = $arrInstance; - } - } catch (Exception $e) { - if (PSI_DEBUG) { - $error = Error::singleton(); - $error->addError($e->getCode(), $e->getMessage()); - } +// if (($separator !== '') && preg_match('/'.$separator.'[^'.$separator.']+'.$separator.'/', $out)) { + if (($separator !== '') && preg_match('/'.$separator.'[\s\S]+'.$separator.'/', $out)) { + fwrite($pipes[0], "quit\n"); + $separator = ''; //only one time + // $te = true; + // break; } } - return $arrData; + return $te; } /** @@ -560,4 +786,111 @@ class CommonFunctions return array(); } } + + /** + * name natural compare function + * + * @return comprasion result + */ + public static function name_natural_compare($a, $b) + { + return strnatcmp($a->getName(), $b->getName()); + } + + /** + * get virtualizer from dmi data + * + * @return string|null + */ + public static function decodevirtualizer($vendor_data) + { + if (gettype($vendor_data) === "array") { + $vendarray = array( + 'KVM' => 'kvm', // KVM + 'OpenStack' => 'kvm', // Detect OpenStack instance as KVM in non x86 architecture + 'KubeVirt' => 'kvm', // Detect KubeVirt instance as KVM in non x86 architecture + 'Amazon EC2' => 'amazon', // Amazon EC2 Nitro using Linux KVM + 'QEMU' => 'qemu', // QEMU + 'VMware' => 'vmware', // VMware https://kb.vmware.com/s/article/1009458 + 'VMW' => 'vmware', + 'innotek GmbH' => 'oracle', // Oracle VM VirtualBox + 'VirtualBox' => 'oracle', + 'Xen' => 'xen', // Xen hypervisor + 'Bochs' => 'bochs', // Bochs + 'Parallels' => 'parallels', // Parallels + // https://wiki.freebsd.org/bhyve + 'BHYVE' => 'bhyve', // bhyve + 'Hyper-V' => 'microsoft', // Hyper-V + 'Apple Virtualization' => 'apple', // Apple Virtualization.framework guests + 'Microsoft Corporation Virtual Machine' => 'microsoft' // Hyper-V + ); + for ($i = 0; $i < count($vendor_data); $i++) { + foreach ($vendarray as $vend=>$virt) { + if (preg_match('/^'.$vend.'/', $vendor_data[$i])) { + return $virt; + } + } + } + } elseif (gettype($vendor_data) === "string") { + $vidarray = array( + 'bhyvebhyve' => 'bhyve', // bhyve + 'KVMKVMKVM' => 'kvm', // KVM + 'LinuxKVMHv' => 'hv-kvm', // KVM (KVM + HyperV Enlightenments) + 'MicrosoftHv' => 'microsoft', // Hyper-V + 'lrpepyhvr' => 'parallels', // Parallels + 'UnisysSpar64' => 'spar', // Unisys sPar + 'VMwareVMware' => 'vmware', // VMware + 'XenVMMXenVMM' => 'xen', // Xen hypervisor + 'ACRNACRNACRN' => 'acrn', // ACRN hypervisor + 'TCGTCGTCGTCG' => 'qemu', // QEMU + 'QNXQVMBSQG' => 'qnx', // QNX hypervisor + 'VBoxVBoxVBox' => 'oracle', // Oracle VM VirtualBox + 'SRESRESRESRE' => 'sre' // LMHS SRE hypervisor + ); + $shortvendorid = trim(preg_replace('/[\s!\.]/', '', $vendor_data)); + if (($shortvendorid !== "") && isset($vidarray[$shortvendorid])) { + return $vidarray[$shortvendorid]; + } + } + + return null; + } + + + /** + * readdmimemdata function + * + * @return array + */ + public static function readdmimemdata() + { + if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) && (self::$_dmimd === null)) { + self::$_dmimd = array(); + $buffer = ''; + if (defined('PSI_DMIDECODE_ACCESS') && (strtolower(PSI_DMIDECODE_ACCESS)==='data')) { + self::rftsdata('dmidecode.tmp', $buffer); + } elseif (self::_findProgram('dmidecode')) { + self::executeProgram('dmidecode', '-t 17', $buffer, PSI_DEBUG); + } + if (!empty($buffer)) { + $banks = preg_split('/^(?=Handle\s)/m', $buffer, -1, PREG_SPLIT_NO_EMPTY); + foreach ($banks as $bank) if (preg_match('/^Handle\s/', $bank)) { + $lines = preg_split("/\n/", $bank, -1, PREG_SPLIT_NO_EMPTY); + $mem = array(); + foreach ($lines as $line) if (preg_match('/^\s+([^:]+):(.+)/', $line, $params)) { + if (preg_match('/^0x([A-F\d]+)/', $params2 = trim($params[2]), $buff)) { + $mem[trim($params[1])] = trim($buff[1]); + } elseif ($params2 != '') { + $mem[trim($params[1])] = $params2; + } + } + if (!empty($mem)) { + self::$_dmimd[] = $mem; + } + } + } + } + + return self::$_dmimd; + } } diff --git a/root/opt/phpsysinfo/includes/class.Parser.inc.php b/root/opt/phpsysinfo/includes/class.Parser.inc.php index f137e4a..61ab062 100644 --- a/root/opt/phpsysinfo/includes/class.Parser.inc.php +++ b/root/opt/phpsysinfo/includes/class.Parser.inc.php @@ -8,7 +8,7 @@ * @package PSI * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Parser.inc.php 604 2012-07-10 07:31:34Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,22 +28,44 @@ class Parser /** * parsing the output of lspci command * - * @return Array + * @param bool $debug + * @return array */ public static function lspci($debug = PSI_DEBUG) { $arrResults = array(); - if (CommonFunctions::executeProgram("lspci", "", $strBuf, $debug)) { + if (CommonFunctions::executeProgram("lspci", (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS)?"-m":"", $strBuf, $debug)) { $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); foreach ($arrLines as $strLine) { - $arrParams = preg_split('/ /', trim($strLine), 2); - if (count($arrParams) == 2) - $strName = $arrParams[1]; - else - $strName = "unknown"; - $strName = preg_replace('/\(.*\)/', '', $strName); $dev = new HWDevice(); - $dev->setName($strName); + $arrParams = preg_split('/(\"? ")|(\" (?=-))/', trim($strLine)); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && ($cp = count($arrParams)) >= 6) { + $arrParams[$cp-1] = trim($arrParams[$cp-1], '"'); // remove last " + $dev->setName($arrParams[1].': '.$arrParams[2].' '.$arrParams[3]); + if (preg_match('/^-/', $arrParams[4])) { + if (($arrParams[5] !== "") && !preg_match('/^Unknown vendor/', $arrParams[5])) { + $dev->setManufacturer(trim($arrParams[5])); + } + if (($arrParams[6] !== "") && !preg_match('/^Device /', $arrParams[6])) { + $dev->setProduct(trim($arrParams[6])); + } + } else { + if (($arrParams[4] !== "") && !preg_match('/^Unknown vendor/', $arrParams[4])) { + $dev->setManufacturer(trim($arrParams[4])); + } + if (($arrParams[5] !== "") && !preg_match('/^Device /', $arrParams[5])) { + $dev->setProduct(trim($arrParams[5])); + } + } + } else { + $strLine=trim(preg_replace('/(")|( -\S+)/', '', $strLine)); + $arrParams = preg_split('/ /', trim($strLine), 2); + if (count($arrParams) == 2) + $strName = preg_replace('/\(rev\s[^\)]+\)/', '', $arrParams[1]); + else + $strName = "unknown"; + $dev->setName($strName); + } $arrResults[] = $dev; } } @@ -54,48 +76,66 @@ class Parser /** * parsing the output of df command * - * @param string $df_param additional parameter for df command + * @param string $df_param additional parameter for df command + * @param bool $get_inodes * * @return array */ - public static function df($df_param = "") + public static function df($df_param = "", $get_inodes = true) { $arrResult = array(); if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) { $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); foreach ($mount as $mount_line) { if (preg_match("/(\S+) on ([\S ]+) type (.*) \((.*)\)/", $mount_line, $mount_buf)) { - $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3]; - $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1]; - if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = $mount_buf[4]; + $parm = array(); + $parm['mountpoint'] = trim($mount_buf[2]); + $parm['fstype'] = $mount_buf[3]; + $parm['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4]; + $mount_parm[] = $parm; } elseif (preg_match("/(\S+) is (.*) mounted on (\S+) \(type (.*)\)/", $mount_line, $mount_buf)) { - $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[4]; - $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1]; - if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[2]; + $parm = array(); + $parm['mountpoint'] = trim($mount_buf[3]); + $parm['fstype'] = $mount_buf[4]; + $parm['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[2]; + $mount_parm[] = $parm; } elseif (preg_match("/(\S+) (.*) on (\S+) \((.*)\)/", $mount_line, $mount_buf)) { - $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[2]; - $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1]; - if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[4]; + $parm = array(); + $parm['mountpoint'] = trim($mount_buf[3]); + $parm['fstype'] = $mount_buf[2]; + $parm['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4]; + $mount_parm[] = $parm; } elseif (preg_match("/(\S+) on ([\S ]+) \((\S+)(,\s(.*))?\)/", $mount_line, $mount_buf)) { - $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3]; - $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1]; - if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = isset($mount_buf[5]) ? $mount_buf[5] : ''; + $parm = array(); + $parm['mountpoint'] = trim($mount_buf[2]); + $parm['fstype'] = $mount_buf[3]; + $parm['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = isset($mount_buf[5]) ? $mount_buf[5] : ''; + $mount_parm[] = $parm; } } - } elseif (CommonFunctions::rfts("/etc/mtab", $mount)) { + } elseif (CommonFunctions::rfts(((PSI_ROOT_FILESYSTEM === '')||(PSI_OS !== 'Linux'))?"/etc/mtab":"/proc/1/mounts", $mount)) { $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); foreach ($mount as $mount_line) { if (preg_match("/(\S+) (\S+) (\S+) (\S+) ([0-9]+) ([0-9]+)/", $mount_line, $mount_buf)) { + $parm = array(); $mount_point = preg_replace("/\\\\040/i", ' ', $mount_buf[2]); //space as \040 - $mount_parm[$mount_point]['fstype'] = $mount_buf[3]; - $mount_parm[$mount_point]['name'] = $mount_buf[1]; - if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_point]['options'] = $mount_buf[4]; + $parm['mountpoint'] = $mount_point; + $parm['fstype'] = $mount_buf[3]; + $parm['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4]; + $mount_parm[] = $parm; } } } - if (CommonFunctions::executeProgram('df', '-k '.$df_param, $df, PSI_DEBUG)) { + $df = ""; + CommonFunctions::executeProgram('df', '-k '.$df_param, $df, PSI_DEBUG); + if ($df!=="") { $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); - if (PSI_SHOW_INODES) { + if ($get_inodes && PSI_SHOW_INODES) { if (CommonFunctions::executeProgram('df', '-i '.$df_param, $df2, PSI_DEBUG)) { $df2 = preg_split("/\n/", $df2, -1, PREG_SPLIT_NO_EMPTY); // Store inode use% in an associative array (df_inodes) for later use @@ -133,13 +173,103 @@ class Parser } if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[5]); - if (isset($mount_parm[$df_buf[5]])) { - $dev->setFsType($mount_parm[$df_buf[5]]['fstype']); + $notwas = true; + if (isset($mount_parm)) { + foreach ($mount_parm as $mount_param) { //name and mountpoint find + if (($mount_param['name']===trim($df_buf[0])) && ($mount_param['mountpoint']===$df_buf[5])) { + $dev->setFsType($mount_param['fstype']); + if (PSI_SHOW_MOUNT_OPTION && (trim($mount_param['options'])!=="")) { + if (PSI_SHOW_MOUNT_CREDENTIALS) { + $dev->setOptions($mount_param['options']); + } else { + $mpo=$mount_param['options']; + + $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); + $mpo=preg_replace('/,guest,/i', ',', $mpo); + + $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); + + $dev->setOptions($mpo); + } + } + $notwas = false; + break; + } + } + if ($notwas) foreach ($mount_parm as $mount_param) { //mountpoint find + if ($mount_param['mountpoint']===$df_buf[5]) { + $dev->setFsType($mount_param['fstype']); + if (PSI_SHOW_MOUNT_OPTION && (trim($mount_param['options'])!=="")) { + if (PSI_SHOW_MOUNT_CREDENTIALS) { + $dev->setOptions($mount_param['options']); + } else { + $mpo=$mount_param['options']; + + $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); + $mpo=preg_replace('/,guest,/i', ',', $mpo); + + $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); + + $dev->setOptions($mpo); + } + } + $notwas = false; + break; + } + } + } + + if ($notwas) { + $dev->setFsType('unknown'); + } + + if ($get_inodes && PSI_SHOW_INODES && isset($df_inodes[trim($df_buf[0])])) { + $dev->setPercentInodesUsed($df_inodes[trim($df_buf[0])]); + } + $arrResult[] = $dev; + } + } + } + } else { + if (isset($mount_parm)) { + foreach ($mount_parm as $mount_param) { + if (is_dir($mount_param['mountpoint'])) { + $total = disk_total_space($mount_param['mountpoint']); + if (($mount_param['fstype'] != 'none') && ($total > 0)) { + $dev = new DiskDevice(); + $dev->setName($mount_param['name']); + $dev->setFsType($mount_param['fstype']); + + if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($mount_param['mountpoint']); + + $dev->setTotal($total); + $free = disk_free_space($mount_param['mountpoint']); + if ($free > 0) { + $dev->setFree($free); + } else { + $free = 0; + } + if ($total > $free) $dev->setUsed($total - $free); + if (PSI_SHOW_MOUNT_OPTION) { if (PSI_SHOW_MOUNT_CREDENTIALS) { - $dev->setOptions($mount_parm[$df_buf[5]]['options']); + $dev->setOptions($mount_param['options']); } else { - $mpo=$mount_parm[$df_buf[5]]['options']; + $mpo=$mount_param['options']; $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); $mpo=preg_replace('/,guest,/i', ',', $mpo); @@ -156,56 +286,8 @@ class Parser $dev->setOptions($mpo); } } + $arrResult[] = $dev; } - if (PSI_SHOW_INODES && isset($df_inodes[trim($df_buf[0])])) { - $dev->setPercentInodesUsed($df_inodes[trim($df_buf[0])]); - } - $arrResult[] = $dev; - } - } - } - } else { - if (isset($mount_parm)) { - foreach ($mount_parm as $mount_point=>$mount_param) { - $total = disk_total_space($mount_point); - if (($mount_param['fstype'] != 'none') && ($total > 0)) { - $dev = new DiskDevice(); - $dev->setName($mount_param['name']); - $dev->setFsType($mount_param['fstype']); - - if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($mount_point); - - $dev->setTotal($total); - $free = disk_free_space($mount_point); - if ($free > 0) { - $dev->setFree($free); - } else { - $free = 0; - } - if ($total > $free) $dev->setUsed($total - $free); - - if (PSI_SHOW_MOUNT_OPTION) { - if (PSI_SHOW_MOUNT_CREDENTIALS) { - $dev->setOptions($mount_param['options']); - } else { - $mpo=$mount_param['options']; - - $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); - $mpo=preg_replace('/,guest,/i', ',', $mpo); - - $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); - $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); - - $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); - $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); - - $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); - $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); - - $dev->setOptions($mpo); - } - } - $arrResult[] = $dev; } } } diff --git a/root/opt/phpsysinfo/includes/error/class.Error.inc.php b/root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php similarity index 87% rename from root/opt/phpsysinfo/includes/error/class.Error.inc.php rename to root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php index 684678f..a93e58b 100644 --- a/root/opt/phpsysinfo/includes/error/class.Error.inc.php +++ b/root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Error.inc.php 569 2012-04-16 06:08:18Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,17 +19,17 @@ * @package PSI_Error * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ -class Error +class PSI_Error { /** * holds the instance of this class * * @static - * @var object + * @var PSI_Error */ private static $_instance; @@ -59,7 +59,7 @@ class Error /** * Singleton function * - * @return Error instance of the class + * @return PSI_Error instance of the class */ public static function singleton() { @@ -113,8 +113,8 @@ class Error /** * add a config error to the internal list * - * @param object $strCommand Command, which cause the Error - * @param object $strMessage additional Message, to describe the Error + * @param string $strCommand Command, which cause the Error + * @param string $strMessage additional Message, to describe the Error * * @return void */ @@ -126,8 +126,8 @@ class Error /** * add a php error to the internal list * - * @param object $strCommand Command, which cause the Error - * @param object $strMessage additional Message, to describe the Error + * @param string $strCommand Command, which cause the Error + * @param string $strMessage additional Message, to describe the Error * * @return void */ @@ -171,8 +171,8 @@ class Error $error->addAttribute('Message', $arrLine['message']); $error->addAttribute('Function', $arrLine['command']); } - header("Cache-Control: no-cache, must-revalidate\n"); - header("Content-Type: text/xml\n\n"); + header('Cache-Control: no-cache, must-revalidate'); + header('Content-Type: text/xml'); echo $xml->getSimpleXmlElement()->asXML(); exit(); } @@ -229,7 +229,9 @@ class Error if ($val == $arrTrace[count($arrTrace) - 1]) { break; } - $strBacktrace .= str_replace(APP_ROOT, ".", $val['file']).' on line '.$val['line']; + if (isset($val['file'])) { + $strBacktrace .= str_replace(PSI_APP_ROOT, ".", $val['file']).' on line '.$val['line']; + } if ($strFunc) { $strBacktrace .= ' in function '.$strFunc; } @@ -238,10 +240,14 @@ class Error } else { $strFunc = $val['function'].'('; if (isset($val['args'][0])) { + if (($val['function'] == 'executeProgram') && ($val['args'][0] == 'sshpass') + && isset($val['args'][1]) && preg_match('/"([^"]+)"$/', $val['args'][1], $tmpout)) { + $val['args'][1] = 'ssh: '. $tmpout[1]; + } $strFunc .= ' '; $strComma = ''; - foreach ($val['args'] as $val) { - $strFunc .= $strComma.$this->_printVar($val); + foreach ($val['args'] as $valArgs) { + $strFunc .= $strComma.$this->_printVar($valArgs); $strComma = ', '; } $strFunc .= ' '; diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php index 7fca97d..3a3b9e7 100644 --- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php @@ -8,7 +8,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Interface_OS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,7 +21,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -47,4 +47,11 @@ interface PSI_Interface_OS * @return System */ public function getSys(); + + /** + * get os specific language + * + * @return string + */ + public function getLanguage(); } diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php index 7582403..9f89edc 100644 --- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php @@ -8,7 +8,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Interface_Output.inc.php 214 2009-05-25 08:32:40Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php index 138169c..08b474e 100644 --- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php @@ -8,7 +8,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Interface_Plugin.inc.php 273 2009-06-24 11:40:09Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,7 +21,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -37,7 +37,7 @@ interface PSI_Interface_Plugin /** * build the xml * - * @return SimpleXMLObject entire XML content for the plugin which than can be appended to the main XML + * @return SimpleXMLElement entire XML content for the plugin which than can be appended to the main XML */ public function xml(); } diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php index 3113d37..64e1c87 100644 --- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php @@ -8,7 +8,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Interface_Sensor.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,7 +21,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php index 73dd1f5..e776b09 100644 --- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php @@ -8,7 +8,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Interface_UPS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI_Interfaces * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ diff --git a/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php index 48e3ccd..ec6a4e4 100644 --- a/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php +++ b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php @@ -159,8 +159,9 @@ class JavaScriptPacker { $parser = new ParseMaster(); // replace: $name -> n, $$name -> na - $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/', - array('fn' => '_replace_name') + $parser->add( + '/((\\x24+)([a-zA-Z$_]+))(\\d*)/', + array('fn' => '_replace_name') ); // replace: _name -> _0, double-underscore (__name) is ignored $regexp = '/\\b_[A-Za-z\\d]\\w*/'; @@ -169,7 +170,8 @@ class JavaScriptPacker // quick ref $encoded = $keywords['encoded']; - $parser->add($regexp, + $parser->add( + $regexp, array( 'fn' => '_replace_encoded', 'data' => $encoded @@ -194,7 +196,8 @@ class JavaScriptPacker $encoded = $keywords['encoded']; // encode - $parser->add($regexp, + $parser->add( + $regexp, array( 'fn' => '_replace_encoded', 'data' => $encoded @@ -521,7 +524,7 @@ class JavaScriptPacker '; //}; /* -' if (!\'\'.replace(/^/, String)) { +' if (!\'\'.replace(/^/, String)) { // decode all the values we need while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count); // global replacement function diff --git a/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php deleted file mode 100644 index 33af328..0000000 --- a/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.coretemp.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting hardware temperature information through sysctl - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @author William Johansson - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version Release: 3.0 - * @link http://phpsysinfo.sourceforge.net - */ -class Coretemp extends Sensors -{ - /** - * get temperature information - * - * @return void - */ - private function _temperature() - { - $smp = 1; - CommonFunctions::executeProgram('sysctl', '-n kern.smp.cpus', $smp); - for ($i = 0; $i < $smp; $i++) { - $temp = 0; - if (CommonFunctions::executeProgram('sysctl', '-n dev.cpu.'.$i.'.temperature', $temp)) { - $temp = preg_replace('/C/', '', $temp); - $dev = new SensorDevice(); - $dev->setName("CPU ".($i + 1)); - $dev->setValue($temp); - $dev->setMax(70); - $this->mbinfo->setMbTemp($dev); - } - } - } - - /** - * get the information - * - * @see PSI_Interface_Sensor::build() - * - * @return Void - */ - public function build() - { - $this->_temperature(); - } -} diff --git a/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php b/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php new file mode 100644 index 0000000..132ece6 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php @@ -0,0 +1,96 @@ + + * @author William Johansson + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class CpuMem extends Hwmon +{ + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) { + $hwpaths = CommonFunctions::findglob("/sys/devices/platform/coretemp.*/", GLOB_NOSORT); + if (is_array($hwpaths) && (count($hwpaths) > 0)) { + $hwpaths2 = CommonFunctions::findglob("/sys/devices/platform/coretemp.*/hwmon/hwmon*/", GLOB_NOSORT); + if (is_array($hwpaths2) && (count($hwpaths2) > 0)) { + $hwpaths = array_merge($hwpaths, $hwpaths2); + } + $totalh = count($hwpaths); + for ($h = 0; $h < $totalh; $h++) { + $this->_temperature($hwpaths[$h]); + } + } + } elseif (PSI_OS == 'FreeBSD') { + $smp = 1; + CommonFunctions::executeProgram('sysctl', '-n kern.smp.cpus', $smp); + for ($i = 0; $i < $smp; $i++) { + $temp = 0; + if (CommonFunctions::executeProgram('sysctl', '-n dev.cpu.'.$i.'.temperature', $temp)) { + $temp = preg_replace('/,/', '.', preg_replace('/C/', '', $temp)); + $dev = new SensorDevice(); + $dev->setName("CPU ".($i + 1)); + $dev->setValue($temp); +// $dev->setMax(70); + $this->mbinfo->setMbTemp($dev); + } + } + } elseif ((PSI_OS == 'WINNT') || defined('PSI_EMU_HOSTNAME')) { + $allCpus = WINNT::_get_Win32_Processor(); + foreach ($allCpus as $oneCpu) if (isset($oneCpu['CurrentVoltage']) && ($oneCpu['CurrentVoltage'] > 0)) { + $dev = new SensorDevice(); + $dev->setName($oneCpu['DeviceID']); + $dev->setValue($oneCpu['CurrentVoltage']/10); + $this->mbinfo->setMbVolt($dev); + } + $allMems = WINNT::_get_Win32_PhysicalMemory(); + $counter = 0; + foreach ($allMems as $oneMem) if (isset($oneMem['ConfiguredVoltage']) && ($oneMem['ConfiguredVoltage'] > 0)) { + $dev = new SensorDevice(); + $dev->setName('Mem'.($counter++)); + $dev->setValue($oneMem['ConfiguredVoltage']/1000); + if (isset($oneMem['MaxVoltage']) && ($oneMem['MaxVoltage'] > 0)) { + $dev->setMax($oneMem['MaxVoltage']/1000); + } + if (isset($oneMem['MinVoltage']) && ($oneMem['MinVoltage'] > 0)) { + $dev->setMin($oneMem['MinVoltage']/1000); + } + $this->mbinfo->setMbVolt($dev); + } + } + if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) { + $dmimd = CommonFunctions::readdmimemdata(); + $counter = 0; + foreach ($dmimd as $mem) { + if (isset($mem['Size']) && preg_match('/^(\d+)\s(M|G)B$/', $mem['Size'], $size) && ($size[1] > 0) + && isset($mem['Configured Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Configured Voltage'], $voltage) && ($voltage[1] > 0)) { + $dev = new SensorDevice(); + $dev->setName('Mem'.($counter++)); + $dev->setValue($voltage[1]); + if (isset($mem['Minimum Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Minimum Voltage'], $minv) && ($minv[1] > 0)) { + $dev->setMin($minv[1]); + } + if (isset($mem['Maximum Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Maximum Voltage'], $maxv) && ($maxv[1] > 0)) { + $dev->setMax($maxv[1]); + } + $this->mbinfo->setMbVolt($dev); + } + } + } + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php b/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php new file mode 100644 index 0000000..4dcc2b5 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php @@ -0,0 +1,122 @@ + + * @copyright 2022 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class FortiSensor extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private array + */ + public function __construct() + { + parent::__construct(); + $lines = ""; + if (defined('PSI_EMU_PORT') && CommonFunctions::executeProgram('execute', 'sensor list', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $resulti = substr($resulte, strlen($resulto[1][0])); + if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) { + $lines = substr($resulti, 0, $resulto[1][1]); + } + } + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + if (preg_match('/^\s*\d+\s(.+)\sTemperature\s+([\d\.]+)\s\S*C\s*$/', $line, $data)) { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + $this->mbinfo->setMbTemp($dev); + } elseif (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=(\d+)\s/', $line, $data) + && !preg_match('/fan| vin/i', $data[1])) { + $dev = new SensorDevice(); + $dev->setName(trim($data[1])); + $dev->setValue($data[3]); + if ($data[2] != 0) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + if (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=([\d\.]+)\s/', $line, $data) + && preg_match('/\./', $data[3]) + && !preg_match('/fan|temp/i', $data[1])) { + $dev = new SensorDevice(); + $dev->setName(trim($data[1])); + $dev->setValue($data[3]); + if ($data[2] != 0) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + if (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=(\d+)\s/', $line, $data) + && preg_match('/fan/i', $data[1])) { + $dev = new SensorDevice(); + $dev->setName(trim($data[1])); + $dev->setValue($data[3]); + if ($data[2] != 0) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbFan($dev); + } + } + } + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php index 753e3d6..ac572a9 100644 --- a/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php @@ -1,25 +1,14 @@ - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.freeipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from ipmi-sensors - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @author Mieczyslaw Nalewaj + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -33,24 +22,23 @@ class FreeIPMI extends Sensors private $_lines = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through command or data access */ public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_FREEIPMI_ACCESS')?strtolower(PSI_SENSOR_FREEIPMI_ACCESS):'command') { case 'command': CommonFunctions::executeProgram('ipmi-sensors', '--output-sensor-thresholds', $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/freeipmi.txt', $lines)) { - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('freeipmi.tmp', $lines)) { + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_freeipmi] ACCESS'); } } @@ -152,6 +140,7 @@ class FreeIPMI extends Sensors $dev = new SensorDevice(); $dev->setName($buffer[1]); $dev->setValue($buffer[3]); + if ($buffer[6] != "N/A") $dev->setMin($buffer[6]); if ($buffer[9] != "N/A") $dev->setMax($buffer[9]); if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); $this->mbinfo->setMbCurrent($dev); @@ -159,12 +148,31 @@ class FreeIPMI extends Sensors } } + /** + * get other information + * + * @return void + */ + private function _other() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[4] == "N/A" + && $buffer[2] != "OEM Reserved" && $buffer[11] != "N/A") { + $dev = new SensorDevice(); + $dev->setName($buffer[1].' ('.$buffer[2].')'); + $dev->setValue(trim($buffer[11], '\'')); + $this->mbinfo->setMbOther($dev); + } + } + } + /** * get the information * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { @@ -173,5 +181,6 @@ class FreeIPMI extends Sensors $this->_fans(); $this->_power(); $this->_current(); + $this->_other(); } } diff --git a/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php index 7b8add4..a9694a9 100644 --- a/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php @@ -1,26 +1,15 @@ - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.hddtemp.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from hddtemp - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer * @author T.A. van Roermund * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,16 +19,16 @@ class HDDTemp extends Sensors * get the temperature information from hddtemp * access is available through tcp or command * - * @return array temperatures in array + * @return void */ private function _temperature() { $ar_buf = array(); - switch (strtolower(PSI_HDD_TEMP)) { - case "tcp": + if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_HDDTEMP_ACCESS')?strtolower(PSI_SENSOR_HDDTEMP_ACCESS):'command') { + case 'tcp': $lines = ''; // Timo van Roermund: connect to the hddtemp daemon, use a 5 second timeout. - $fp = @fsockopen('localhost', 7634, $errno, $errstr, 5); + $fp = @fsockopen(defined('PSI_EMU_HOSTNAME')?PSI_EMU_HOSTNAME:'localhost', 7634, $errno, $errstr, 5); // if connected, read the output of the hddtemp daemon if ($fp) { while (!feof($fp)) { @@ -52,7 +41,7 @@ class HDDTemp extends Sensors $lines = str_replace("||", "|\n|", $lines); $ar_buf = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); break; - case "command": + case 'command': $strDrives = ""; $strContent = ""; $hddtemp_value = ""; @@ -100,8 +89,7 @@ class HDDTemp extends Sensors } break; default: - $this->error->addConfigError("temperature()", "PSI_HDD_TEMP"); - break; + $this->error->addConfigError("temperature()", "[sensor_hddtemp] ACCESS"); } // Timo van Roermund: parse the info from the hddtemp daemon. foreach ($ar_buf as $line) { @@ -114,7 +102,7 @@ class HDDTemp extends Sensors if (is_numeric($data[3])) { $dev->setValue($data[3]); } - $dev->setMax(60); +// $dev->setMax(60); $this->mbinfo->setMbTemp($dev); } } @@ -126,7 +114,7 @@ class HDDTemp extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php index dce6759..23a401f 100644 --- a/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.healthd.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from healthd - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,28 +19,33 @@ class Healthd extends Sensors * * @var array */ - private $_lines = array(); + private $_values = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through command or data access */ public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + if (PSI_OS == 'FreeBSD') switch (defined('PSI_SENSOR_HEALTHD_ACCESS')?strtolower(PSI_SENSOR_HEALTHD_ACCESS):'command') { case 'command': - $lines = ""; - CommonFunctions::executeProgram('healthdc', '-t', $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + if (CommonFunctions::executeProgram('healthdc', '-t', $lines)) { + $lines0 = preg_split("/\n/", $lines, 1, PREG_SPLIT_NO_EMPTY); + if (count($lines0) == 1) { + $this->_values = preg_split("/\t+/", $lines0[0]); + } + } break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/healthd.txt', $lines)) { - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('healthd.tmp', $lines)) { + $lines0 = preg_split("/\n/", $lines, 1, PREG_SPLIT_NO_EMPTY); + if (count($lines0) == 1) { + $this->_values = preg_split("/\t+/", $lines0[0]); + } } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_healthd] ACCESS'); } } @@ -62,22 +56,23 @@ class Healthd extends Sensors */ private function _temperature() { - $ar_buf = preg_split("/\t+/", $this->_lines); - $dev1 = new SensorDevice(); - $dev1->setName('temp1'); - $dev1->setValue($ar_buf[1]); - $dev1->setMax(70); - $this->mbinfo->setMbTemp($dev1); - $dev2 = new SensorDevice(); - $dev2->setName('temp1'); - $dev2->setValue($ar_buf[2]); - $dev2->setMax(70); - $this->mbinfo->setMbTemp($dev2); - $dev3 = new SensorDevice(); - $dev3->setName('temp1'); - $dev3->setValue($ar_buf[3]); - $dev3->setMax(70); - $this->mbinfo->setMbTemp($dev3); + if (count($this->_values) == 14) { + $dev1 = new SensorDevice(); + $dev1->setName('temp1'); + $dev1->setValue($this->_values[1]); +// $dev1->setMax(70); + $this->mbinfo->setMbTemp($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('temp1'); + $dev2->setValue($this->_values[2]); +// $dev2->setMax(70); + $this->mbinfo->setMbTemp($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('temp1'); + $dev3->setValue($this->_values[3]); +// $dev3->setMax(70); + $this->mbinfo->setMbTemp($dev3); + } } /** @@ -87,60 +82,62 @@ class Healthd extends Sensors */ private function _fans() { - $ar_buf = preg_split("/\t+/", $this->_lines); - $dev1 = new SensorDevice(); - $dev1->setName('fan1'); - $dev1->setValue($ar_buf[4]); - $dev1->setMin(3000); - $this->mbinfo->setMbFan($dev1); - $dev2 = new SensorDevice(); - $dev2->setName('fan2'); - $dev2->setValue($ar_buf[5]); - $dev2->setMin(3000); - $this->mbinfo->setMbFan($dev2); - $dev3 = new SensorDevice(); - $dev3->setName('fan3'); - $dev3->setValue($ar_buf[6]); - $dev3->setMin(3000); - $this->mbinfo->setMbFan($dev3); + if (count($this->_values) == 14) { + $dev1 = new SensorDevice(); + $dev1->setName('fan1'); + $dev1->setValue($this->_values[4]); +// $dev1->setMin(3000); + $this->mbinfo->setMbFan($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('fan2'); + $dev2->setValue($this->_values[5]); +// $dev2->setMin(3000); + $this->mbinfo->setMbFan($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('fan3'); + $dev3->setValue($this->_values[6]); +// $dev3->setMin(3000); + $this->mbinfo->setMbFan($dev3); + } } /** * get voltage information * - * @return array voltage in array with lable + * @return void */ private function _voltage() { - $ar_buf = preg_split("/\t+/", $this->_lines); - $dev1 = new SensorDevice(); - $dev1->setName('Vcore1'); - $dev1->setValue($ar_buf[7]); - $this->mbinfo->setMbVolt($dev1); - $dev2 = new SensorDevice(); - $dev2->setName('Vcore2'); - $dev2->setValue($ar_buf[8]); - $this->mbinfo->setMbVolt($dev2); - $dev3 = new SensorDevice(); - $dev3->setName('3volt'); - $dev3->setValue($ar_buf[9]); - $this->mbinfo->setMbVolt($dev3); - $dev4 = new SensorDevice(); - $dev4->setName('+5Volt'); - $dev4->setValue($ar_buf[10]); - $this->mbinfo->setMbVolt($dev4); - $dev5 = new SensorDevice(); - $dev5->setName('+12Volt'); - $dev5->setValue($ar_buf[11]); - $this->mbinfo->setMbVolt($dev5); - $dev6 = new SensorDevice(); - $dev6->setName('-12Volt'); - $dev6->setValue($ar_buf[12]); - $this->mbinfo->setMbVolt($dev6); - $dev7 = new SensorDevice(); - $dev7->setName('-5Volt'); - $dev7->setValue($ar_buf[13]); - $this->mbinfo->setMbVolt($dev7); + if (count($this->_values) == 14) { + $dev1 = new SensorDevice(); + $dev1->setName('Vcore1'); + $dev1->setValue($this->_values[7]); + $this->mbinfo->setMbVolt($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('Vcore2'); + $dev2->setValue($this->_values[8]); + $this->mbinfo->setMbVolt($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('3volt'); + $dev3->setValue($this->_values[9]); + $this->mbinfo->setMbVolt($dev3); + $dev4 = new SensorDevice(); + $dev4->setName('+5Volt'); + $dev4->setValue($this->_values[10]); + $this->mbinfo->setMbVolt($dev4); + $dev5 = new SensorDevice(); + $dev5->setName('+12Volt'); + $dev5->setValue($this->_values[11]); + $this->mbinfo->setMbVolt($dev5); + $dev6 = new SensorDevice(); + $dev6->setName('-12Volt'); + $dev6->setValue($this->_values[12]); + $this->mbinfo->setMbVolt($dev6); + $dev7 = new SensorDevice(); + $dev7->setName('-5Volt'); + $dev7->setValue($this->_values[13]); + $this->mbinfo->setMbVolt($dev7); + } } /** @@ -148,7 +145,7 @@ class Healthd extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php b/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php new file mode 100644 index 0000000..077cfaf --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php @@ -0,0 +1,267 @@ + + * @copyright 2016 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Hwmon extends Sensors +{ + /** + * get temperature information + * + * @param string $hwpath + * @return void + */ + protected function _temperature($hwpath) + { + $sensor = CommonFunctions::findglob($hwpath."temp*_input", GLOB_NOSORT); + if (is_array($sensor) && (($total = count($sensor)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) { + $dev = new SensorDevice(); + $dev->setValue($buf/1000); + if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) { + $name = " (".$buf.")"; + } else { + $name = ""; + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) { + $dev->setName($buf.$name); + } else { + $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME))); + if (($name == " (drivetemp)") && (count($buf = CommonFunctions::gdc($hwpath . "device/block", false)))) { + $labelname = "/dev/" . $buf[0]; + if (($buf = CommonFunctions::rolv($hwpath . "device/model"))!==null) { + $labelname .= " (".$buf.")"; + $name = ""; + } + } + if ($labelname !== "") { + $dev->setName($labelname.$name); + } else { + $dev->setName('unknown'.$name); + } + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_crit"))!==null) { + $dev->setMax($buf/1000); + if (CommonFunctions::rolv($sensor[$i], "/_input$/", "_crit_alarm")==="1") { + $dev->setEvent("Critical Alarm"); + } + } elseif (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) { + $dev->setMax($buf/1000); + } + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @param string $hwpath + * @return void + */ + private function _voltage($hwpath) + { + $sensor = CommonFunctions::findglob($hwpath."in*_input", GLOB_NOSORT); + if (is_array($sensor) && (($total = count($sensor)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) { + $dev = new SensorDevice(); + $dev->setValue($buf/1000); + if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) { + $name = " (".$buf.")"; + } else { + $name = ""; + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) { + $dev->setName($buf.$name); + } else { + $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME))); + if ($labelname !== "") { + $dev->setName($labelname.$name); + } else { + $dev->setName('unknown'.$name); + } + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) { + $dev->setMax($buf/1000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) { + $dev->setMin($buf/1000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @param string $hwpath + * @return void + */ + protected function _fans($hwpath) + { + $sensor = CommonFunctions::findglob($hwpath."fan*_input", GLOB_NOSORT); + if (is_array($sensor) && (($total = count($sensor)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) { + $dev = new SensorDevice(); + $dev->setValue($buf); + if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) { + $name = " (".$buf.")"; + } else { + $name = ""; + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) { + $dev->setName($buf.$name); + } else { + $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME))); + if ($labelname !== "") { + $dev->setName($labelname.$name); + } else { + $dev->setName('unknown'.$name); + } + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_full_speed"))!==null) { + $dev->setMax($buf); + } elseif (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) { + $dev->setMax($buf); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) { + $dev->setMin($buf); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @param string $hwpath + * @return void + */ + private function _power($hwpath) + { + $sensor = CommonFunctions::findglob($hwpath."power*_input", GLOB_NOSORT); + if (is_array($sensor) && (($total = count($sensor)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) { + $dev = new SensorDevice(); + $dev->setValue($buf/1000000); + if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) { + $name = " (".$buf.")"; + } else { + $name = ""; + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) { + $dev->setName($buf.$name); + } else { + $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME))); + if ($labelname !== "") { + $dev->setName($labelname.$name); + } else { + $dev->setName('unknown'.$name); + } + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) { + $dev->setMax($buf/1000000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) { + $dev->setMin($buf/1000000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get current information + * + * @param string $hwpath + * @return void + */ + private function _current($hwpath) + { + $sensor = CommonFunctions::findglob($hwpath."curr*_input", GLOB_NOSORT); + if (is_array($sensor) && (($total = count($sensor)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) { + $dev = new SensorDevice(); + $dev->setValue($buf/1000); + if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) { + $name = " (".$buf.")"; + } else { + $name = ""; + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) { + $dev->setName($buf.$name); + } else { + $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME))); + if ($labelname !== "") { + $dev->setName($labelname.$name); + } else { + $dev->setName('unknown'.$name); + } + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) { + $dev->setMax($buf/1000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) { + $dev->setMin($buf/1000); + } + if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbCurrent($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) { + $hwpaths = CommonFunctions::findglob("/sys/class/hwmon/hwmon*/", GLOB_NOSORT); + if (is_array($hwpaths) && (count($hwpaths) > 0)) { + $hwpaths2 = CommonFunctions::findglob("/sys/class/hwmon/hwmon*/device/", GLOB_NOSORT); + if (is_array($hwpaths2) && (count($hwpaths2) > 0)) { + $hwpaths = array_merge($hwpaths, $hwpaths2); + } + $totalh = count($hwpaths); + for ($h = 0; $h < $totalh; $h++) { + $this->_temperature($hwpaths[$h]); + $this->_voltage($hwpaths[$h]); + $this->_fans($hwpaths[$h]); + $this->_power($hwpaths[$h]); + $this->_current($hwpaths[$h]); + } + } + } + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php index 948fba6..19e1199 100644 --- a/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.hwsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from hwsensors - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -33,15 +22,17 @@ class HWSensors extends Sensors private $_lines = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through command */ public function __construct() { parent::__construct(); - $lines = ""; -// CommonFunctions::executeProgram('sysctl', '-w hw.sensors', $lines); - CommonFunctions::executeProgram('sysctl', 'hw.sensors', $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + if (PSI_OS == 'OpenBSD') { + $lines = ""; +// CommonFunctions::executeProgram('sysctl', '-w hw.sensors', $lines); + CommonFunctions::executeProgram('sysctl', 'hw.sensors', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } } /** @@ -145,7 +136,7 @@ class HWSensors extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php deleted file mode 100644 index 1d16bde..0000000 --- a/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php +++ /dev/null @@ -1,197 +0,0 @@ - - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.ipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from ipmitool - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version Release: 3.0 - * @link http://phpsysinfo.sourceforge.net - */ -class IPMI extends Sensors -{ - /** - * content to parse - * - * @var array - */ - private $_lines = array(); - - /** - * fill the private content var through tcp or file access - */ - public function __construct() - { - parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { - case 'command': - CommonFunctions::executeProgram('ipmitool', 'sensor', $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); - break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/ipmi.txt', $lines)) { - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); - } - break; - default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; - } - } - - /** - * get temperature information - * - * @return void - */ - private function _temperature() - { - foreach ($this->_lines as $line) { - $buffer = preg_split("/\s*\|\s*/", $line); - if ($buffer[2] == "degrees C" && $buffer[3] != "na") { - $dev = new SensorDevice(); - $dev->setName($buffer[0]); - $dev->setValue($buffer[1]); - if ($buffer[8] != "na") $dev->setMax($buffer[8]); - switch ($buffer[3]) { - case "nr": $dev->setEvent("Non-Recoverable"); break; - case "cr": $dev->setEvent("Critical"); break; - case "nc": $dev->setEvent("Non-Critical"); break; - } - $this->mbinfo->setMbTemp($dev); - } - } - } - - /** - * get voltage information - * - * @return void - */ - private function _voltage() - { - foreach ($this->_lines as $line) { - $buffer = preg_split("/\s*\|\s*/", $line); - if ($buffer[2] == "Volts" && $buffer[3] != "na") { - $dev = new SensorDevice(); - $dev->setName($buffer[0]); - $dev->setValue($buffer[1]); - if ($buffer[5] != "na") $dev->setMin($buffer[5]); - if ($buffer[8] != "na") $dev->setMax($buffer[8]); - switch ($buffer[3]) { - case "nr": $dev->setEvent("Non-Recoverable"); break; - case "cr": $dev->setEvent("Critical"); break; - case "nc": $dev->setEvent("Non-Critical"); break; - } - $this->mbinfo->setMbVolt($dev); - } - } - } - - /** - * get fan information - * - * @return void - */ - private function _fans() - { - foreach ($this->_lines as $line) { - $buffer = preg_split("/\s*\|\s*/", $line); - if ($buffer[2] == "RPM" && $buffer[3] != "na") { - $dev = new SensorDevice(); - $dev->setName($buffer[0]); - $dev->setValue($buffer[1]); - if ($buffer[8] != "na") { - $dev->setMin($buffer[8]); - } elseif (($buffer[5] != "na") && ($buffer[5]<$buffer[1])) { //max instead min issue - $dev->setMin($buffer[5]); - } - switch ($buffer[3]) { - case "nr": $dev->setEvent("Non-Recoverable"); break; - case "cr": $dev->setEvent("Critical"); break; - case "nc": $dev->setEvent("Non-Critical"); break; - } - $this->mbinfo->setMbFan($dev); - } - } - } - - /** - * get power information - * - * @return void - */ - private function _power() - { - foreach ($this->_lines as $line) { - $buffer = preg_split("/\s*\|\s*/", $line); - if ($buffer[2] == "Watts" && $buffer[3] != "na") { - $dev = new SensorDevice(); - $dev->setName($buffer[0]); - $dev->setValue($buffer[1]); - if ($buffer[8] != "na") $dev->setMax($buffer[8]); - switch ($buffer[3]) { - case "nr": $dev->setEvent("Non-Recoverable"); break; - case "cr": $dev->setEvent("Critical"); break; - case "nc": $dev->setEvent("Non-Critical"); break; - } - $this->mbinfo->setMbPower($dev); - } - } - } - - /** - * get current information - * - * @return void - */ - private function _current() - { - foreach ($this->_lines as $line) { - $buffer = preg_split("/\s*\|\s*/", $line); - if ($buffer[2] == "Amps" && $buffer[3] != "na") { - $dev = new SensorDevice(); - $dev->setName($buffer[0]); - $dev->setValue($buffer[1]); - if ($buffer[8] != "na") $dev->setMax($buffer[8]); - switch ($buffer[3]) { - case "nr": $dev->setEvent("Non-Recoverable"); break; - case "cr": $dev->setEvent("Critical"); break; - case "nc": $dev->setEvent("Non-Critical"); break; - } - $this->mbinfo->setMbCurrent($dev); - } - } - } - - /** - * get the information - * - * @see PSI_Interface_Sensor::build() - * - * @return Void - */ - public function build() - { - $this->_temperature(); - $this->_voltage(); - $this->_fans(); - $this->_power(); - $this->_current(); - } -} diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php new file mode 100644 index 0000000..0fd3e6e --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php @@ -0,0 +1,321 @@ + + * @copyright 2021 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class IPMIcfg extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through command or data access + */ + public function __construct() + { + parent::__construct(); + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMICFG_ACCESS')?strtolower(PSI_SENSOR_IPMICFG_ACCESS):'command') { + case 'command': + if ((!defined('PSI_SENSOR_IPMICFG_SDR') || (PSI_SENSOR_IPMICFG_SDR!==false)) || + (!defined('PSI_SENSOR_IPMICFG_PSFRUINFO') || (PSI_SENSOR_IPMICFG_PSFRUINFO!==false)) || + (!defined('PSI_SENSOR_IPMICFG_PMINFO') || (PSI_SENSOR_IPMICFG_PMINFO!==false))) { + $lines=''; + $first=true; + if (!defined('PSI_SENSOR_IPMICFG_SDR') || (PSI_SENSOR_IPMICFG_SDR!==false)) { + $linestmp=''; + if (CommonFunctions::executeProgram('ipmicfg', '-sdr', $linestmp)) { + $lines=$linestmp; + } + $first=false; + } + if (!defined('PSI_SENSOR_IPMICFG_PSFRUINFO') || (PSI_SENSOR_IPMICFG_PSFRUINFO!==false)) { + $linestmp=''; + if (CommonFunctions::executeProgram('ipmicfg', '-psfruinfo', $linestmp, $first || PSI_DEBUG)) { + $lines.=$linestmp; + } + $first=false; + } + if (!defined('PSI_SENSOR_IPMICFG_PMINFO') || (PSI_SENSOR_IPMICFG_PMINFO!==false)) { + $linestmp=''; + if (CommonFunctions::executeProgram('ipmicfg', '-pminfo', $linestmp, $first || PSI_DEBUG)) { + $lines.=$linestmp; + } + } + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } else { + $this->error->addConfigError('__construct()', '[sensor_ipmicfg] Not defined: SDR or PSFRUINFO or PMINFO'); + } + break; + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('ipmicfg.tmp', $lines)) { + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', '[sensor_ipmicfg] ACCESS'); + } + + if ($this->_lines===false) { + $this->_lines = array(); + } else { + $pmbus=false; + for ($licz=count($this->_lines); $licz--; $licz>0) { + $line=$this->_lines[$licz]; + if (preg_match("/^\s*PMBus Revision\s*\|/", $line)) { + $pmbus=true; + } else if (preg_match("/^(\s*\[SlaveAddress = [\da..fA..F]+h\] \[)(Module )(\d+\])/", $line, $tmpbuf)) { + $this->_lines[$licz]=$tmpbuf[1].($pmbus?"PMBus ":"SMBus ").$tmpbuf[3]; + $pmbus=false; + } else { + $this->_lines[$licz]=preg_replace("/\|\s*$/", "", $line); + } + } + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + if ($valbuff[1]<-128) $valbuff[1]+=256; //+256 correction + $dev->setValue($valbuff[1]); + if (preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[3], $valbuffmin)) { + if ($valbuffmin[1]<-128) $valbuffmin[1]+=256; //+256 correction + } + if (preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[4], $valbuffmax)) { + if ($valbuffmax[1]<-128) $valbuffmax[1]+=256; //+256 correction + $dev->setMax($valbuffmax[1]); + } + if ((isset($valbuffmin[1]) && ($valbuff[1]<=$valbuffmin[1])) || (isset($valbuffmax[1]) && ($valbuff[1]>=$valbuffmax[1]))) { //own range test due to errors with +256 correction + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbTemp($dev); + } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[1], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($valbuff[1]); + $this->mbinfo->setMBTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([\d\.]+)\sV\s*$/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($valbuff[1]); + if (preg_match("/^\s*([\d\.].+)\sV\s*$/", $buffer[3], $valbuffmin)) { + $dev->setMin($valbuffmin[1]); + } + if (preg_match("/^\s*([\d\.].+)\sV\s*$/", $buffer[4], $valbuffmax)) { + $dev->setMax($valbuffmax[1]); + } + if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0])); + $this->mbinfo->setMbVolt($dev); + } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([\d\.]+)\sV\s*$/", $buffer[1], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($valbuff[1]); + $this->mbinfo->setMBVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($valbuff[1]); + if (preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[3], $valbuffmin)) { + $dev->setMin($valbuffmin[1]); + } + if ((trim($buffer[0]) != "OK") && isset($valbuffmin[1])) { + $dev->setEvent(trim($buffer[0])); + } + $this->mbinfo->setMbFan($dev); + } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[1], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($valbuff[1]); + $this->mbinfo->setMBFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*(\d+)\sWatts\s*$/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($valbuff[1]); + if (preg_match("/^\s*(\d+)\sWatts\s*$/", $buffer[4], $valbuffmax)) { + $dev->setMax($valbuffmax[1]); + } + if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0])); + $this->mbinfo->setMbPower($dev); + } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*(\d+)\sW\s*$/", $buffer[1], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($valbuff[1]); + $this->mbinfo->setMBPower($dev); + } + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([\d\.]+)\sAmps\s*$/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($valbuff[1]); + if (preg_match("/^\s*([\d\.].+)\sAmps\s*$/", $buffer[3], $valbuffmin)) { + $dev->setMin($valbuffmin[1]); + } + if (preg_match("/^\s*([\d\.].+)\sAmps\s*$/", $buffer[4], $valbuffmax)) { + $dev->setMax($valbuffmax[1]); + } + if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0])); + $this->mbinfo->setMbCurrent($dev); + } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([\d\.]+)\sA\s*$/", $buffer[1], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($valbuff[1]); + $this->mbinfo->setMBCurrent($dev); + } + } + } + + /** + * get other information + * + * @return void + */ + private function _other() + { + $mdid=''; + foreach ($this->_lines as $line) { + if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) { + $mdid=$mdidtmp[1]; + continue; + } + $buffer = preg_split("/\s*\|\s*/", $line); + if (($mdid=='') && (count($buffer)>=3) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff)) { + $buffer[2]=trim($buffer[2]); + if ((count($buffer)==3) && + ($buffer[2]!=="Correctable ECC / other correctable memory error") && + ($buffer[2]!=="Not Present") && + ($buffer[2]!=="N/A") && + (trim($buffer[0]) != "")) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($buffer[2]); + if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0])); + $this->mbinfo->setMbOther($dev); + } elseif ((count($buffer)==5)&& preg_match("/(^\s*[\d\.]+\s*$)|(^\s*[\da-fA-F]{2}\s+[\da-fA-F]{2}\s+[\da-fA-F]{2}\s+[\da-fA-F]{2}\s*$)/", $buffer[2], $valbuff)) { + $dev = new SensorDevice(); + $dev->setName($namebuff[1]); + $dev->setValue($buffer[0]); + $this->mbinfo->setMbOther($dev); + } + } elseif (($mdid!='') && (count($buffer)==2) && ((trim($buffer[0])=="Status") || (trim($buffer[0])=="Current Sharing Control"))) { + $dev = new SensorDevice(); + $dev->setName(trim($buffer[0])." (".$mdid.")"); + $dev->setValue($buffer[1]); + $this->mbinfo->setMbOther($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + $this->_other(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php new file mode 100644 index 0000000..bcdfcc7 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php @@ -0,0 +1,320 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class IPMItool extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_buf = array(); + + /** + * fill the private content var through command or data access + */ + public function __construct() + { + parent::__construct(); + $lines = ""; + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMITOOL_ACCESS')?strtolower(PSI_SENSOR_IPMITOOL_ACCESS):'command') { + case 'command': + CommonFunctions::executeProgram('ipmitool', 'sensor -v', $lines); + break; + case 'data': + if (!defined('PSI_EMU_PORT')) { + CommonFunctions::rftsdata('ipmitool.tmp', $lines); + } + break; + default: + $this->error->addConfigError('__construct()', '[sensor_ipmitool] ACCESS'); + } + if (trim($lines) !== "") { + if (preg_match("/^Sensor ID\s+/", $lines)) { //new data format ('ipmitool sensor -v') + $lines = preg_replace("/\n?Unable to read sensor/", "\nUnable to read sensor", $lines); + $sensors = preg_split("/Sensor ID\s+/", $lines, -1, PREG_SPLIT_NO_EMPTY); + foreach ($sensors as $sensor) { + if (preg_match("/^:\s*(.+)\s\((0x[a-f\d]+)\)\r?\n/", $sensor, $name) && (($name1 = trim($name[1])) !== "")) { + $sensorvalues = preg_split("/\r?\n/", $sensor, -1, PREG_SPLIT_NO_EMPTY); + unset($sensorvalues[0]); //skip first + $sens = array(); + $was = false; + foreach ($sensorvalues as $sensorvalue) { + if (preg_match("/^\s+\[(.+)\]$/", $sensorvalue, $buffer) && (($buffer1 = trim($buffer[1])) !== "")) { + if (isset($sens['State'])) { + $sens['State'] .= ', '.$buffer1; + } else { + $sens['State'] = $buffer1; + } + $was = true; + } elseif (preg_match("/^([^:]+):(.+)$/", $sensorvalue, $buffer) + && (($buffer1 = trim($buffer[1])) !== "") + && (($buffer2 = trim($buffer[2])) !== "")) { + $sens[$buffer1] = $buffer2; + $was = true; + } + } + if ($was && !isset($sens['Unable to read sensor'])) { + $sens['Sensor'] = $name1; + if (isset($sens['Sensor Reading']) + && preg_match("/^([\d\.]+)\s+\([^\)]*\)\s+(.+)$/", $sens['Sensor Reading'], $buffer) + && (($buffer2 = trim($buffer[2])) !== "")) { + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer2; + } + $this->_buf[intval($name[2], 0)] = $sens; + } + } + } + } else { + $lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + if (count($lines)>0) { + $buffer = preg_split("/\s*\|\s*/", $lines[0]); + if (count($buffer)>8) { //old data format ('ipmitool sensor') + foreach ($lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (count($buffer)>8) { + $sens = array(); + $sens['Sensor'] = $buffer[0]; + switch ($buffer[2]) { + case 'degrees C': + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer[2]; + $sens['Upper Critical'] = $buffer[8]; + $sens['Sensor Type (Threshold)'] = 'Temperature'; + break; + case 'Volts': + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer[2]; + $sens['Lower Critical'] = $buffer[5]; + $sens['Upper Critical'] = $buffer[8]; + $sens['Sensor Type (Threshold)'] = 'Voltage'; + break; + case 'RPM': + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer[2]; + $sens['Lower Critical'] = $buffer[5]; + $sens['Upper Critical'] = $buffer[8]; + $sens['Sensor Type (Threshold)'] = 'Fan'; + break; + case 'Watts': + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer[2]; + $sens['Upper Critical'] = $buffer[8]; + $sens['Sensor Type (Threshold)'] = 'Current'; + break; + case 'Amps': + $sens['Value'] = $buffer[1]; + $sens['Unit'] = $buffer[2]; + $sens['Lower Critical'] = $buffer[5]; + $sens['Upper Critical'] = $buffer[8]; + $sens['Sensor Type (Threshold)'] = 'Current'; + break; + case 'discrete': + if (($buffer[1]==='0x0') || ($buffer[1]==='0x1')) { + $sens['State'] = $buffer[1]; + $sens['Sensor Type (Discrete)'] = ''; + $sens['State'] = $buffer[1]; + } + } + $this->_buf[] = $sens; + } + } + } + } + } + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_buf as $sensor) { + if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Temperature')) + ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Temperature'))) + && isset($sensor['Unit']) && ($sensor['Unit'] == 'degrees C') + && isset($sensor['Value'])) { + $dev = new SensorDevice(); + $dev->setName($sensor['Sensor']); + $dev->setValue($sensor['Value']); + if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) { + $dev->setMax($max); + } + if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) { + $dev->setEvent($status); + } + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_buf as $sensor) { + if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Voltage')) + ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Voltage'))) + && isset($sensor['Unit']) && ($sensor['Unit'] == 'Volts') + && isset($sensor['Value'])) { + $dev = new SensorDevice(); + $dev->setName($sensor['Sensor']); + $dev->setValue($sensor['Value']); + if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) { + $dev->setMax($max); + } + if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) { + $dev->setMin($min); + } + if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) { + $dev->setEvent($status); + } + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_buf as $sensor) { + if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Fan')) + ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Fan'))) + && isset($sensor['Unit']) && ($sensor['Unit'] == 'RPM') + && isset($sensor['Value'])) { + $dev = new SensorDevice(); + $dev->setName($sensor['Sensor']); + $dev->setValue($value = $sensor['Value']); + if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) { + $dev->setMin($min); + } elseif (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na") + && ($max < $value)) { // max instead min issue + $dev->setMin($max); + } + if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) { + $dev->setEvent($status); + } + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + foreach ($this->_buf as $sensor) { + if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Current')) + ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Current'))) + && isset($sensor['Unit']) && ($sensor['Unit'] == 'Watts') + && isset($sensor['Value'])) { + $dev = new SensorDevice(); + $dev->setName($sensor['Sensor']); + $dev->setValue($sensor['Value']); + if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) { + $dev->setMax($max); + } + if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) { + $dev->setEvent($status); + } + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + foreach ($this->_buf as $sensor) { + if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Current')) + ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Current'))) + && isset($sensor['Unit']) && ($sensor['Unit'] == 'Amps') + && isset($sensor['Value'])) { + $dev = new SensorDevice(); + $dev->setName($sensor['Sensor']); + $dev->setValue($sensor['Value']); + if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) { + $dev->setMax($max); + } + if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) { + $dev->setMin($min); + } + if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) { + $dev->setEvent($status); + } + $this->mbinfo->setMbCurrent($dev); + } + } + } + + /** + * get other information + * + * @return void + */ + private function _other() + { + foreach ($this->_buf as $sensor) { + if (isset($sensor['Sensor Type (Discrete)'])) { + $dev = new SensorDevice(); + if ($sensor['Sensor Type (Discrete)']!=='') { + $dev->setName($sensor['Sensor'].' ('.$sensor['Sensor Type (Discrete)'].')'); + } else { + $dev->setName($sensor['Sensor']); + } + if (isset($sensor['State'])) { + $dev->setValue($sensor['State']); + } else { + $dev->setValue('0x0'); + } + $this->mbinfo->setMbOther($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + $this->_other(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php index 68613c3..ed36181 100644 --- a/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php @@ -1,25 +1,14 @@ - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.ipmiutil.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from ipmi-sensors - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @author Mieczyslaw Nalewaj + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -33,24 +22,23 @@ class IPMIutil extends Sensors private $_lines = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through command or data access */ public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMIUTIL_ACCESS')?strtolower(PSI_SENSOR_IPMIUTIL_ACCESS):'command') { case 'command': CommonFunctions::executeProgram('ipmiutil', 'sensor -stw', $lines); $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/ipmiutil.txt', $lines)) { + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('ipmiutil.tmp', $lines)) { $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_ipmiutil] ACCESS'); } } @@ -63,7 +51,10 @@ class IPMIutil extends Sensors { foreach ($this->_lines as $line) { $buffer = preg_split("/\s*\|\s*/", $line); - if (isset($buffer[2]) && $buffer[2] == "Temperature" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sC$/", $buffer[6], $value)) { + if (isset($buffer[2]) && $buffer[2] == "Temperature" + && $buffer[1] == "Full" + && isset($buffer[6]) && preg_match("/^(\S+)\sC$/", $buffer[6], $value) + && $buffer[5] !== "Init") { $dev = new SensorDevice(); $dev->setName($buffer[4]); $dev->setValue($value[1]); @@ -90,7 +81,10 @@ class IPMIutil extends Sensors { foreach ($this->_lines as $line) { $buffer = preg_split("/\s*\|\s*/", $line); - if (isset($buffer[2]) && $buffer[2] == "Voltage" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sV$/", $buffer[6], $value)) { + if (isset($buffer[2]) && $buffer[2] == "Voltage" + && $buffer[1] == "Full" + && isset($buffer[6]) && preg_match("/^(\S+)\sV$/", $buffer[6], $value) + && $buffer[5] !== "Init") { $dev = new SensorDevice(); $dev->setName($buffer[4]); $dev->setValue($value[1]); @@ -123,7 +117,10 @@ class IPMIutil extends Sensors { foreach ($this->_lines as $line) { $buffer = preg_split("/\s*\|\s*/", $line); - if (isset($buffer[2]) && $buffer[2] == "Fan" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sRPM$/", $buffer[6], $value)) { + if (isset($buffer[2]) && $buffer[2] == "Fan" + && $buffer[1] == "Full" + && isset($buffer[6]) && preg_match("/^(\S+)\sRPM$/", $buffer[6], $value) + && $buffer[5] !== "Init") { $dev = new SensorDevice(); $dev->setName($buffer[4]); $dev->setValue($value[1]); @@ -157,7 +154,10 @@ class IPMIutil extends Sensors { foreach ($this->_lines as $line) { $buffer = preg_split("/\s*\|\s*/", $line); - if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sW$/", $buffer[6], $value)) { + if (isset($buffer[2]) && $buffer[2] == "Current" + && $buffer[1] == "Full" + && isset($buffer[6]) && preg_match("/^(\S+)\sW$/", $buffer[6], $value) + && $buffer[5] !== "Init") { $dev = new SensorDevice(); $dev->setName($buffer[4]); $dev->setValue($value[1]); @@ -184,11 +184,20 @@ class IPMIutil extends Sensors { foreach ($this->_lines as $line) { $buffer = preg_split("/\s*\|\s*/", $line); - if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sA$/", $buffer[6], $value)) { + if (isset($buffer[2]) && $buffer[2] == "Current" + && $buffer[1] == "Full" + && isset($buffer[6]) && preg_match("/^(\S+)\sA$/", $buffer[6], $value) + && $buffer[5] !== "Init") { $dev = new SensorDevice(); $dev->setName($buffer[4]); $dev->setValue($value[1]); if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMin($limits[1]); + } if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) @@ -202,12 +211,50 @@ class IPMIutil extends Sensors } } + /** + * get other information + * + * @return void + */ + private function _other() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[1]) && $buffer[1] == "Compact" + && $buffer[5] !== "Init" + && $buffer[5] !== "Unknown" + && $buffer[5] !== "NotAvailable") { + $dev = new SensorDevice(); + $dev->setName($buffer[4].' ('.$buffer[2].')'); + + $buffer5s = preg_split("/\s+/", $buffer5 = $buffer[5]); + if (isset($buffer5s[1])) { + if (preg_match('/^[0-9A-Fa-f]+$/', $buffer5s[0])) { + $value = hexdec($buffer5s[0]) & 0xff; + if ($buffer5s[1] === 'DiscreteEvt') { + $dev->setValue('0x'.dechex($value)); + } elseif (($buffer5s[1] === 'DiscreteUnit') && ($value > 0)) { + $dev->setValue('0x'.dechex($value - 1)); + } else { + $dev->setValue($buffer5); + } + } else { + $dev->setValue($buffer5); + } + } else { + $dev->setValue($buffer5); + } + $this->mbinfo->setMbOther($dev); + } + } + } + /** * get the information * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { @@ -216,5 +263,6 @@ class IPMIutil extends Sensors $this->_fans(); $this->_power(); $this->_current(); + $this->_other(); } } diff --git a/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php index 9383353..d64611c 100644 --- a/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.k8temp.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from k8temp - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -38,20 +27,19 @@ class K8Temp extends Sensors public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_K8TEMP_ACCESS')?strtolower(PSI_SENSOR_K8TEMP_ACCESS):'command') { case 'command': $lines = ""; CommonFunctions::executeProgram('k8temp', '', $lines); $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/k8temp.txt', $lines)) { + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('k8temp.tmp', $lines)) { $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_k8temp] ACCESS'); } } @@ -67,7 +55,7 @@ class K8Temp extends Sensors if ($data[2] > 0) { $dev = new SensorDevice(); $dev->setName($data[1]); - $dev->setMax('70.0'); +// $dev->setMax('70.0'); if ($data[2] < 250) { $dev->setValue($data[2]); } @@ -82,7 +70,7 @@ class K8Temp extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php index e883c1e..5801767 100644 --- a/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.lmsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from lmsensor - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class LMSensors extends Sensors { /** - * content to parse + * array of values * * @var array */ - private $_lines = array(); + private $_values = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through command or data access */ public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + $lines = ""; + if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_LMSENSORS_ACCESS')?strtolower(PSI_SENSOR_LMSENSORS_ACCESS):'command') { case 'command': - if (CommonFunctions::executeProgram("sensors", "", $lines)) { - // Martijn Stolk: Dirty fix for misinterpreted output of sensors, - // where info could come on next line when the label is too long. - $lines = str_replace(":\n", ":", $lines); - $lines = str_replace("\n\n", "\n", $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); - } + CommonFunctions::executeProgram("sensors", "", $lines); break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/lmsensors.txt', $lines)) { - $lines = str_replace(":\n", ":", $lines); - $lines = str_replace("\n\n", "\n", $lines); - $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + case 'data': + if (!defined('PSI_EMU_PORT')) { + CommonFunctions::rftsdata('lmsensors.tmp', $lines); } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_lmsensors] ACCESS'); + } + + if (trim($lines) !== "") { + $lines = str_replace("\r\n", "\n", $lines); + $lines = str_replace(":\n", ":", $lines); + $lines = str_replace("\n\n", "\n", $lines); + $lines = preg_replace("/\n\s+\(/m", " (", $lines); + $_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + + $applearray1 = array( + "A" => "Ambient", + "B" => "Battery", + "C" => "CPU", + "G" => "GPU", + "H" => "Harddisk Bay", + "h" => "Heatpipe", + "L" => "LCD", + "M" => "Memory", + "m" => "Memory Contr.", + "N" => "Northbridge", + "O" => "Optical Drive", + "p" => "Power supply", + "S" => "Slot", + "s" => "Slot", + "W" => "Airport" + ); + $applearray3 = array( + "H" => "Heatsink", + "P" => "Proximity", + "D" => "Die" + ); + + $tmpvalue=array(); + $applesmc = false; + $sname = ''; + foreach ($_lines as $line) { + if ((trim($line) !== "") && (strpos($line, ':') === false)) { + if (sizeof($tmpvalue)>0) { + $this->_values[] = $tmpvalue; + $tmpvalue = array(); + } + $sname = trim($line); + $applesmc = ($sname === "applesmc-isa-0300"); + if (preg_match('/^([^-]+)-/', $sname, $snamebuf)) { + $sname = $snamebuf[1]; + } else { + $sname = ''; + } + } else { + if (preg_match("/^(.+):(.+)$/", trim($line), $data) && ($data[1]!=="Adapter")) { + if ($applesmc && (strlen($data[1]) == 4) && ($data[1][0] == "T")) { + if (isset($applearray1[$data[1][1]])) $data[1] .= " ".$applearray1[$data[1][1]]; + if (isset($applearray3[$data[1][3]])) $data[1] .= " ".$applearray3[$data[1][3]]; + } + + $arrtemp=array(); + if ($sname !== "" ) { + $arrtemp["name"] = $data[1]." (".$sname.")"; + } else { + $arrtemp["name"] = $data[1]; + } + if (preg_match("/^([^\(]+)\s+\(/", $data[2], $tmp) || preg_match("/^(.+)\s+ALARM$/", $data[2], $tmp)) { + if (($tmp[1] = trim($tmp[1])) == "") { + $arrtemp["value"] = "ALARM"; + } else { + $arrtemp["value"] = $tmp[1]; + } + if (preg_match("/\s(ALARM)\s*$/", $data[2]) || preg_match("/\s(ALARM)\s+\(/", $data[2]) || preg_match("/\s(ALARM)\s+sensor\s+=/", $data[2])) { + $arrtemp["alarm"]="ALARM"; + } + + if (preg_match_all("/\(([^\)]+\s+=\s+[^\)]+)\)/", $data[2], $tmp2)) foreach ($tmp2[1] as $tmp3) { + $arrtmp3 = preg_split('/,/', $tmp3); + foreach ($arrtmp3 as $tmp4) if (preg_match("/^(\S+)\s+=\s+(.*)$/", trim($tmp4), $tmp5)) { + $arrtemp[$tmp5[1]]=trim($tmp5[2]); + } + } + } else { + $arrtemp["value"] = trim($data[2]); + } + $tmpvalue[] = $arrtemp; + } + } + } + if (sizeof($tmpvalue)>0) $this->_values[] = $tmpvalue; } } @@ -68,88 +134,35 @@ class LMSensors extends Sensors */ private function _temperature() { - $ar_buf = array(); - foreach ($this->_lines as $line) { - $data = array(); - if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*)/", $line, $data); - } - if (count($data) > 1) { - $temp = substr(trim($data[2]), -1); - switch ($temp) { - case "C": -// case "F": - array_push($ar_buf, $line); - } - } - } - foreach ($ar_buf as $line) { - $data = array(); - if (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)\)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*).C[ \t]+/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*).C$/", $line, $data); - } - foreach ($data as $key=>$value) { - if (preg_match("/^\+?(-?[0-9\.]+).?$/", trim($value), $newvalue)) { - $data[$key] = 0+trim($newvalue[1]); - } else { - $data[$key] = trim($value); - } - } - $dev = new SensorDevice(); - - if (strlen($data[1]) == 4) { - if ($data[1][0] == "T") { - - if ($data[1][1] == "A") { - $data[1] = $data[1] . " Ambient"; - } elseif ($data[1][1] == "C") { - $data[1] = $data[1] . " CPU"; - } elseif ($data[1][1] == "G") { - $data[1] = $data[1] . " GPU"; - } elseif ($data[1][1] == "H") { - $data[1] = $data[1] . " Harddisk"; - } elseif ($data[1][1] == "L") { - $data[1] = $data[1] . " LCD"; - } elseif ($data[1][1] == "O") { - $data[1] = $data[1] . " ODD"; - } elseif ($data[1][1] == "B") { - $data[1] = $data[1] . " Battery"; + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + $limit = ""; + if (preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor["value"], $tmpbuf) || + ((isset($sensor[$limit="crit"]) || isset($sensor[$limit="high"]) || isset($sensor[$limit="hyst"])) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit]))) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + if ($limit != "") { + $dev->setValue($sensor["value"]); + $dev->setEvent("FAULT"); + } else { + if ($tmpbuf[1] == -110.8) { + $dev->setValue("FAULT"); + $dev->setEvent("FAULT"); + } else { + $dev->setValue(floatval($tmpbuf[1])); + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); + } } - if ($data[1][3] == "H") { - $data[1] = $data[1] . " Heatsink"; - } elseif ($data[1][3] == "P") { - $data[1] = $data[1] . " Proximity"; - } elseif ($data[1][3] == "D") { - $data[1] = $data[1] . " Die"; + if (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit], $tmpbuf) && (($tmpbuf[1]=floatval($tmpbuf[1])) > 0)) { + $dev->setMax(floatval($tmpbuf[1])); + } elseif (isset($sensor[$limit="high"]) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit], $tmpbuf) && (($tmpbuf[1]=floatval($tmpbuf[1])) > 0) && ($tmpbuf[1]<65261.8)) { + $dev->setMax(floatval($tmpbuf[1])); } + + $this->mbinfo->setMbTemp($dev); } } - - $dev->setName($data[1]); - $dev->setValue($data[2]); - - if (isset($data[6]) && $data[2] <= $data[6]) { - $dev->setMax(max($data[4], $data[6])); - } elseif (isset($data[4]) && $data[2] <= $data[4]) { - $dev->setMax($data[4]); - } - if (preg_match("/\sALARM(\s*)$/", $line)) { - $dev->setEvent("Alarm"); - } - $this->mbinfo->setMbTemp($dev); } } @@ -160,50 +173,32 @@ class LMSensors extends Sensors */ private function _fans() { - $ar_buf = array(); - foreach ($this->_lines as $line) { - $data = array(); - if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*)/", $line, $data); - } - if (count($data) > 1) { - $temp = substr(trim($data[2]), -4); - switch ($temp) { - case " RPM": - array_push($ar_buf, $line); + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + $limit = ""; + if (preg_match("/^(\d+) RPM$/", $sensor["value"], $tmpbuf) || + ((isset($sensor[$limit="min"]) || isset($sensor[$limit="max"])) && preg_match("/^(\d+) RPM$/", $sensor[$limit]))) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + if ($limit != "") { + $dev->setValue($sensor["value"]); + $dev->setEvent("FAULT"); + } else { + $dev->setValue($tmpbuf[1]); + } + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); + + if (isset($sensor[$limit="min"]) && preg_match("/^(\d+) RPM$/", $sensor[$limit], $tmpbuf) && ($tmpbuf[1] > 0)) { + $dev->setMin($tmpbuf[1]); + } + + $this->mbinfo->setMbFan($dev); } } } - foreach ($ar_buf as $line) { - $data = array(); - if (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)\)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) RPM[ \t]+/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*) RPM$/", $line, $data); - } - $dev = new SensorDevice(); - $dev->setName(trim($data[1])); - $dev->setValue(trim($data[2])); - if (isset($data[4])) { - $dev->setMin(trim($data[4])); - } - if (preg_match("/\sALARM(\s*)$/", $line)) { - $dev->setEvent("Alarm"); - } - $this->mbinfo->setMbFan($dev); - } } + /** * get voltage information * @@ -211,58 +206,37 @@ class LMSensors extends Sensors */ private function _voltage() { - $ar_buf = array(); - foreach ($this->_lines as $line) { - $data = array(); - if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*)\(/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*)/", $line, $data); - } - if (count($data) > 1) { - $temp = substr(trim($data[2]), -2); - switch ($temp) { - case " V": - array_push($ar_buf, $line); + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + $limit = ""; + if (preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor["value"], $tmpbuf) || + ((isset($sensor[$limit="min"]) || isset($sensor[$limit="max"])) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit]))) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + if ($limit != "") { + $dev->setValue($sensor["value"]); + $dev->setEvent("FAULT"); + } else { + if ($tmpbuf[2] == "m") { + $dev->setValue(floatval($tmpbuf[1])/1000); + } else { + $dev->setValue(floatval($tmpbuf[1])); + } + } + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); + + if (isset($sensor[$limit="min"]) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit], $tmpbuf)) { + $dev->setMin(floatval($tmpbuf[1])); + } + + if (isset($sensor[$limit="max"]) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit], $tmpbuf)) { + $dev->setMax(floatval($tmpbuf[1])); + } + + $this->mbinfo->setMbVolt($dev); } } } - foreach ($ar_buf as $line) { - $data = array(); - if (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)\)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) V[ \t]+/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*) V$/", $line, $data); - } - foreach ($data as $key=>$value) { - if (preg_match("/^\+?(-?[0-9\.]+)$/", trim($value), $newvalue)) { - $data[$key] = 0+trim($newvalue[1]); - } else { - $data[$key] = trim($value); - } - } - if (isset($data[1])) { - $dev = new SensorDevice(); - $dev->setName($data[1]); - $dev->setValue($data[2]); - if (isset($data[4])) { - $dev->setMin($data[4]); - } - if (isset($data[6])) { - $dev->setMax($data[6]); - } - if (preg_match("/\sALARM(\s*)$/", $line)) { - $dev->setEvent("Alarm"); - } - $this->mbinfo->setMbVolt($dev); - } - } } /** @@ -272,63 +246,32 @@ class LMSensors extends Sensors */ private function _power() { - $ar_buf = array(); - foreach ($this->_lines as $line) { - $data = array(); - if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*)/", $line, $data); - } - if (count($data) > 1) { - $temp = substr(trim($data[2]), -2); - switch ($temp) { - case " W": - array_push($ar_buf, $line); - } - } - } - foreach ($ar_buf as $line) { - $data = array(); -/* not tested yet - if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)\)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)/", $line, $data)) { - ; - } else -*/ - if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) W[ \t]+/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*) W$/", $line, $data); - } - foreach ($data as $key=>$value) { - if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) { - $data[$key] = trim($newvalue[1]); - } else { - $data[$key] = trim($value); - } - } - $dev = new SensorDevice(); - $dev->setName($data[1]); - $dev->setValue($data[2]); + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + $limit = ""; + if (preg_match("/^\+?(-?[\d\.]+) W$/", $sensor["value"], $tmpbuf) || + (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) W$/", $sensor[$limit]))) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + if ($limit != "") { + $dev->setValue($sensor["value"]); + $dev->setEvent("FAULT"); + } else { + $dev->setValue(floatval($tmpbuf[1])); + } + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); - if (isset($data[6]) && $data[2] <= $data[6]) { - $dev->setMax(max($data[4], $data[6])); - } elseif (isset($data[4]) && $data[2] <= $data[4]) { - $dev->setMax($data[4]); + if (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) W$/", $sensor[$limit], $tmpbuf)) { + $dev->setMax(floatval($tmpbuf[1])); + } + + $this->mbinfo->setMbPower($dev); + } } - if (preg_match("/\sALARM(\s*)$/", $line)) { - $dev->setEvent("Alarm"); - } - $this->mbinfo->setMbPower($dev); } } + /** * get current information * @@ -336,60 +279,54 @@ class LMSensors extends Sensors */ private function _current() { - $ar_buf = array(); - foreach ($this->_lines as $line) { - $data = array(); - if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*)/", $line, $data); - } - if (count($data) > 1) { - $temp = substr(trim($data[2]), -2); - switch ($temp) { - case " A": - array_push($ar_buf, $line); + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + $limit = ""; + if (preg_match("/^\+?(-?[\d\.]+) A$/", $sensor["value"], $tmpbuf) || + (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit]))) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + if ($limit != "") { + $dev->setValue($sensor["value"]); + $dev->setEvent("FAULT"); + } else { + $dev->setValue(floatval($tmpbuf[1])); + } + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); + + if (isset($sensor[$limit="min"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit], $tmpbuf)) { + $dev->setMin(floatval($tmpbuf[1])); + } + + if (isset($sensor[$limit="max"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit], $tmpbuf)) { + $dev->setMax(floatval($tmpbuf[1])); + } + + $this->mbinfo->setMbCurrent($dev); } } } - foreach ($ar_buf as $line) { - $data = array(); -/* not tested yet - if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)\)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)/", $line, $data)) { - ; - } else -*/ - if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A\)(.*)/", $line, $data)) { - ; - } elseif (preg_match("/(.*):(.*) A[ \t]+/", $line, $data)) { - ; - } else { - preg_match("/(.*):(.*) A$/", $line, $data); - } - foreach ($data as $key=>$value) { - if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) { - $data[$key] = trim($newvalue[1]); - } else { - $data[$key] = trim($value); + } + + /** + * get other information + * + * @return void + */ + private function _other() + { + foreach ($this->_values as $sensors) foreach ($sensors as $sensor){ + if (isset($sensor["value"])) { + if ((preg_match("/^[^\-\+\d]/", $sensor["value"]) || preg_match("/^\d+$/", $sensor["value"])) && ($sensor["value"] !== 'failed') && + !isset($sensor[$limit="min"]) && !isset($sensor[$limit="max"]) && !isset($sensor[$limit="crit"]) && !isset($sensor[$limit="high"]) && !isset($sensor[$limit="hyst"])) { + $dev = new SensorDevice(); + $dev->setName($sensor["name"]); + $dev->setValue($sensor["value"]); + if (isset($sensor["alarm"])) $dev->setEvent("ALARM"); + + $this->mbinfo->setMbOther($dev); } } - $dev = new SensorDevice(); - $dev->setName($data[1]); - $dev->setValue($data[2]); - - if (isset($data[6]) && $data[2] <= $data[6]) { - $dev->setMax(max($data[4], $data[6])); - } elseif (isset($data[4]) && $data[2] <= $data[4]) { - $dev->setMax($data[4]); - } - if (preg_match("/\sALARM(\s*)$/", $line)) { - $dev->setEvent("Alarm"); - } - $this->mbinfo->setMbCurrent($dev); } } @@ -398,14 +335,15 @@ class LMSensors extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { $this->_temperature(); - $this->_voltage(); $this->_fans(); + $this->_voltage(); $this->_power(); $this->_current(); + $this->_other(); } } diff --git a/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php index bd22b40..19b81ad 100644 --- a/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.mbm5.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from Motherboard Monitor 5 - * information retrival through csv file - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -46,20 +34,15 @@ class MBM5 extends Sensors public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { - case 'file': + if ((PSI_OS == 'WINNT') && !defined('PSI_EMU_HOSTNAME')) { $delim = "/;/"; - CommonFunctions::rfts(APP_ROOT."/data/MBM5.csv", $buffer); + CommonFunctions::rftsdata("MBM5.csv", $buffer); if (strpos($buffer, ";") === false) { $delim = "/,/"; } $buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); $this->_buf_label = preg_split($delim, substr($buffer[0], 0, -2), -1, PREG_SPLIT_NO_EMPTY); $this->_buf_value = preg_split($delim, substr($buffer[1], 0, -2), -1, PREG_SPLIT_NO_EMPTY); - break; - default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; } } @@ -78,7 +61,7 @@ class MBM5 extends Sensors $dev = new SensorDevice(); $dev->setName($this->_buf_label[$intPosi]); $dev->setValue($hits[0]); - $dev->setMax(70); +// $dev->setMax(70); $this->mbinfo->setMbTemp($dev); } } @@ -98,7 +81,7 @@ class MBM5 extends Sensors $dev = new SensorDevice(); $dev->setName($this->_buf_label[$intPosi]); $dev->setValue($hits[0]); - $dev->setMin(3000); +// $dev->setMin(3000); $this->mbinfo->setMbFan($dev); } } @@ -127,7 +110,7 @@ class MBM5 extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php index 351b0a8..05a00dc 100644 --- a/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php @@ -1,6 +1,6 @@ * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.mbmon.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from mbmon - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -33,14 +22,14 @@ class MBMon extends Sensors private $_lines = array(); /** - * fill the private content var through tcp or file access + * fill the private content var through tcp, command or data access */ public function __construct() { parent::__construct(); - switch (strtolower(PSI_SENSOR_ACCESS)) { + if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_MBMON_ACCESS')?strtolower(PSI_SENSOR_MBMON_ACCESS):'command') { case 'tcp': - $fp = fsockopen("localhost", 411, $errno, $errstr, 5); + $fp = fsockopen(defined('PSI_EMU_HOSTNAME')?PSI_EMU_HOSTNAME:'localhost', 411, $errno, $errstr, 5); if ($fp) { $lines = ""; while (!feof($fp)) { @@ -55,14 +44,13 @@ class MBMon extends Sensors CommonFunctions::executeProgram('mbmon', '-c 1 -r', $lines, PSI_DEBUG); $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); break; - case 'file': - if (CommonFunctions::rfts(APP_ROOT.'/data/mbmon.txt', $lines)) { + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('mbmon.tmp', $lines)) { $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); } break; default: - $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); - break; + $this->error->addConfigError('__construct()', '[sensor_mbmon] ACCESS'); } } @@ -78,7 +66,7 @@ class MBMon extends Sensors if ($data[2] <> '0') { $dev = new SensorDevice(); $dev->setName($data[1]); - $dev->setMax(70); +// $dev->setMax(70); if ($data[2] < 250) { $dev->setValue($data[2]); } @@ -101,7 +89,7 @@ class MBMon extends Sensors $dev = new SensorDevice(); $dev->setName($data[1]); $dev->setValue($data[2]); - $dev->setMax(3000); +// $dev->setMax(3000); $this->mbinfo->setMbFan($dev); } } diff --git a/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php new file mode 100644 index 0000000..149627f --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php @@ -0,0 +1,136 @@ + + * @copyright 2020 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class NvidiaSMI extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_gpus = array(); + + /** + * fill the private array + */ + public function __construct() + { + parent::__construct(); + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_NVIDIASMI_ACCESS')?strtolower(PSI_SENSOR_NVIDIASMI_ACCESS):'command') { + case 'command': + if (PSI_OS == 'WINNT') { + $winnt_exe = (defined('PSI_SENSOR_NVIDIASMI_EXE_PATH') && is_string(PSI_SENSOR_NVIDIASMI_EXE_PATH))?strtolower(PSI_SENSOR_NVIDIASMI_EXE_PATH):"c:\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe"; + if (($_exe=realpath(trim($winnt_exe))) && preg_match("/^([a-zA-Z]:\\\\[^\\\\]+)/", $_exe, $out)) { + CommonFunctions::executeProgram('cmd', "/c set ProgramFiles=".$out[1]."^&\"".$_exe."\" -q", $lines); + } else { + $this->error->addConfigError('__construct()', '[sensor_nvidiasmi] EXE_PATH="'.$winnt_exe.'"'); + } + } else { + CommonFunctions::executeProgram('nvidia-smi', '-q', $lines); + } + + $this->_gpus = preg_split("/^(?=GPU )/m", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'data': + if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('nvidiasmi.tmp', $lines)) { + $this->_gpus = preg_split("/^(?=GPU )/m", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', '[sensor_nvidiasmi] ACCESS'); + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $gpuc=count($this->_gpus); + switch ($gpuc) { + case 0: + $this->error->addError("nvidia-smi", "No values"); + break; + case 1: + $this->error->addError("nvidia-smi", "Error: ".$this->_gpus[0]); + break; + default: + for ($c = 0; $c < $gpuc; $c++) { + if (preg_match("/^\s+GPU Current Temp\s+:\s*(\d+)\s*C\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." (nvidiasmi)"); + $dev->setValue($out[1]); + if (preg_match("/^\s+GPU Shutdown Temp\s+:\s*(\d+)\s*C\s*$/m", $this->_gpus[$c], $out)) { + $dev->setMax($out[1]); + } + $this->mbinfo->setMbTemp($dev); + } + if (preg_match("/^\s+Power Draw\s+:\s*([\d\.]+)\s*W\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." (nvidiasmi)"); + $dev->setValue($out[1]); + if (preg_match("/^\s+Power Limit\s+:\s*([\d\.]+)\s*W\s*$/m", $this->_gpus[$c], $out)) { + $dev->setMax($out[1]); + } + $this->mbinfo->setMbPower($dev); + } + if (preg_match("/^\s+Fan Speed\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." (nvidiasmi)"); + $dev->setValue($out[1]); + $dev->setUnit("%"); + $this->mbinfo->setMbFan($dev); + } + if (preg_match("/^\s+Performance State\s+:\s*(\S+)\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." Performance State (nvidiasmi)"); + $dev->setValue($out[1]); + $this->mbinfo->setMbOther($dev); + } + if (preg_match("/^\s+Gpu\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." Utilization (nvidiasmi)"); + $dev->setValue($out[1]); + $dev->setUnit("%"); + $this->mbinfo->setMbOther($dev); + } + if (preg_match("/^\s+Memory\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." Memory Utilization (nvidiasmi)"); + $dev->setValue($out[1]); + $dev->setUnit("%"); + $this->mbinfo->setMbOther($dev); + } + if (preg_match("/^\s+Encoder\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." Encoder Utilization (nvidiasmi)"); + $dev->setValue($out[1]); + $dev->setUnit("%"); + $this->mbinfo->setMbOther($dev); + } + if (preg_match("/^\s+Decoder\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) { + $dev = new SensorDevice(); + $dev->setName("GPU ".($c)." Decoder Utilization (nvidiasmi)"); + $dev->setValue($out[1]); + $dev->setUnit("%"); + $this->mbinfo->setMbOther($dev); + } + } + } + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php index baed9bb..2eced04 100644 --- a/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php @@ -1,25 +1,14 @@ - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from Open Hardware Monitor - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @author Mieczyslaw Nalewaj + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -38,25 +27,16 @@ class OHM extends Sensors public function __construct() { parent::__construct(); - $_wmi = null; - // don't set this params for local connection, it will not work - $strHostname = ''; - $strUser = ''; - $strPassword = ''; - try { - // initialize the wmi object - $objLocator = new COM('WbemScripting.SWbemLocator'); - if ($strHostname == "") { - $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor'); - - } else { - $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor', $strHostname.'\\'.$strUser, $strPassword); + if ((PSI_OS == 'WINNT') || (defined('PSI_EMU_HOSTNAME') && !defined('PSI_EMU_PORT'))) { + $_wmi = WINNT::initWMI('root\OpenHardwareMonitor', true); + if ($_wmi) { + $tmpbuf = WINNT::getWMI($_wmi, 'Sensor', array('Parent', 'Name', 'SensorType', 'Value')); + if ($tmpbuf) foreach ($tmpbuf as $buffer) { + if (!isset($this->_buf[$buffer['SensorType']]) || !isset($this->_buf[$buffer['SensorType']][$buffer['Parent'].' '.$buffer['Name']])) { // avoid duplicates + $this->_buf[$buffer['SensorType']][$buffer['Parent'].' '.$buffer['Name']] = $buffer['Value']; + } + } } - } catch (Exception $e) { - $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for OpenHardwareMonitor data."); - } - if ($_wmi) { - $this->_buf = CommonFunctions::getWMI($_wmi, 'Sensor', array('Parent', 'Name', 'SensorType', 'Value')); } } @@ -67,13 +47,11 @@ class OHM extends Sensors */ private function _temperature() { - if ($this->_buf) foreach ($this->_buf as $buffer) { - if ($buffer['SensorType'] == "Temperature") { - $dev = new SensorDevice(); - $dev->setName($buffer['Parent'].' '.$buffer['Name']); - $dev->setValue($buffer['Value']); - $this->mbinfo->setMbTemp($dev); - } + if (isset($this->_buf['Temperature'])) foreach ($this->_buf['Temperature'] as $name=>$value) { + $dev = new SensorDevice(); + $dev->setName($name); + $dev->setValue($value); + $this->mbinfo->setMbTemp($dev); } } @@ -84,13 +62,11 @@ class OHM extends Sensors */ private function _voltage() { - if ($this->_buf) foreach ($this->_buf as $buffer) { - if ($buffer['SensorType'] == "Voltage") { - $dev = new SensorDevice(); - $dev->setName($buffer['Parent'].' '.$buffer['Name']); - $dev->setValue($buffer['Value']); - $this->mbinfo->setMbVolt($dev); - } + if (isset($this->_buf['Voltage'])) foreach ($this->_buf['Voltage'] as $name=>$value) { + $dev = new SensorDevice(); + $dev->setName($name); + $dev->setValue($value); + $this->mbinfo->setMbVolt($dev); } } @@ -101,13 +77,11 @@ class OHM extends Sensors */ private function _fans() { - if ($this->_buf) foreach ($this->_buf as $buffer) { - if ($buffer['SensorType'] == "Fan") { - $dev = new SensorDevice(); - $dev->setName($buffer['Parent'].' '.$buffer['Name']); - $dev->setValue($buffer['Value']); - $this->mbinfo->setMbFan($dev); - } + if (isset($this->_buf['Fan'])) foreach ($this->_buf['Fan'] as $name=>$value) { + $dev = new SensorDevice(); + $dev->setName($name); + $dev->setValue($value); + $this->mbinfo->setMbFan($dev); } } @@ -118,13 +92,11 @@ class OHM extends Sensors */ private function _power() { - if ($this->_buf) foreach ($this->_buf as $buffer) { - if ($buffer['SensorType'] == "Power") { - $dev = new SensorDevice(); - $dev->setName($buffer['Parent'].' '.$buffer['Name']); - $dev->setValue($buffer['Value']); - $this->mbinfo->setMbPower($dev); - } + if (isset($this->_buf['Power'])) foreach ($this->_buf['Power'] as $name=>$value) { + $dev = new SensorDevice(); + $dev->setName($name); + $dev->setValue($value); + $this->mbinfo->setMbPower($dev); } } @@ -133,7 +105,7 @@ class OHM extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php index 1455ad5..ff55719 100644 --- a/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php @@ -7,8 +7,10 @@ * @category PHP * @package PSI_Sensor * @author Marc Hillesheim - * @copyright 2012 Marc Hillesheim - * @link http://pi.no-ip.biz + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net */ class PiTemp extends Sensors { @@ -16,15 +18,15 @@ class PiTemp extends Sensors { $temp = null; $temp_max = null; - if (!CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input', $temp, 0, 4096, false)) { // Not Banana Pi - CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/temp', $temp); - CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/trip_point_0_temp', $temp_max, 0, 4096, PSI_DEBUG); + if (!CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input', $temp, 1, 4096, false)) { // Not Banana Pi + CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/temp', $temp, 1); + CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/trip_point_0_temp', $temp_max, 1, 4096, PSI_DEBUG); } - if (!is_null($temp) && (trim($temp) != "")) { + if (($temp !== null) && (($temp = trim($temp)) != "")) { $dev = new SensorDevice(); $dev->setName("CPU 1"); $dev->setValue($temp / 1000); - if (!is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) { + if (($temp_max !== null) && (($temp_max = trim($temp_max)) != "") && ($temp_max > 0)) { $dev->setMax($temp_max / 1000); } $this->mbinfo->setMbTemp($dev); @@ -34,7 +36,7 @@ class PiTemp extends Sensors private function _voltage() { $volt = null; - if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now', $volt, 0, 4096, false) && !is_null($volt) && (trim($volt) != "")) { // Banana Pi + if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now', $volt, 1, 4096, false) && ($volt !== null) && (($volt = trim($volt)) != "")) { // Banana Pi $dev = new SensorDevice(); $dev->setName("Voltage 1"); $dev->setValue($volt / 1000000); @@ -45,7 +47,7 @@ class PiTemp extends Sensors private function _current() { $current = null; - if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now', $current, 0, 4096, false) && !is_null($current) && (trim($current) != "")) { // Banana Pi + if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now', $current, 1, 4096, false) && ($current !== null) && (($current = trim($current)) != "")) { // Banana Pi $dev = new SensorDevice(); $dev->setName("Current 1"); $dev->setValue($current / 1000000); @@ -55,8 +57,10 @@ class PiTemp extends Sensors public function build() { - $this->_temperature(); - $this->_voltage(); - $this->_current(); + if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) { + $this->_temperature(); + $this->_voltage(); + $this->_current(); + } } } diff --git a/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php b/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php new file mode 100644 index 0000000..475831a --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php @@ -0,0 +1,93 @@ + + * @copyright 2016 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class QTSsnmp extends Sensors +{ + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + if (!defined('PSI_EMU_PORT')) { + $address = '127.0.0.1'; + } else { + $address = PSI_EMU_HOSTNAME; + } + if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.5.0", $buffer, PSI_DEBUG) + && preg_match('/^[\.\d]+ = STRING:\s\"?(\d+)\sC/', $buffer, $data)) { + $dev = new SensorDevice(); + $dev->setName("CPU"); + $dev->setValue($data[1]); + $this->mbinfo->setMbTemp($dev); + } + + if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.6.0", $buffer, PSI_DEBUG) + && preg_match('/^[\.\d]+ = STRING:\s\"?(\d+)\sC/', $buffer, $data)) { + $dev = new SensorDevice(); + $dev->setName("System"); + $dev->setValue($data[1]); + $this->mbinfo->setMbTemp($dev); + } + + if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.11.1.3", $buffer, PSI_DEBUG)) { + $lines = preg_split('/\r?\n/', $buffer); + foreach ($lines as $line) if (preg_match('/^[\.\d]+\.(\d+) = STRING:\s\"?(\d+)\sC/', $line, $data)) { + $dev = new SensorDevice(); + $dev->setName("HDD ".$data[1]); + $dev->setValue($data[2]); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + if (!defined('PSI_EMU_PORT')) { + $address = '127.0.0.1'; + } else { + $address = PSI_EMU_HOSTNAME; + } + if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.15.1.3", $buffer, PSI_DEBUG)) { + $lines = preg_split('/\r?\n/', $buffer); + foreach ($lines as $line) if (preg_match('/^[\.\d]+\.(\d+) = STRING:\s\"?(\d+)\sRPM/', $line, $data)) { + $dev = new SensorDevice(); + $dev->setName("Fan ".$data[1]); + $dev->setValue($data[2]); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) { + $this->_temperature(); + $this->_fans(); + } + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php index a37385b..dce90ac 100644 --- a/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php @@ -8,7 +8,7 @@ * @package PSI sensors class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.sensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI sensors class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,7 +28,7 @@ abstract class Sensors implements PSI_Interface_Sensor /** * object for error handling * - * @var Error + * @var PSI_Error */ protected $error; @@ -44,7 +44,7 @@ abstract class Sensors implements PSI_Interface_Sensor */ public function __construct() { - $this->error = Error::singleton(); + $this->error = PSI_Error::singleton(); $this->mbinfo = new MBInfo(); } diff --git a/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php b/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php new file mode 100644 index 0000000..628d811 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php @@ -0,0 +1,125 @@ + + * @copyright 2016 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SpeedFan extends Sensors +{ + /* + * variable, which holds the content of the command + * @var array + */ + private $_filecontent = array(); + + public function __construct() + { + parent::__construct(); + if ((PSI_OS == 'WINNT') && !defined('PSI_EMU_HOSTNAME')) switch (defined('PSI_SENSOR_SPEEDFAN_ACCESS')?strtolower(PSI_SENSOR_SPEEDFAN_ACCESS):'command') { + case 'command': + if (CommonFunctions::executeProgram("SpeedFanGet.exe", "", $buffer, PSI_DEBUG) && (strlen($buffer) > 0)) { + if (preg_match("/^Temperatures:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["temp"] = $out[1]; + } + if (preg_match("/^Fans:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["fans"] = $out[1]; + } + if (preg_match("/^Voltages:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["volt"] = $out[1]; + } + } + break; + case 'data': + if (CommonFunctions::rftsdata('speedfan.tmp', $buffer) && (strlen($buffer) > 0)) { + if (preg_match("/^Temperatures:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["temp"] = $out[1]; + } + if (preg_match("/^Fans:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["fans"] = $out[1]; + } + if (preg_match("/^Voltages:\s+(.+)$/m", $buffer, $out)) { + $this->_filecontent["volt"] = $out[1]; + } + } + break; + default: + $this->error->addConfigError('__construct()', '[sensor_speedfan] ACCESS'); + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + if (isset($this->_filecontent["temp"]) && (trim($this->_filecontent["temp"]) !== "")) { + $values = preg_split("/ /", trim($this->_filecontent["temp"])); + foreach ($values as $id=>$value) { + $dev = new SensorDevice(); + $dev->setName("temp".$id); + $dev->setValue($value); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + if (isset($this->_filecontent["fans"]) && (trim($this->_filecontent["fans"]) !== "")) { + $values = preg_split("/ /", trim($this->_filecontent["fans"])); + foreach ($values as $id=>$value) { + $dev = new SensorDevice(); + $dev->setName("fan".$id); + $dev->setValue($value); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + if (isset($this->_filecontent["volt"]) && (trim($this->_filecontent["volt"]) !== "")) { + $values = preg_split("/ /", trim($this->_filecontent["volt"])); + foreach ($values as $id=>$value) { + $dev = new SensorDevice(); + $dev->setName("in".$id); + $dev->setValue($value); + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $this->_temperature(); + $this->_fans(); + $this->_voltage(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php index 6abd7c1..19ddcb6 100644 --- a/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php +++ b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php @@ -1,31 +1,20 @@ - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $ - * @link http://phpsysinfo.sourceforge.net - */ - /** - * getting information from Thermal Zone WMI class - * - * @category PHP - * @package PSI_Sensor - * @author Michael Cramer - * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @author Mieczyslaw Nalewaj + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class ThermalZone extends Sensors { -/** + /** * holds the COM object that we pull all the WMI data from * * @var Object @@ -38,27 +27,39 @@ class ThermalZone extends Sensors public function __construct() { parent::__construct(); - if (PSI_OS == 'WINNT') { - $_wmi = null; - // don't set this params for local connection, it will not work - $strHostname = ''; - $strUser = ''; - $strPassword = ''; - try { - // initialize the wmi object - $objLocator = new COM('WbemScripting.SWbemLocator'); - if ($strHostname == "") { - $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI'); - + switch (defined('PSI_SENSOR_THERMALZONE_ACCESS')?strtolower(PSI_SENSOR_THERMALZONE_ACCESS):'command') { + case 'command': + if ((PSI_OS == 'WINNT') || (defined('PSI_EMU_HOSTNAME') && !defined('PSI_EMU_PORT'))) { + if (defined('PSI_EMU_HOSTNAME') || WINNT::isAdmin()) { + $_wmi = WINNT::initWMI('root\WMI', true); + if ($_wmi) { + $this->_buf = WINNT::getWMI($_wmi, 'MSAcpi_ThermalZoneTemperature', array('InstanceName', 'CriticalTripPoint', 'CurrentTemperature')); + } } else { - $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI', $strHostname.'\\'.$strUser, $strPassword); + $_wmi = WINNT::getcimv2wmi(); + if ($_wmi) { + $this->_buf = WINNT::getWMI($_wmi, 'Win32_PerfFormattedData_Counters_ThermalZoneInformation', array('Name', 'HighPrecisionTemperature', 'Temperature')); + } + if (!$this->_buf || PSI_DEBUG) { + $this->error->addError("Error reading data from thermalzone sensor", "Allowed only for systems with administrator privileges (run as administrator)"); + } } - } catch (Exception $e) { - $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for ThermalZone data."); } - if ($_wmi) { - $this->_buf = CommonFunctions::getWMI($_wmi, 'MSAcpi_ThermalZoneTemperature', array('InstanceName', 'CriticalTripPoint', 'CurrentTemperature')); + break; + case 'data': + if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::rftsdata('thermalzone.tmp', $lines)) { //output of "wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CriticalTripPoint,CurrentTemperature,InstanceName" + $lines = trim(preg_replace('/[\x00-\x09\x0b-\x1F]/', '', $lines)); + $lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + if ((($clines=count($lines)) > 1) && preg_match("/CriticalTripPoint\s+CurrentTemperature\s+InstanceName/i", $lines[0])) for ($i = 1; $i < $clines; $i++) { + $values = preg_split("/\s+/", trim($lines[$i]), -1, PREG_SPLIT_NO_EMPTY); + if (count($values)==3) { + $this->_buf[] = array('CriticalTripPoint'=>trim($values[0]), 'CurrentTemperature'=>trim($values[1]), 'InstanceName'=>trim($values[2])); + } + } } + break; + default: + $this->error->addConfigError('__construct()', '[sensor_thermalzone] ACCESS'); } } @@ -69,7 +70,9 @@ class ThermalZone extends Sensors */ private function _temperature() { - if (PSI_OS == 'WINNT') { + $mode = defined('PSI_SENSOR_THERMALZONE_ACCESS')?strtolower(PSI_SENSOR_THERMALZONE_ACCESS):'command'; + if ((($mode == 'command') && ((PSI_OS == 'WINNT') || defined('PSI_EMU_HOSTNAME'))) + || (($mode == 'data') && !defined('PSI_EMU_HOSTNAME'))) { if ($this->_buf) foreach ($this->_buf as $buffer) { if (isset($buffer['CurrentTemperature']) && (($value = ($buffer['CurrentTemperature'] - 2732)/10) > -100)) { $dev = new SensorDevice(); @@ -83,34 +86,73 @@ class ThermalZone extends Sensors $dev->setMax($maxvalue); } $this->mbinfo->setMbTemp($dev); + } else { + if ((isset($buffer['HighPrecisionTemperature']) && (($value = ($buffer['HighPrecisionTemperature'] - 2732)/10) > -100)) + || (isset($buffer['Temperature']) && (($value = ($buffer['Temperature'] - 273)) > -100))) { + $dev = new SensorDevice(); + if (isset($buffer['Name']) && preg_match("/([^\\\\\. ]+)$/", $buffer['Name'], $outbuf)) { + $dev->setName('ThermalZone '.$outbuf[1]); + } else { + $dev->setName('ThermalZone THM0'); + } + $dev->setValue($value); + $this->mbinfo->setMbTemp($dev); + } } } - } else { - foreach (glob('/sys/class/thermal/thermal_zone*/') as $thermalzone) { + } elseif (($mode == 'command') && (PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) { + $notwas = true; + $thermalzones = CommonFunctions::findglob('/sys/class/thermal/thermal_zone*/'); + if (is_array($thermalzones) && (count($thermalzones) > 0)) foreach ($thermalzones as $thermalzone) { $thermalzonetemp = $thermalzone.'temp'; $temp = null; - if (CommonFunctions::rfts($thermalzonetemp, $temp, 0, 4096, false) && !is_null($temp) && (trim($temp) != "")) { + if (CommonFunctions::rfts($thermalzonetemp, $temp, 1, 4096, false) && ($temp !== null) && (($temp = trim($temp)) != "")) { if ($temp >= 1000) { - $temp = $temp / 1000; + $div = 1000; + } elseif ($temp >= 200) { + $div = 10; + } else { + $div = 1; } - + $temp = $temp / $div; + if ($temp > -40) { $dev = new SensorDevice(); $dev->setValue($temp); $temp_type = null; - if (CommonFunctions::rfts($thermalzone.'type', $temp_type, 0, 4096, false) && !is_null($temp_type) && (trim($temp_type) != "")) { + if (CommonFunctions::rfts($thermalzone.'type', $temp_type, 1, 4096, false) && ($temp_type !== null) && (($temp_type = trim($temp_type)) != "")) { $dev->setName($temp_type); + } else { + $dev->setName("ThermalZone"); } $temp_max = null; - if (CommonFunctions::rfts($thermalzone.'trip_point_0_temp', $temp_max, 0, 4096, false) && !is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) { - if ($temp_max >= 1000) { - $temp_max = $temp_max / 1000; + if (CommonFunctions::rfts($thermalzone.'trip_point_0_temp', $temp_max, 1, 4096, false) && ($temp_max !== null) && (($temp_max = trim($temp_max)) != "") && ($temp_max > -40)) { + $temp_max = $temp_max / $div; + if (($temp_max != 0) || ($temp != 0)) { // if non-zero values + $dev->setMax($temp_max); + $this->mbinfo->setMbTemp($dev); } - $dev->setMax($temp_max); + } else { + $this->mbinfo->setMbTemp($dev); } - + $notwas = false; + } + } + } + if ($notwas) { + $thermalzones = (PSI_ROOT_FILESYSTEM.'/proc/acpi/thermal_zone/TH*/temperature'); + if (is_array($thermalzones) && (count($thermalzones) > 0)) foreach ($thermalzones as $thermalzone) { + $temp = null; + if (CommonFunctions::rfts($thermalzone, $temp, 1, 4096, false) && ($temp !== null) && (($temp = trim($temp)) != "")) { + $dev = new SensorDevice(); + if (preg_match("/^\/proc\/acpi\/thermal_zone\/(.+)\/temperature$/", $thermalzone, $name)) { + $dev->setName("ThermalZone ".$name[1]); + } else { + $dev->setName("ThermalZone"); + } + $dev->setValue(trim(substr($temp, 23, 4))); $this->mbinfo->setMbTemp($dev); } } @@ -123,7 +165,7 @@ class ThermalZone extends Sensors * * @see PSI_Interface_Sensor::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php b/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php new file mode 100644 index 0000000..ee24091 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php @@ -0,0 +1,41 @@ + + * @copyright 2017 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Thinkpad extends Hwmon +{ + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) { + $hwpaths = CommonFunctions::findglob("/sys/devices/platform/thinkpad_hwmon/", GLOB_NOSORT); + if (is_array($hwpaths) && (count($hwpaths) == 1)) { + $hwpaths2 = CommonFunctions::findglob("/sys/devices/platform/thinkpad_hwmon/hwmon/hwmon*/", GLOB_NOSORT); + if (is_array($hwpaths2) && (count($hwpaths2) > 0)) { + $hwpaths = array_merge($hwpaths, $hwpaths2); + } + $totalh = count($hwpaths); + for ($h = 0; $h < $totalh; $h++) { + $this->_temperature($hwpaths[$h]); + $this->_fans($hwpaths[$h]); + } + } + } + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.AIX.inc.php b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php index 61ce603..2bae924 100644 --- a/root/opt/phpsysinfo/includes/os/class.AIX.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php @@ -8,7 +8,7 @@ * @package PSI AIX OS class * @author Krzysztof Paz (kpaz@gazeta.pl) based on HPUX of Michael Cramer * @copyright 2011 Krzysztof Paz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.AIX.inc.php 287 2009-06-26 12:11:59Z Krzysztof Paz, IBM POLSKA * @link http://phpsysinfo.sourceforge.net */ @@ -20,13 +20,20 @@ * @package PSI AIX OS class * @author Krzysztof Paz (kpaz@gazeta.pl) based on Michael Cramer * @copyright 2011 Krzysztof Paz -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class AIX extends OS { + /** + * uptime command result. + */ + private $_uptime = null; + /** + * prtconf command result. + */ private $_aixdata = array(); /** @@ -35,34 +42,17 @@ class AIX extends OS */ private function _hostname() { - /* if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + /* if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('hostname', '', $ret)) { $this->sys->setHostname($ret); } } */ - $this->sys->setHostname(getenv('SERVER_NAME')); + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } - /** - * IP of the Virtual Host Name - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * IBM AIX Version * @return void @@ -81,8 +71,8 @@ class AIX extends OS */ private function _uptime() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf) || preg_match("/up (\d+) day,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/up (\d+) day[s]?,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) { $min = $ar_buf[3]; $hours = $ar_buf[2]; $days = $ar_buf[1]; @@ -91,17 +81,6 @@ class AIX extends OS } } - /** - * Number of Users - * @return void - */ - private function _users() - { - if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) { - $this->sys->setUsers($buf); - } - } - /** * Processor Load * optionally create a loadbar @@ -109,8 +88,8 @@ class AIX extends OS */ private function _loadavg() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) { $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); } } @@ -305,7 +284,7 @@ class AIX extends OS $mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) { $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); - while (list(, $line) = each($lines)) { + foreach ($lines as $line) { $a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY); $fsdev[$a[0]] = $a[4]; } @@ -339,7 +318,7 @@ class AIX extends OS /** * IBM AIX informations by K.PAZ - * @return void + * @return array */ private function readaixdata() { @@ -357,25 +336,34 @@ class AIX extends OS * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->error->addError("WARN", "The AIX version of phpSysInfo is a work in progress, some things currently don't work"); - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_loadavg(); - $this->_cpuinfo(); - $this->_pci(); - $this->_ide(); - $this->_scsi(); - $this->_usb(); - $this->_network(); - $this->_memory(); - $this->_filesystems(); + $this->error->addWarning("The AIX version of phpSysInfo is a work in progress, some things currently don't work"); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_cpuinfo(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_usb(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.Android.inc.php b/root/opt/phpsysinfo/includes/os/class.Android.inc.php index 04c88e4..3286a24 100644 --- a/root/opt/phpsysinfo/includes/os/class.Android.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.Android.inc.php @@ -8,7 +8,7 @@ * @package PSI Android OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,18 +20,33 @@ * @package PSI Android OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class Android extends Linux { /** - * call parent constructor + * holds the data from /system/build.prop file + * + * @var string */ - public function __construct() + private $_buildprop = null; + + /** + * reads the data from /system/build.prop file + * + * @return string + */ + private function _get_buildprop() { - parent::__construct(); + if ($this->_buildprop === null) { + if (!CommonFunctions::rfts('/system/build.prop', $this->_buildprop, 0, 4096, false)) { + CommonFunctions::rfts('/system//build.prop', $this->_buildprop, 0, 4096, false); //fix some access issues + } + } + + return $this->_buildprop; } /** @@ -39,16 +54,25 @@ class Android extends Linux * * @return void */ - private function _kernel() + protected function _kernel() { - if (CommonFunctions::rfts('/proc/version', $strBuf, 1)) { - if (preg_match('/version (.*?) /', $strBuf, $ar_buf)) { - $result = $ar_buf[1]; + if (CommonFunctions::executeProgram('uname', '-r', $strBuf, false)) { + $result = $strBuf; + if (CommonFunctions::executeProgram('uname', '-v', $strBuf, PSI_DEBUG)) { if (preg_match('/SMP/', $strBuf)) { $result .= ' (SMP)'; } - $this->sys->setKernel($result); } + if (CommonFunctions::executeProgram('uname', '-m', $strBuf, PSI_DEBUG)) { + $result .= ' '.$strBuf; + } + $this->sys->setKernel($result); + } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) && preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) { + $result = $ar_buf[1]; + if (preg_match('/SMP/', $strBuf)) { + $result .= ' (SMP)'; + } + $this->sys->setKernel($result); } } @@ -57,7 +81,7 @@ class Android extends Linux * * @return void */ - private function _users() + protected function _users() { $this->sys->setUsers(1); } @@ -67,9 +91,10 @@ class Android extends Linux * * @return void */ - private function _filesystems() + protected function _filesystems() { - if (CommonFunctions::executeProgram('df', '2>/dev/null ', $df, PSI_DEBUG)) { + $notwas = true; + if (CommonFunctions::executeProgram('df', '2>/dev/null ', $df, PSI_DEBUG) && preg_match("/\s+[0-9\.]+[KMGT]\s+/", $df)) { $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) { $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); @@ -130,10 +155,17 @@ class Android extends Linux } } $this->sys->setDiskDevices($dev); + $notwas = false; } } } } + if ($notwas) { // try Linux df style + $arrResult = Parser::df("-P 2>/dev/null", false); + foreach ($arrResult as $dev) { + $this->sys->setDiskDevices($dev); + } + } } /** @@ -141,18 +173,17 @@ class Android extends Linux * * @return void */ - private function _distro() + protected function _distro() { $buf = ""; - if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false) - && preg_match('/^ro\.build\.version\.release=([^\n]+)/m', $lines, $ar_buf)) { + if (($lines = $this->_get_buildprop()) && preg_match('/^ro\.build\.version\.release=([^\n]+)/m', $lines, $ar_buf)) { $buf = trim($ar_buf[1]); } - if (is_null($buf) || ($buf == "")) { + if (($buf === null) || ($buf == "")) { $this->sys->setDistribution('Android'); } else { if (preg_match('/^(\d+\.\d+)/', $buf, $ver) - && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true)) + && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true)) && isset($list['Android'][$ver[1]])) { $buf.=' '.$list['Android'][$ver[1]]; } @@ -166,14 +197,14 @@ class Android extends Linux * * @return void */ - private function _machine() + protected function _machine() { - if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false)) { + if ($lines = $this->_get_buildprop()) { $buf = ""; - if (preg_match('/^ro\.product\.manufacturer=([^\n]+)/m', $lines, $ar_buf)) { + if (preg_match('/^ro\.product\.manufacturer=([^\n]+)/m', $lines, $ar_buf) && (trim($ar_buf[1]) !== "unknown")) { $buf .= ' '.trim($ar_buf[1]); } - if (preg_match('/^ro\.product\.model=([^\n]+)/m', $lines, $ar_buf) && (trim($buf) !== trim($ar_buf[1]))) { + if (preg_match('/^ro\.product\.model=([^\n]+)/m', $lines, $ar_buf) && (trim($ar_buf[1]) !== trim($buf))) { $buf .= ' '.trim($ar_buf[1]); } if (preg_match('/^ro\.semc\.product\.name=([^\n]+)/m', $lines, $ar_buf)) { @@ -188,7 +219,7 @@ class Android extends Linux /** * PCI devices * - * @return array + * @return void */ private function _pci() { @@ -205,50 +236,40 @@ class Android extends Linux } } - /** - * USB devices - * - * @return array - */ - private function _usb() - { - if (file_exists('/dev/bus/usb') && CommonFunctions::executeProgram('lsusb', '', $bufr, false)) { - $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); - foreach ($bufe as $buf) { - $device = preg_split("/ /", $buf, 6); - if (isset($device[5]) && trim($device[5]) != "") { - $dev = new HWDevice(); - $dev->setName(trim($device[5])); - $this->sys->setUsbDevices($dev); - } - } - } - } - /** * get the information * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_machine(); - $this->_uptime(); - $this->_users(); - $this->_cpuinfo(); - $this->_pci(); - $this->_usb(); - $this->_i2c(); - $this->_network(); - $this->_memory(); - $this->_filesystems(); - $this->_loadavg(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_machine(); + $this->_cpuinfo(); + $this->_virtualizer(); + $this->_pci(); + $this->_usb(); + $this->_i2c(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php index 50bc2cf..7db0296 100644 --- a/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php @@ -8,7 +8,7 @@ * @package PSI BSDCommon OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.BSDCommon.inc.php 621 2012-07-29 18:49:04Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,68 +21,72 @@ * @package PSI BSDCommon OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ abstract class BSDCommon extends OS { + /** + * Assoc array of all CPUs loads. + */ + private $_cpu_loads = null; + /** * content of the syslog * * @var array */ - private $_dmesg = array(); + private $_dmesg = null; /** * regexp1 for cpu information out of the syslog * * @var string */ - private $_CPURegExp1 = ""; + private $_CPURegExp1 = "//"; /** * regexp2 for cpu information out of the syslog * * @var string */ - private $_CPURegExp2 = ""; + private $_CPURegExp2 = "//"; /** * regexp1 for scsi information out of the syslog * * @var string */ - private $_SCSIRegExp1 = ""; + private $_SCSIRegExp1 = "//"; /** * regexp2 for scsi information out of the syslog * * @var string */ - private $_SCSIRegExp2 = ""; + private $_SCSIRegExp2 = "//"; + + /** + * regexp3 for scsi information out of the syslog + * + * @var string + */ + private $_SCSIRegExp3 = "//"; /** * regexp1 for pci information out of the syslog * * @var string */ - private $_PCIRegExp1 = ""; + private $_PCIRegExp1 = "//"; /** * regexp1 for pci information out of the syslog * * @var string */ - private $_PCIRegExp2 = ""; - - /** - * call parent constructor - */ - public function __construct() - { - parent::__construct(); - } + private $_PCIRegExp2 = "//"; /** * setter for cpuregexp1 @@ -132,6 +136,18 @@ abstract class BSDCommon extends OS $this->_SCSIRegExp2 = $value; } + /** + * setter for scsiregexp3 + * + * @param string $value value to set + * + * @return void + */ + protected function setSCSIRegExp3($value) + { + $this->_SCSIRegExp3 = $value; + } + /** * setter for pciregexp1 * @@ -163,12 +179,12 @@ abstract class BSDCommon extends OS */ protected function readdmesg() { - if (count($this->_dmesg) === 0) { - if (PSI_OS != "Darwin") { - if (CommonFunctions::rfts('/var/run/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/log/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/run/dmesg.boot', $buf)) { // Once again but with debug - $parts = preg_split("/rebooting|Uptime/", $buf, -1, PREG_SPLIT_NO_EMPTY); - $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY); - } + if ($this->_dmesg === null) { + if ((PSI_OS != 'Darwin') && (CommonFunctions::rfts('/var/run/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/log/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/run/dmesg.boot', $buf))) { // Once again but with debug + $parts = preg_split("/rebooting|Uptime/", $buf, -1, PREG_SPLIT_NO_EMPTY); + $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY); + } else { + $this->_dmesg = array(); } } @@ -199,8 +215,8 @@ abstract class BSDCommon extends OS */ protected function hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('hostname', '', $buf, PSI_DEBUG)) { $this->sys->setHostname($buf); @@ -208,24 +224,6 @@ abstract class BSDCommon extends OS } } - /** - * IP of the Canonical Host Name - * - * @return void - */ - protected function ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * Kernel Version * @@ -234,19 +232,98 @@ abstract class BSDCommon extends OS protected function kernel() { $s = $this->grabkey('kern.version'); - $a = preg_split('/:/', $s); - $this->sys->setKernel($a[0].$a[1].':'.$a[2]); + $a = preg_split('/:/', $s, 4); + if (isset($a[3])) { + if (preg_match('/^(\d{2} [A-Z]{3});/', $a[3], $abuf) // eg. 19:58 GMT;... + || preg_match('/^(\d{2} [A-Z]{3} \d{4})/', $a[3], $abuf)) { // eg. 26:31 PDT 2019... + $this->sys->setKernel($a[0].$a[1].':'.$a[2].':'.$abuf[1]); + } else { + $this->sys->setKernel($a[0].$a[1].':'.$a[2]); + } + } elseif (isset($a[2])) { + $this->sys->setKernel($a[0].$a[1].':'.$a[2]); + } else { + $this->sys->setKernel($s); + } } /** - * Number of Users + * Virtualizer info * * @return void */ - protected function users() + private function virtualizer() { - if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) { - $this->sys->setUsers($buf); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $testvirt = $this->sys->getVirtualizer(); + $novm = true; + foreach ($testvirt as $virtkey=>$virtvalue) if ($virtvalue) { + $novm = false; + break; + } + // Detect QEMU cpu + if ($novm && isset($testvirt["cpuid:QEMU"])) { + $this->sys->setVirtualizer('qemu'); // QEMU + $novm = false; + } + + if ($novm && isset($testvirt["hypervisor"])) { + $this->sys->setVirtualizer('unknown'); + } + } + } + + /** + * CPU usage + * + * @return void + */ + protected function cpuusage() + { + if (($this->_cpu_loads === null)) { + $this->_cpu_loads = array(); + if (PSI_OS != 'Darwin') { + if ($fd = $this->grabkey('kern.cp_time')) { + // Find out the CPU load + // user + sys = load + // total = total + if (preg_match($this->_CPURegExp2, $fd, $res) && (sizeof($res) > 4)) { + $load = $res[2] + $res[3] + $res[4]; // cpu.user + cpu.sys + $total = $res[2] + $res[3] + $res[4] + $res[5]; // cpu.total + // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) + sleep(1); + $fd = $this->grabkey('kern.cp_time'); + if (preg_match($this->_CPURegExp2, $fd, $res) && (sizeof($res) > 4)) { + $load2 = $res[2] + $res[3] + $res[4]; + $total2 = $res[2] + $res[3] + $res[4] + $res[5]; + if ($total2 != $total) { + $this->_cpu_loads['cpu'] = (100 * ($load2 - $load)) / ($total2 - $total); + } else { + $this->_cpu_loads['cpu'] = 0; + } + } + } + } + } else { + $ncpu = $this->grabkey('hw.ncpu'); + if (($ncpu !== "") && ($ncpu >= 1) && CommonFunctions::executeProgram('ps', "-A -o %cpu", $pstable, false) && !empty($pstable)) { + $pslines = preg_split("/\n/", $pstable, -1, PREG_SPLIT_NO_EMPTY); + if (!empty($pslines) && (count($pslines)>1) && (trim($pslines[0])==="%CPU")) { + array_shift($pslines); + $sum = 0; + foreach ($pslines as $psline) { + $sum+=str_replace(',', '.', trim($psline)); + } + $this->_cpu_loads['cpu'] = min($sum/$ncpu, 100); + } + } + } + } + + if (isset($this->_cpu_loads['cpu'])) { + return $this->_cpu_loads['cpu']; + } else { + return null; } } @@ -261,23 +338,11 @@ abstract class BSDCommon extends OS $s = $this->grabkey('vm.loadavg'); $s = preg_replace('/{ /', '', $s); $s = preg_replace('/ }/', '', $s); + $s = str_replace(',', '.', $s); $this->sys->setLoad($s); - if (PSI_LOAD_BAR && (PSI_OS != "Darwin")) { - if ($fd = $this->grabkey('kern.cp_time')) { - // Find out the CPU load - // user + sys = load - // total = total - preg_match($this->_CPURegExp2, $fd, $res); - $load = $res[2] + $res[3] + $res[4]; // cpu.user + cpu.sys - $total = $res[2] + $res[3] + $res[4] + $res[5]; // cpu.total - // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) - sleep(1); - $fd = $this->grabkey('kern.cp_time'); - preg_match($this->_CPURegExp2, $fd, $res); - $load2 = $res[2] + $res[3] + $res[4]; - $total2 = $res[2] + $res[3] + $res[4] + $res[5]; - $this->sys->setLoadPercent((100 * ($load2 - $load)) / ($total2 - $total)); - } + + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($this->cpuusage()); } } @@ -289,37 +354,153 @@ abstract class BSDCommon extends OS protected function cpuinfo() { $dev = new CpuDevice(); - $dev->setModel($this->grabkey('hw.model')); + $cpumodel = $this->grabkey('hw.model'); + $dev->setModel($cpumodel); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^QEMU Virtual CPU version /', $cpumodel)) { + $this->sys->setVirtualizer("cpuid:QEMU", false); + } + $notwas = true; foreach ($this->readdmesg() as $line) { if ($notwas) { - if (preg_match("/".$this->_CPURegExp1."/", $line, $ar_buf)) { - $dev->setCpuSpeed(round($ar_buf[2])); - $notwas = false; + $regexps = preg_split("/\n/", $this->_CPURegExp1, -1, PREG_SPLIT_NO_EMPTY); // multiple regexp separated by \n + foreach ($regexps as $regexp) { + if (preg_match($regexp, $line, $ar_buf) && (sizeof($ar_buf) > 2)) { + if ($dev->getCpuSpeed() == 0) { + $dev->setCpuSpeed(round($ar_buf[2])); + } + $notwas = false; + break; + } } } else { - if (preg_match("/ Origin| Features/", $line, $ar_buf)) { - if (preg_match("/ Features2[ ]*=.*<(.*)>/", $line, $ar_buf)) { + if (preg_match("/^\s+Origin| Features/", $line, $ar_buf)) { + if (preg_match("/^\s+Origin[ ]*=[ ]*\"(.+)\"/", $line, $ar_buf)) { + $dev->setVendorId($ar_buf[1]); + } elseif (preg_match("/ Features2[ ]*=.*<(.+)>/", $line, $ar_buf)) { $feats = preg_split("/,/", strtolower(trim($ar_buf[1])), -1, PREG_SPLIT_NO_EMPTY); foreach ($feats as $feat) { if (($feat=="vmx") || ($feat=="svm")) { $dev->setVirt($feat); - break 2; + } elseif ($feat=="hv") { + if ($dev->getVirt() === null) { + $dev->setVirt('hypervisor'); + } + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $this->sys->setVirtualizer("hypervisor", false); + } } } - break; } } else break; } } + $ncpu = $this->grabkey('hw.ncpu'); - if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + if (($ncpu === "") || !($ncpu >= 1)) { $ncpu = 1; + } + if (($ncpu == 1) && PSI_LOAD_BAR) { + $dev->setLoad($this->cpuusage()); + } for ($ncpu ; $ncpu > 0 ; $ncpu--) { $this->sys->setCpus($dev); } } + /** + * Machine information + * + * @return void + */ + private function machine() + { + if ((PSI_OS == 'NetBSD') || (PSI_OS == 'OpenBSD')) { + $buffer = array(); + if (PSI_OS == 'NetBSD') { // NetBSD + $buffer['Manufacturer'] = $this->grabkey('machdep.dmi.system-vendor'); + $buffer['Model'] = $this->grabkey('machdep.dmi.system-product'); + $buffer['Product'] = $this->grabkey('machdep.dmi.board-product'); + $buffer['SMBIOSBIOSVersion'] = $this->grabkey('machdep.dmi.bios-version'); + $buffer['ReleaseDate'] = $this->grabkey('machdep.dmi.bios-date'); + } else { // OpenBSD + $buffer['Manufacturer'] = $this->grabkey('hw.vendor'); + $buffer['Model'] = $this->grabkey('hw.product'); + $buffer['Product'] = ""; + $buffer['SMBIOSBIOSVersion'] = ""; + $buffer['ReleaseDate'] = ""; + } + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $vendor_array = array(); + $vendor_array[] = $buffer['Model']; + $vendor_array[] = trim($buffer['Manufacturer']." ".$buffer['Model']); + if (PSI_OS == 'NetBSD') { // NetBSD + $vendor_array[] = $this->grabkey('machdep.dmi.board-vendor'); + $vendor_array[] = $this->grabkey('machdep.dmi.bios-vendor'); + } + $virt = CommonFunctions::decodevirtualizer($vendor_array); + if ($virt !== null) { + $this->sys->setVirtualizer($virt); + } + } + + $buf = ""; + if (($buffer['Manufacturer'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^System manufacturer$|^Not Specified$/i", $buf2=trim($buffer['Manufacturer'])) && ($buf2 !== "")) { + $buf .= ' '.$buf2; + } + + if (($buffer['Model'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^System Product Name$|^Not Specified$/i", $buf2=trim($buffer['Model'])) && ($buf2 !== "")) { + $model = $buf2; + $buf .= ' '.$buf2; + } + if (($buffer['Product'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^BaseBoard Product Name$|^Not Specified$|^Default string$/i", $buf2=trim($buffer['Product'])) && ($buf2 !== "")) { + if ($buf2 !== $model) { + $buf .= '/'.$buf2; + } elseif (isset($buffer['SystemFamily']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Family$|^Not Specified$/i", $buf2=trim($buffer['SystemFamily'])) && ($buf2 !== "")) { + $buf .= '/'.$buf2; + } + } + + $bver = ""; + $brel = ""; + if (($buf2=trim($buffer['SMBIOSBIOSVersion'])) !== "") { + $bver .= ' '.$buf2; + } + if ($buffer['ReleaseDate'] !== "") { + if (preg_match("/^(\d{4})(\d{2})(\d{2})$/", $buffer['ReleaseDate'], $dateout)) { + $brel .= ' '.$dateout[2].'/'.$dateout[3].'/'.$dateout[1]; + } elseif (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $buffer['ReleaseDate'])) { + $brel .= ' '.$buffer['ReleaseDate']; + } + } + if ((trim($bver) !== "") || (trim($brel) !== "")) { + $buf .= ', BIOS'.$bver.$brel; + } + + if (trim($buf) !== "") { + $this->sys->setMachine(trim($buf)); + } + } elseif ((PSI_OS == 'FreeBSD') && defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $vendorid = $this->grabkey('hw.hv_vendor'); + if (trim($vendorid) === "") { + foreach ($this->readdmesg() as $line) if (preg_match("/^Hypervisor: Origin = \"(.+)\"/", $line, $ar_buf)) { + if (trim($ar_buf[1]) !== "") { + $vendorid = $ar_buf[1]; + } + break; + } + } + if (trim($vendorid) !== "") { + $virt = CommonFunctions::decodevirtualizer($vendorid); + if ($virt !== null) { + $this->sys->setVirtualizer($virt); + } else { + $this->sys->setVirtualizer('unknown'); + } + } + } + } + /** * SCSI devices * get the scsi device information out of dmesg @@ -329,16 +510,22 @@ abstract class BSDCommon extends OS protected function scsi() { foreach ($this->readdmesg() as $line) { - if (preg_match("/".$this->_SCSIRegExp1."/", $line, $ar_buf)) { + if (preg_match($this->_SCSIRegExp1, $line, $ar_buf) && (sizeof($ar_buf) > 2)) { $dev = new HWDevice(); - $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $dev->setName($ar_buf[1].": ".trim($ar_buf[2])); $this->sys->setScsiDevices($dev); - } elseif (preg_match("/".$this->_SCSIRegExp2."/", $line, $ar_buf)) { + } elseif (preg_match($this->_SCSIRegExp2, $line, $ar_buf) && (sizeof($ar_buf) > 1)) { /* duplication security */ $notwas = true; foreach ($this->sys->getScsiDevices() as $finddev) { if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { - $finddev->setCapacity($ar_buf[2] * 2048 * 1.049); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($ar_buf[3]) && ($ar_buf[3]==="G")) { + $finddev->setCapacity($ar_buf[2] * 1024 * 1024 * 1024); + } elseif (isset($ar_buf[2])) { + $finddev->setCapacity($ar_buf[2] * 1024 * 1024); + } + } $notwas = false; break; } @@ -346,15 +533,43 @@ abstract class BSDCommon extends OS if ($notwas) { $dev = new HWDevice(); $dev->setName($ar_buf[1]); - $dev->setCapacity($ar_buf[2] * 2048 * 1.049); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($ar_buf[3]) && ($ar_buf[3]==="G")) { + $dev->setCapacity($ar_buf[2] * 1024 * 1024 * 1024); + } elseif (isset($ar_buf[2])) { + $dev->setCapacity($ar_buf[2] * 1024 * 1024); + } + } + $this->sys->setScsiDevices($dev); + } + } elseif (preg_match($this->_SCSIRegExp3, $line, $ar_buf) && (sizeof($ar_buf) > 1)) { + /* duplication security */ + $notwas = true; + foreach ($this->sys->getScsiDevices() as $finddev) { + if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + if (isset($ar_buf[2])) $finddev->setSerial(trim($ar_buf[2])); + } + $notwas = false; + break; + } + } + if ($notwas) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + if (isset($ar_buf[2])) $dev->setSerial(trim($ar_buf[2])); + } $this->sys->setScsiDevices($dev); } } } /* cleaning */ foreach ($this->sys->getScsiDevices() as $finddev) { - if (strpos($finddev->getName(), ': ') !== false) - $finddev->setName(substr(strstr($finddev->getName(), ': '), 2)); + if (strpos($finddev->getName(), ': ') !== false) + $finddev->setName(substr(strstr($finddev->getName(), ': '), 2)); } } @@ -412,13 +627,13 @@ abstract class BSDCommon extends OS */ protected function pci() { - if (!is_array($results = Parser::lspci(false)) || !is_array($results = $this->pciconf())) { + if ((!$results = Parser::lspci(false)) && (!$results = $this->pciconf())) { foreach ($this->readdmesg() as $line) { - if (preg_match("/".$this->_PCIRegExp1."/", $line, $ar_buf)) { + if (preg_match($this->_PCIRegExp1, $line, $ar_buf) && (sizeof($ar_buf) > 2)) { $dev = new HWDevice(); $dev->setName($ar_buf[1].": ".$ar_buf[2]); $results[] = $dev; - } elseif (preg_match("/".$this->_PCIRegExp2."/", $line, $ar_buf)) { + } elseif (preg_match($this->_PCIRegExp2, $line, $ar_buf) && (sizeof($ar_buf) > 2)) { $dev = new HWDevice(); $dev->setName($ar_buf[1].": ".$ar_buf[2]); $results[] = $dev; @@ -441,23 +656,27 @@ abstract class BSDCommon extends OS foreach ($this->readdmesg() as $line) { if (preg_match('/^(ad[0-9]+): (.*)MB <(.*)> (.*) (.*)/', $line, $ar_buf)) { $dev = new HWDevice(); - $dev->setName($ar_buf[1].": ".$ar_buf[3]); - $dev->setCapacity($ar_buf[2] * 1024); + $dev->setName($ar_buf[1].": ".trim($ar_buf[3])); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setCapacity($ar_buf[2] * 1024 * 1024); + } $this->sys->setIdeDevices($dev); } elseif (preg_match('/^(acd[0-9]+): (.*) <(.*)> (.*)/', $line, $ar_buf)) { $dev = new HWDevice(); - $dev->setName($ar_buf[1].": ".$ar_buf[3]); + $dev->setName($ar_buf[1].": ".trim($ar_buf[3])); $this->sys->setIdeDevices($dev); } elseif (preg_match('/^(ada[0-9]+): <(.*)> (.*)/', $line, $ar_buf)) { $dev = new HWDevice(); - $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $dev->setName($ar_buf[1].": ".trim($ar_buf[2])); $this->sys->setIdeDevices($dev); } elseif (preg_match('/^(ada[0-9]+): (.*)MB \((.*)\)/', $line, $ar_buf)) { /* duplication security */ $notwas = true; foreach ($this->sys->getIdeDevices() as $finddev) { if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { - $finddev->setCapacity($ar_buf[2] * 1024); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $finddev->setCapacity($ar_buf[2] * 1024 * 1024); + } $notwas = false; break; } @@ -465,7 +684,31 @@ abstract class BSDCommon extends OS if ($notwas) { $dev = new HWDevice(); $dev->setName($ar_buf[1]); - $dev->setCapacity($ar_buf[2] * 1024); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setCapacity($ar_buf[2] * 1024 * 1024); + } + $this->sys->setIdeDevices($dev); + } + } elseif (preg_match('/^(ada[0-9]+): Serial Number (.*)/', $line, $ar_buf)) { + /* duplication security */ + $notwas = true; + foreach ($this->sys->getIdeDevices() as $finddev) { + if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $finddev->setSerial(trim($ar_buf[2])); + } + $notwas = false; + break; + } + } + if ($notwas) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $finddev->setSerial(trim($ar_buf[2])); + } $this->sys->setIdeDevices($dev); } } @@ -530,7 +773,19 @@ abstract class BSDCommon extends OS */ protected function usb() { - foreach ($this->readdmesg() as $line) { + $notwas = true; + if ((PSI_OS == 'FreeBSD') && CommonFunctions::executeProgram('usbconfig', '', $bufr, false)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + if (preg_match('/^(ugen[0-9]+\.[0-9]+): <([^,]*)(.*)> at (usbus[0-9]+)/', $line, $ar_buf)) { + $notwas = false; + $dev = new HWDevice(); + $dev->setName($ar_buf[2]); + $this->sys->setUSBDevices($dev); + } + } + } + if ($notwas) foreach ($this->readdmesg() as $line) { // if (preg_match('/^(ugen[0-9\.]+): <(.*)> (.*) (.*)/', $line, $ar_buf)) { // $dev->setName($ar_buf[1].": ".$ar_buf[2]); if (preg_match('/^(u[a-z]+[0-9]+): <([^,]*)(.*)> on (usbus[0-9]+)/', $line, $ar_buf)) { @@ -566,27 +821,60 @@ abstract class BSDCommon extends OS } } + /** + * UpTime + * time the system is running + * + * @return void + */ + private function uptime() + { + if ($kb = $this->grabkey('kern.boottime')) { + if (preg_match("/sec = ([0-9]+)/", $kb, $buf)) { // format like: { sec = 1096732600, usec = 885425 } Sat Oct 2 10:56:40 2004 + $this->sys->setUptime(time() - $buf[1]); + } else { + date_default_timezone_set('UTC'); + $kbt = strtotime($kb); + if (($kbt !== false) && ($kbt != -1)) { + $this->sys->setUptime(time() - $kbt); // format like: Sat Oct 2 10:56:40 2004 + } else { + $this->sys->setUptime(time() - $kb); // format like: 1096732600 + } + } + } + } + /** * get the information * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->distro(); - $this->memory(); - $this->ide(); - $this->pci(); - $this->cpuinfo(); - $this->filesystems(); - $this->kernel(); - $this->users(); - $this->loadavg(); - $this->hostname(); - $this->ip(); - $this->scsi(); - $this->usb(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->distro(); + $this->hostname(); + $this->kernel(); + $this->_users(); + $this->loadavg(); + $this->uptime(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->machine(); + $this->cpuinfo(); + $this->virtualizer(); + $this->pci(); + $this->ide(); + $this->scsi(); + $this->usb(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->filesystems(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php index 1ee9dd8..c84d8a5 100644 --- a/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php @@ -8,7 +8,7 @@ * @package PSI Darwin OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Darwin.inc.php 638 2012-08-24 09:40:48Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,7 +21,7 @@ * @package PSI Darwin OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,13 +30,13 @@ class Darwin extends BSDCommon /** * define the regexp for log parser */ - /* public function __construct() + /* public function __construct($blockname = false) { - parent::__construct(); + parent::__construct($blockname); $this->error->addWarning("The Darwin version of phpSysInfo is a work in progress, some things currently don't work!"); - $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)"); + $this->setCPURegExp1("/CPU: (.*) \((.*)-MHz (.*)\)/"); $this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/"); - $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device"); + $this->setSCSIRegExp1("/^(.*): <(.*)> .*SCSI.*device/"); } */ /** @@ -89,25 +89,6 @@ class Darwin extends BSDCommon } } - /** - * UpTime - * time the system is running - * - * @return void - */ - private function _uptime() - { - if (CommonFunctions::executeProgram('sysctl', '-n kern.boottime', $a, PSI_DEBUG)) { - $tmp = explode(" ", $a); - if ($tmp[0]=="{") { /* kern.boottime= { sec = 1096732600, usec = 885425 } Sat Oct 2 10:56:40 2004 */ - $data = trim($tmp[3], ","); - $this->sys->setUptime(time() - $data); - } else { /* kern.boottime= 1096732600 */ - $this->sys->setUptime(time() - $a); - } - } - } - /** * get CPU information * @@ -116,12 +97,12 @@ class Darwin extends BSDCommon protected function cpuinfo() { $dev = new CpuDevice(); - if (CommonFunctions::executeProgram('hostinfo', '| grep "Processor type"', $buf, PSI_DEBUG)) { - $dev->setModel(preg_replace('/Processor type: /', '', $buf)); + if (CommonFunctions::executeProgram('hostinfo', '', $buf, PSI_DEBUG) && ($buf !== '') && preg_match('/^Processor type:[ ]+(.+)$/m', $buf, $proc) && (($proc[1] = trim($proc[1])) !== '')) { + $dev->setModel($proc[1]); $buf=$this->grabkey('hw.model'); - if (!is_null($buf) && (trim($buf) != "")) { + if (($buf !== null) && (trim($buf) != "")) { $this->sys->setMachine(trim($buf)); - if (CommonFunctions::rfts(APP_ROOT.'/data/ModelTranslation.txt', $buffer)) { + if (CommonFunctions::rftsdata('ModelTranslation.txt', $buffer)) { $buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); foreach ($buffer as $line) { $ar_buf = preg_split("/:/", $line, 3); @@ -134,12 +115,12 @@ class Darwin extends BSDCommon } } $buf=$this->grabkey('machdep.cpu.brand_string'); - if (!is_null($buf) && (trim($buf) != "") && + if (($buf !== null) && (trim($buf) != "") && ((trim($buf) != "i486 (Intel 80486)") || ($dev->getModel() == ""))) { $dev->setModel(trim($buf)); } $buf=$this->grabkey('machdep.cpu.features'); - if (!is_null($buf) && (trim($buf) != "")) { + if (($buf !== null) && (trim($buf) != "")) { if (preg_match("/ VMX/", $buf)) { $dev->setVirt("vmx"); } elseif (preg_match("/ SVM/", $buf)) { @@ -151,17 +132,21 @@ class Darwin extends BSDCommon $dev->setBusSpeed(round($this->grabkey('hw.busfrequency') / 1000000)); $bufn=$this->grabkey('hw.cpufrequency_min'); $bufx=$this->grabkey('hw.cpufrequency_max'); - if (!is_null($bufn) && (trim($bufn) != "") && !is_null($bufx) && (trim($bufx) != "") && ($bufn != $bufx)) { + if (($bufn !== null) && (trim($bufn) != "") && ($bufx !== null) && (trim($bufx) != "") && ($bufn != $bufx)) { $dev->setCpuSpeedMin(round($bufn / 1000000)); $dev->setCpuSpeedMax(round($bufx / 1000000)); } $buf=$this->grabkey('hw.l2cachesize'); - if (!is_null($buf) && (trim($buf) != "")) { + if ($buf !== "") { $dev->setCache(round($buf)); } $ncpu = $this->grabkey('hw.ncpu'); - if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + if (($ncpu === "") || !($ncpu >= 1)) { $ncpu = 1; + } + if (($ncpu == 1) && PSI_LOAD_BAR) { + $dev->setLoad($this->cpuusage()); + } for ($ncpu ; $ncpu > 0 ; $ncpu--) { $this->sys->setCpus($dev); } @@ -238,6 +223,18 @@ class Darwin extends BSDCommon if (!preg_match('/"USB Product Name" = "([^"]*)"/', $line, $ar_buf)) $ar_buf = preg_split("/[\s@]+/", $line, 19); $dev->setName(trim($ar_buf[1])); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (preg_match('/"USB Vendor Name" = "([^"]*)"/', $line, $ar_buf)) { + $dev->setManufacturer(trim($ar_buf[1])); + } + if (preg_match('/"USB Product Name" = "([^"]*)"/', $line, $ar_buf)) { + $dev->setProduct(trim($ar_buf[1])); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL + && preg_match('/"USB Serial Number" = "([^"]*)"/', $line, $ar_buf)) { + $dev->setSerial(trim($ar_buf[1])); + } + } $this->sys->setUsbDevices($dev); } } @@ -267,60 +264,63 @@ class Darwin extends BSDCommon */ protected function memory() { - $s = $this->grabkey('hw.memsize'); - if (CommonFunctions::executeProgram('vm_stat', '', $pstat, PSI_DEBUG)) { - // calculate free memory from page sizes (each page = 4096) - if (preg_match('/^Pages free:\s+(\S+)/m', $pstat, $free_buf)) { - if (preg_match('/^Anonymous pages:\s+(\S+)/m', $pstat, $anon_buf) - && preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf) - && preg_match('/^File-backed pages:\s+(\S+)/m', $pstat, $fileb_buf)) { - // OS X 10.9 or never - $this->sys->setMemFree($free_buf[1] * 4 * 1024); - $this->sys->setMemApplication(($anon_buf[1]+$wire_buf[1]) * 4 * 1024); - $this->sys->setMemCache($fileb_buf[1] * 4 * 1024); - if (preg_match('/^Pages occupied by compressor:\s+(\S+)/m', $pstat, $compr_buf)) { - $this->sys->setMemBuffer($compr_buf[1] * 4 * 1024); - } - } else { - if (preg_match('/^Pages speculative:\s+(\S+)/m', $pstat, $spec_buf)) { - $this->sys->setMemFree(($free_buf[1]+$spec_buf[1]) * 4 * 1024); + if (($s = $this->grabkey('hw.memsize')) > 0) { + $this->sys->setMemTotal($s); + if (CommonFunctions::executeProgram('vm_stat', '', $pstat, PSI_DEBUG)) { + // calculate free memory from page sizes (each page = 4096) + if (preg_match('/^Pages free:\s+(\S+)/m', $pstat, $free_buf)) { + if (preg_match('/^Anonymous pages:\s+(\S+)/m', $pstat, $anon_buf) + && preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf) + && preg_match('/^File-backed pages:\s+(\S+)/m', $pstat, $fileb_buf)) { + // OS X 10.9 or never + $this->sys->setMemFree($free_buf[1] * 4 * 1024); + $this->sys->setMemApplication(($anon_buf[1]+$wire_buf[1]) * 4 * 1024); + $this->sys->setMemCache($fileb_buf[1] * 4 * 1024); + if (preg_match('/^Pages occupied by compressor:\s+(\S+)/m', $pstat, $compr_buf)) { + $this->sys->setMemBuffer($compr_buf[1] * 4 * 1024); + } } else { - $this->sys->setMemFree($free_buf[1] * 4 * 1024); - } - $appMemory = 0; - if (preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)) { - $appMemory += $wire_buf[1] * 4 * 1024; - } - if (preg_match('/^Pages active:\s+(\S+)/m', $pstat, $active_buf)) { - $appMemory += $active_buf[1] * 4 * 1024; - } - $this->sys->setMemApplication($appMemory); + if (preg_match('/^Pages speculative:\s+(\S+)/m', $pstat, $spec_buf)) { + $this->sys->setMemFree(($free_buf[1]+$spec_buf[1]) * 4 * 1024); + } else { + $this->sys->setMemFree($free_buf[1] * 4 * 1024); + } + $appMemory = 0; + if (preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)) { + $appMemory += $wire_buf[1] * 4 * 1024; + } + if (preg_match('/^Pages active:\s+(\S+)/m', $pstat, $active_buf)) { + $appMemory += $active_buf[1] * 4 * 1024; + } + $this->sys->setMemApplication($appMemory); - if (preg_match('/^Pages inactive:\s+(\S+)/m', $pstat, $inactive_buf)) { - $this->sys->setMemCache($inactive_buf[1] * 4 * 1024); + if (preg_match('/^Pages inactive:\s+(\S+)/m', $pstat, $inactive_buf)) { + $this->sys->setMemCache($inactive_buf[1] * 4 * 1024); + } } + } else { + $lines = preg_split("/\n/", $pstat, -1, PREG_SPLIT_NO_EMPTY); + $ar_buf = preg_split("/\s+/", $lines[1], 19); + $this->sys->setMemFree($ar_buf[2] * 4 * 1024); } - } else { - $lines = preg_split("/\n/", $pstat, -1, PREG_SPLIT_NO_EMPTY); - $ar_buf = preg_split("/\s+/", $lines[1], 19); - $this->sys->setMemFree($ar_buf[2] * 4 * 1024); + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); } - $this->sys->setMemTotal($s); - $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); - - if (CommonFunctions::executeProgram('sysctl', 'vm.swapusage | colrm 1 22', $swapBuff, PSI_DEBUG)) { - $swap1 = preg_split('/M/', $swapBuff); - $swap2 = preg_split('/=/', $swap1[1]); - $swap3 = preg_split('/=/', $swap1[2]); - $dev = new DiskDevice(); - $dev->setName('SWAP'); - $dev->setMountPoint('SWAP'); - $dev->setFsType('swap'); - $dev->setTotal($swap1[0] * 1024 * 1024); - $dev->setUsed($swap2[1] * 1024 * 1024); - $dev->setFree($swap3[1] * 1024 * 1024); - $this->sys->setSwapDevices($dev); + if (($swap = $this->grabkey("vm.swapusage")) > 0) { + $swap0 = preg_split('/M/', $swap); + $swap1 = preg_split('/=/', $swap0[0]); + $swap2 = preg_split('/=/', $swap0[1]); + $swap3 = preg_split('/=/', $swap0[2]); + if (($swap=str_replace(',', '.', trim($swap1[1]))) > 0) { + $dev = new DiskDevice(); + $dev->setName('SWAP'); + $dev->setMountPoint('SWAP'); + $dev->setFsType('swap'); + $dev->setTotal($swap * 1024 * 1024); + $dev->setUsed(str_replace(',', '.', trim($swap2[1])) * 1024 * 1024); + $dev->setFree(str_replace(',', '.', trim($swap3[1])) * 1024 * 1024); + $this->sys->setSwapDevices($dev); + } } } } @@ -354,7 +354,7 @@ class Darwin extends BSDCommon $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); foreach ($lines as $line) { $ar_buf = preg_split("/\s+/", $line, 10); - if (! empty($ar_buf[0])) { + if (!empty($ar_buf[0])) { $dev = new NetDevice(); $dev->setName($ar_buf[0]); $dev->setTxBytes($ar_buf[8]); @@ -366,14 +366,25 @@ class Darwin extends BSDCommon if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe2 as $buf2) { - if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) { $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); - elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) - && !preg_match('/^fe80::/i', $ar_buf2[1])) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) { + if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") { + $unit = "G"; + } else { + $unit = "M"; + } + if (preg_match('/[<\s]([^\s<]+)-duplex/i', $buf2, $ar_buf3)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1])); + else + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s'); + } } } $this->sys->setNetDevices($dev); @@ -390,28 +401,37 @@ class Darwin extends BSDCommon protected function distro() { $this->sys->setDistributionIcon('Darwin.png'); - if (!CommonFunctions::executeProgram('system_profiler', 'SPSoftwareDataType', $buffer, PSI_DEBUG)) { + if ((!CommonFunctions::executeProgram('system_profiler', 'SPSoftwareDataType', $buffer, PSI_DEBUG) || !preg_match('/\n\s*System Version:/', $buffer)) + && (!CommonFunctions::executeProgram('sw_vers', '', $buffer, PSI_DEBUG) || !preg_match('/^ProductName:/', $buffer))) { parent::distro(); } else { - $arrBuff = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); - foreach ($arrBuff as $line) { - $arrLine = preg_split("/:/", $line, -1, PREG_SPLIT_NO_EMPTY); - if (trim($arrLine[0]) === "System Version") { - $distro = trim($arrLine[1]); - - if (preg_match('/(^Mac OS)|(^OS X)/', $distro)) { - $this->sys->setDistributionIcon('Apple.png'); - if (preg_match('/((^Mac OS X Server)|(^Mac OS X)|(^OS X Server)|(^OS X)) (\d+\.\d+)/', $distro, $ver) - && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true)) - && isset($list['OS X'][$ver[6]])) { - $distro.=' '.$list['OS X'][$ver[6]]; + $distro_tmp = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); + foreach ($distro_tmp as $info) { + $info_tmp = preg_split('/:/', $info, 2); + if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "") && + isset($distro_tmp[1]) && ($distro_tmp[1] !== null) && (trim($distro_tmp[1]) != "")) { + $distro_arr[trim($info_tmp[0])] = trim($info_tmp[1]); + } + } + if (isset($distro_arr['ProductName']) && isset($distro_arr['ProductVersion']) && isset($distro_arr['BuildVersion'])) { + $distro_arr['System Version'] = $distro_arr['ProductName'].' '.$distro_arr['ProductVersion'].' ('.$distro_arr['BuildVersion'].')'; + } + if (isset($distro_arr['System Version'])) { + $distro = $distro_arr['System Version']; + if (preg_match('/^Mac OS |^OS X |^macOS |^iPhone OS |^Mac OS$|^OS X$|^macOS$|^iPhone OS$/', $distro)) { + $this->sys->setDistributionIcon('Apple.png'); + if (preg_match('/(^Mac OS X Server|^Mac OS X|^OS X Server|^OS X|^macOS Server|^macOS) ((\d+)\.\d+)/', $distro, $ver) + && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) { + if (isset($list['macOS'][$ver[2]])) { + $distro.=' '.$list['macOS'][$ver[2]]; + } elseif (isset($list['macOS'][$ver[3]])) { + $distro.=' '.$list['macOS'][$ver[3]]; } } - - $this->sys->setDistribution($distro); - - return; } + $this->sys->setDistribution($distro); + } else { + parent::distro(); } } } @@ -451,14 +471,19 @@ class Darwin extends BSDCommon * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { parent::build(); - $this->_uptime(); - $this->_network(); - $this->_processes(); - $this->_tb(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_tb(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php index 9e9f946..9c0ac7a 100644 --- a/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php @@ -8,7 +8,7 @@ * @package PSI DragonFly OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.DragonFly.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI DragonFly OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -29,33 +29,20 @@ class DragonFly extends BSDCommon /** * define the regexp for log parser */ - public function __construct() + public function __construct($blockname = false) { - parent::__construct(); - $this->setCPURegExp1("^cpu(.*)\, (.*) MHz"); - $this->setCPURegExp2("^(.*) at scsibus.*: <(.*)> .*"); - $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); - $this->setPCIRegExp1("/(.*): <(.*)>(.*) (pci|legacypci)[0-9]$/"); + parent::__construct($blockname); + $this->setCPURegExp1("/^cpu(.*)\, (.*) MHz/\n/^CPU: (.*) \((.*)-MHz (.*)\)/"); // multiple regexp separated by \n + $this->setCPURegExp2("/^(.*) at scsibus.*: <(.*)> .*/"); + $this->setSCSIRegExp2("/^(da[0-9]+): (.*)MB /"); + $this->setPCIRegExp1("/(.*): <(.*)>(.*) (pci|legacypci)[0-9]+$/"); $this->setPCIRegExp2("/(.*): <(.*)>.* at [0-9\.]+$/"); } - /** - * UpTime - * time the system is running - * - * @return void - */ - private function _uptime() - { - $a = $this->grab_key('kern.boottime'); - preg_match("/sec = ([0-9]+)/", $a, $buf); - $this->sys->setUptime(time() - $buf[1]); - } - /** * get network information * - * @return array + * @return void */ private function _network() { @@ -66,7 +53,7 @@ class DragonFly extends BSDCommon for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); - if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[5]) || ($ar_buf_n[5] === "0"))) { $dev = new NetDevice(); $dev->setName($ar_buf_b[0]); $dev->setTxBytes($ar_buf_b[8]); @@ -81,16 +68,16 @@ class DragonFly extends BSDCommon /** * get the ide information * - * @return array + * @return void */ protected function ide() { foreach ($this->readdmesg() as $line) { - if (preg_match('/^(.*): (.*) <(.*)> at (ata[0-9]\-(.*)) (.*)/', $line, $ar_buf)) { + if (preg_match('/^(.*): (.*) <(.*)> at (ata[0-9]+\-(.*)) (.*)/', $line, $ar_buf)) { $dev = new HWDevice(); $dev->setName($ar_buf[1]); - if (!preg_match("/^acd[0-9](.*)/", $ar_buf[1])) { - $dev->setCapacity($ar_buf[2] * 1024); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && !preg_match("/^acd[0-9]+(.*)/", $ar_buf[1])) { + $dev->setCapacity($ar_buf[2] * 1024 * 1024); } $this->sys->setIdeDevices($dev); } @@ -140,14 +127,17 @@ class DragonFly extends BSDCommon * * @see BSDCommon::build() * - * @return Void + * @return void */ public function build() { parent::build(); - $this->_distroicon(); - $this->_network(); - $this->_uptime(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distroicon(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php index d602a60..01ba0c3 100644 --- a/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php @@ -8,7 +8,7 @@ * @package PSI FreeBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.FreeBSD.inc.php 696 2012-09-09 11:24:04Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI FreeBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -29,30 +29,18 @@ class FreeBSD extends BSDCommon /** * define the regexp for log parser */ - public function __construct() + public function __construct($blockname = false) { - parent::__construct(); - $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)"); + parent::__construct($blockname); + $this->setCPURegExp1("/CPU: (.*) \((.*)-MHz (.*)\)/"); $this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/"); - $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device"); - $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); - $this->setPCIRegExp1("/(.*): <(.*)>(.*) pci[0-9]$/"); + $this->setSCSIRegExp1("/^(.*): <(.*)> .*SCSI.*device/"); + $this->setSCSIRegExp2("/^(da[0-9]+): (.*)MB /"); + $this->setSCSIRegExp3("/^(da[0-9]+|cd[0-9]+): Serial Number (.*)/"); + $this->setPCIRegExp1("/(.*): <(.*)>(.*) pci[0-9]+$/"); $this->setPCIRegExp2("/(.*): <(.*)>.* at [.0-9]+ irq/"); } - /** - * UpTime - * time the system is running - * - * @return void - */ - private function _uptime() - { - $s = preg_split('/ /', $this->grabkey('kern.boottime')); - $a = preg_replace('/,/', '', $s[3]); - $this->sys->setUptime(time() - $a); - } - /** * get network information * @@ -65,11 +53,11 @@ class FreeBSD extends BSDCommon $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); foreach ($lines as $line) { $ar_buf = preg_split("/\s+/", $line); - if (! empty($ar_buf[0])) { + if (!empty($ar_buf[0])) { if (preg_match('/^setName($ar_buf[0]); - if (strlen($ar_buf[3]) < 17) { /* no Address */ + if ((strlen($ar_buf[3]) < 17) && ($ar_buf[0] != $ar_buf[3])) { /* no MAC or dev name*/ if (isset($ar_buf[11]) && (trim($ar_buf[11]) != '')) { /* Idrop column exist*/ $dev->setTxBytes($ar_buf[9]); $dev->setRxBytes($ar_buf[6]); @@ -97,14 +85,25 @@ class FreeBSD extends BSDCommon if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe2 as $buf2) { - if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) { $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); - elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) - && !preg_match('/^fe80::/i', $ar_buf2[1])) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) { + if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") { + $unit = "G"; + } else { + $unit = "M"; + } + if (preg_match('/[<\s]([^\s<]+)-duplex/i', $buf2, $ar_buf3)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1])); + else + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s'); + } } } $this->sys->setNetDevices($dev); @@ -121,9 +120,19 @@ class FreeBSD extends BSDCommon */ private function _distroicon() { - if (extension_loaded('pfSense') && CommonFunctions::rfts('/etc/version', $version, 1, 4096, false) && (trim($version) != '')) { // pfSense detection - $this->sys->setDistribution('pfSense '. trim($version)); - $this->sys->setDistributionIcon('pfSense.png'); + if (CommonFunctions::rfts('/etc/version', $version, 1, 4096, false) && (($version=trim($version)) != '')) { + if (extension_loaded('pfSense')) { // pfSense detection + $this->sys->setDistribution('pfSense '. $version); + $this->sys->setDistributionIcon('pfSense.png'); + } elseif (preg_match('/^FreeNAS/i', $version)) { // FreeNAS detection + $this->sys->setDistribution($version); + $this->sys->setDistributionIcon('FreeNAS.png'); + } elseif (preg_match('/^TrueNAS/i', $version)) { // TrueNAS detection + $this->sys->setDistribution($version); + $this->sys->setDistributionIcon('TrueNAS.png'); + } else { + $this->sys->setDistributionIcon('FreeBSD.png'); + } } else { $this->sys->setDistributionIcon('FreeBSD.png'); } @@ -176,15 +185,20 @@ class FreeBSD extends BSDCommon * * @see BSDCommon::build() * - * @return Void + * @return void */ public function build() { parent::build(); - $this->_memoryadditional(); - $this->_distroicon(); - $this->_network(); - $this->_uptime(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distroicon(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memoryadditional(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.GNU.inc.php b/root/opt/phpsysinfo/includes/os/class.GNU.inc.php new file mode 100644 index 0000000..3d42959 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.GNU.inc.php @@ -0,0 +1,118 @@ + + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version SVN: $Id: class.GNU.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * GNU sysinfo class + * get all the required information from GNU + * + * @category PHP + * @package PSI GNU class + * @author Mieczyslaw Nalewaj + * @copyright 2022 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class GNU extends Linux +{ + /** + * Network devices + * includes also rx/tx bytes + * + * @return void + */ + protected function _network($bufr = null) + { + if ($this->sys->getOS() == 'GNU') { + if (CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $was = false; + $macaddr = ""; + $dev = null; + foreach ($lines as $line) { + if (preg_match("/^\/dev\/([^\s:]+)/", $line, $ar_buf) || preg_match("/^([^\s:]+)/", $line, $ar_buf)) { + if ($was) { + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + $this->sys->setNetDevices($dev); + } + $macaddr = ""; + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + $was = true; + } else { + if ($was) { + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/^\s+inet address\s+(\S+)$/', $line, $ar_buf)) { + $dev->setInfo($ar_buf[1]); + } elseif (preg_match('/^\s+hardware addr\s+(\S+)$/', $line, $ar_buf)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) { + $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf[1])); + if ($macaddr === '00-00-00-00-00-00') { // empty + $macaddr = ""; + } + } + } + } + } + } + } + if ($was) { + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + $this->sys->setNetDevices($dev); + } + } + } else { + parent::_network($bufr); + } + } + + /** + * Number of Users + * + * @return void + */ + protected function _users() + { + if ($this->sys->getOS() == 'GNU') { + if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) { + if (strlen($strBuf) > 0) { + $lines = preg_split('/\n/', $strBuf); + preg_match_all('/^login\s+/m', $strBuf, $ttybuf); + if (($who = count($lines)-count($ttybuf[0])) > 0) { + $this->sys->setUsers($who); + } + } + } + } else { + parent::_users(); + } + } + + /** + * get the information + * + * @return void + */ + public function build() + { + if ($this->sys->getOS() == 'GNU') { + $this->error->addWarning("The GNU Hurd version of phpSysInfo is a work in progress, some things currently don't work"); + } + parent::build(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php index 02626ca..5d1a551 100644 --- a/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php @@ -8,7 +8,7 @@ * @package PSI HPUX OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.HPUX.inc.php 596 2012-07-05 19:37:48Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,12 +20,17 @@ * @package PSI HPUX OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class HPUX extends OS { + /** + * uptime command result. + */ + private $_uptime = null; + /** * Virtual Host Name * @@ -33,8 +38,8 @@ class HPUX extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('hostname', '', $ret)) { $this->sys->setHostname($ret); @@ -42,24 +47,6 @@ class HPUX extends OS } } - /** - * IP of the Virtual Host Name - * - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * HP-UX Version * @@ -80,8 +67,8 @@ class HPUX extends OS */ private function _uptime() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) { $min = $ar_buf[3]; $hours = $ar_buf[2]; $days = $ar_buf[1]; @@ -90,19 +77,6 @@ class HPUX extends OS } } - /** - * Number of Users - * - * @return void - */ - private function _users() - { - if (CommonFunctions::executeProgram('who', '-q', $ret)) { - $who = preg_split('/=/', $ret, -1, PREG_SPLIT_NO_EMPTY); - $this->sys->setUsers($who[1]); - } - } - /** * Processor Load * optionally create a loadbar @@ -111,8 +85,8 @@ class HPUX extends OS */ private function _loadavg() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) { $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); } } @@ -132,31 +106,29 @@ class HPUX extends OS $dev = new CpuDevice(); $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); foreach ($details as $detail) { - $arrBuff = preg_split('/\s+:\s+/', trim($detail)); - if (count($arrBuff) == 2) { - switch (strtolower($arrBuff[0])) { + if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) { + switch (strtolower(trim($arrBuff[1]))) { case 'model name': case 'cpu': - $dev->setModel($arrBuff[1]); + $dev->setModel($arrBuff2); break; case 'cpu mhz': case 'clock': - $dev->setCpuSpeed($arrBuff[1]); + $dev->setCpuSpeed($arrBuff2); break; case 'cycle frequency [hz]': - $dev->setCpuSpeed($arrBuff[1] / 1000000); + $dev->setCpuSpeed($arrBuff2 / 1000000); break; case 'cpu0clktck': - $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64 + $dev->setCpuSpeed(hexdec($arrBuff2) / 1000000); // Linux sparc64 break; case 'l2 cache': case 'cache size': - $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024); + $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff2) * 1024); break; case 'bogomips': case 'cpu0bogo': - $dev->setBogomips($arrBuff[1]); - break; + $dev->setBogomips($arrBuff2); } } } @@ -172,19 +144,25 @@ class HPUX extends OS private function _pci() { if (CommonFunctions::rfts('/proc/pci', $bufr)) { + $device = false; $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { - if (preg_match('/Bus/', $buf)) { + if (preg_match('/^\s*Bus\s/', $buf)) { $device = true; continue; } if ($device) { + $dev = new HWDevice(); + $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($buf))); + $this->sys->setPciDevices($dev); +/* list($key, $value) = preg_split('/: /', $buf, 2); if (!preg_match('/bridge/i', $key) && !preg_match('/USB/i', $key)) { $dev = new HWDevice(); $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($value))); $this->sys->setPciDevices($dev); } +*/ $device = false; } } @@ -203,10 +181,10 @@ class HPUX extends OS if (preg_match('/^hd/', $file)) { $dev = new HWDevice(); $dev->setName(trim($file)); - if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { if (trim($buf) == 'disk') { if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false)) { - $dev->setCapacity(trim($buf) * 512 / 1024); + $dev->setCapacity(trim($buf) * 512); } } } @@ -250,9 +228,11 @@ class HPUX extends OS { if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) { $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $devnum = -1; + $results = array(); foreach ($bufe as $buf) { if (preg_match('/^T/', $buf)) { - $devnum += 1; + $devnum++; $results[$devnum] = ""; } elseif (preg_match('/^S:/', $buf)) { list($key, $value) = preg_split('/: /', $buf, 2); @@ -344,7 +324,7 @@ class HPUX extends OS $mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) { $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); - while (list(, $line) = each($lines)) { + foreach ($lines as $line) { $a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY); $fsdev[$a[0]] = $a[4]; } @@ -381,24 +361,33 @@ class HPUX extends OS * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_loadavg(); - $this->_cpuinfo(); - $this->_pci(); - $this->_ide(); - $this->_scsi(); - $this->_usb(); - $this->_network(); - $this->_memory(); - $this->_filesystems(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_cpuinfo(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_usb(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php index c803156..fe0bbe2 100644 --- a/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php @@ -8,7 +8,7 @@ * @package PSI Haiku OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Haiku.inc.php 687 2012-09-06 20:54:49Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,24 +20,16 @@ * @package PSI Haiku OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class Haiku extends OS { - /** - * call parent constructor - */ - public function __construct() - { - parent::__construct(); - } - /** * get the cpu information * - * @return array + * @return void */ protected function _cpuinfo() { @@ -53,21 +45,22 @@ class Haiku extends OS $dev->setModel($ar_buf[1]); $arrLines = preg_split("/\n/", $cpu, -1, PREG_SPLIT_NO_EMPTY); foreach ($arrLines as $Line) { - if (preg_match("/^\s+Data TLB:\s+(.*)K-byte/", $Line, $Line_buf)) { - $dev->setCache(max($Line_buf[1]*1024, $dev->getCache())); - } elseif (preg_match("/^\s+Data TLB:\s+(.*)M-byte/", $Line, $Line_buf)) { - $dev->setCache(max($Line_buf[1]*1024*1024, $dev->getCache())); - } elseif (preg_match("/^\s+Data TLB:\s+(.*)G-byte/", $Line, $Line_buf)) { - $dev->setCache(max($Line_buf[1]*1024*1024*1024, $dev->getCache())); + if (preg_match("/^\s+Data TLB:\s+(.*)K-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)K-byte/", $Line, $Line_buf)) { + $dev->setCache(max(intval($Line_buf[1])*1024, $dev->getCache())); + } elseif (preg_match("/^\s+Data TLB:\s+(.*)M-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)M-byte/", $Line, $Line_buf)) { + $dev->setCache(max(intval($Line_buf[1])*1024*1024, $dev->getCache())); + } elseif (preg_match("/^\s+Data TLB:\s+(.*)G-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)G-byte/", $Line, $Line_buf)) { + $dev->setCache(max(intval($Line_buf[1])*1024*1024*1024, $dev->getCache())); } elseif (preg_match("/\s+VMX/", $Line, $Line_buf)) { $dev->setVirt("vmx"); } elseif (preg_match("/\s+SVM/", $Line, $Line_buf)) { $dev->setVirt("svm"); } } - if ($cpuspeed != "")$dev->setCpuSpeed($cpuspeed); + if ($cpuspeed != "") { + $dev->setCpuSpeed($cpuspeed); + } $this->sys->setCpus($dev); - //echo ">>>>>".$cpu; } } } @@ -136,7 +129,7 @@ class Haiku extends OS private function _kernel() { if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) { - $this->sys->setKernel($ret); + $this->sys->setKernel($ret); } } @@ -163,19 +156,28 @@ class Haiku extends OS */ private function _uptime() { - if (CommonFunctions::executeProgram('uptime', '-u', $buf)) { - if (preg_match("/^up (\d+) minute[s]?/", $buf, $ar_buf)) { - $min = $ar_buf[1]; - $this->sys->setUptime($min * 60); - } elseif (preg_match("/^up (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) { - $min = $ar_buf[2]; - $hours = $ar_buf[1]; - $this->sys->setUptime($hours * 3600 + $min * 60); - } elseif (preg_match("/^up (\d+) day[s]?, (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $buf, $ar_buf)) { $min = $ar_buf[3]; $hours = $ar_buf[2]; $days = $ar_buf[1]; $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $buf, $ar_buf)) { + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60); + } elseif (preg_match("/up (\d+) day[s]?, (\d+) hour[s]?, (\d+) minute[s]?$/", $buf, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } elseif (preg_match("/up (\d+) hour[s]?, (\d+) minute[s]?$/", $buf, $ar_buf)) { + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60); + } elseif (preg_match("/up (\d+) minute[s]?$/", $buf, $ar_buf)) { + $min = $ar_buf[1]; + $this->sys->setUptime($min * 60); } } } @@ -203,7 +205,7 @@ class Haiku extends OS * * @return void */ - private function _users() + protected function _users() { $this->sys->setUsers(1); } @@ -215,8 +217,8 @@ class Haiku extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { $ip = gethostbyname($result); @@ -227,24 +229,6 @@ class Haiku extends OS } } - /** - * IP of the Virtual Host Name - * - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * Physical memory information and Swap Space information * @@ -256,7 +240,7 @@ class Haiku extends OS if (preg_match("/(.*)bytes free\s+\(used\/max\s+(.*)\s+\/\s+(.*)\)\s*\n\s+\(cached\s+(.*)\)/", $bufr, $ar_buf)) { $this->sys->setMemTotal($ar_buf[3]); $this->sys->setMemFree($ar_buf[1]); - $this->sys->setMemCache($ar_buf[4]); + $this->sys->setMemCache(min($ar_buf[4], $ar_buf[2])); $this->sys->setMemUsed($ar_buf[2]); } } @@ -310,10 +294,13 @@ class Haiku extends OS { if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); - $notwas = true; + $was = false; + $errors = 0; + $drops = 0; + $dev = null; foreach ($lines as $line) { if (preg_match("/^(\S+)/", $line, $ar_buf)) { - if (!$notwas) { + if ($was) { $dev->setErrors($errors); $dev->setDrops($drops); $this->sys->setNetDevices($dev); @@ -322,9 +309,9 @@ class Haiku extends OS $drops = 0; $dev = new NetDevice(); $dev->setName($ar_buf[1]); - $notwas = false; + $was = true; } else { - if (!$notwas) { + if ($was) { if (preg_match('/\sReceive:\s\d+\spackets,\s(\d+)\serrors,\s(\d+)\sbytes,\s\d+\smcasts,\s(\d+)\sdropped/i', $line, $ar_buf2)) { $errors +=$ar_buf2[1]; $drops +=$ar_buf2[3]; @@ -336,18 +323,19 @@ class Haiku extends OS } if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { - if (preg_match('/\sEthernet,\s+Address:\s(\S*)/i', $line, $ar_buf2)) - $dev->setInfo(preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\saddr:\s(\S*),/i', $line, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); - elseif (preg_match('/^\s+inet6\saddr:\s(\S*),/i', $line, $ar_buf2)) - if (!preg_match('/^fe80::/i', $ar_buf2[1])) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + if (preg_match('/\sEthernet,\s+Address:\s(\S*)/i', $line, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\saddr:\s(\S*),/i', $line, $ar_buf2)) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } elseif (preg_match('/^\s+inet6\saddr:\s(\S*),/i', $line, $ar_buf2) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } } } } } - if (!$notwas) { + if ($was) { $dev->setErrors($errors); $dev->setDrops($drops); $this->sys->setNetDevices($dev); @@ -380,24 +368,33 @@ class Haiku extends OS /** * get the information * - * @return Void + * @return void */ public function build() { - $this->error->addError("WARN", "The Haiku version of phpSysInfo is a work in progress, some things currently don't work"); - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_loadavg(); - $this->_pci(); - $this->_usb(); - $this->_cpuinfo(); - $this->_memory(); - $this->_filesystems(); - $this->_network(); - $this->_processes(); + $this->error->addWarning("The Haiku version of phpSysInfo is a work in progress, some things currently don't work"); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_cpuinfo(); + $this->_pci(); + $this->_usb(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.Linux.inc.php b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php index 96abbbf..d9d35bd 100644 --- a/root/opt/phpsysinfo/includes/os/class.Linux.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php @@ -8,7 +8,7 @@ * @package PSI Linux OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,23 +20,250 @@ * @package PSI Linux OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class Linux extends OS { /** - * Assoc array of all CPUs loads. + * Uptime command result. */ - protected $_cpu_loads; + private $_uptime = null; /** - * call parent constructor + * Assoc array of all CPUs loads. */ - public function __construct() + protected $_cpu_loads = null; + + /** + * Version string. + */ + private $_kernel_string = null; + + /** + * Array of info from Bios. + */ + private $_machine_info = null; + + /** + * Content of dmesg file. + */ + private $_dmesg_f = null; + + /** + * Result of executing dmesg command. + */ + private $_dmesg_c = null; + + /** + * Result of systemd-detect-virt. + */ + private $system_detect_virt = null; + + /** + * Read contents of the dmesg file. + * + * @return string + */ + private function _get_dmesg_f() { - parent::__construct(); + if ($this->_dmesg_f === null) { + $this->_dmesg_f = ""; + if (CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false)) { + $this->_dmesg_f = trim($result); + } + } + + return $this->_dmesg_f; + } + + /** + * Save output of the dmesg command. + * + * @return string + */ + private function _get_dmesg_c() + { + if ($this->_dmesg_c === null) { + $this->_dmesg_c = ""; + if (CommonFunctions::executeProgram('dmesg', '', $result, false)) { + $this->_dmesg_c = trim($result); + } + } + + return $this->_dmesg_c; + } + + /** + * Get machine info + * + * @return string + */ + private function _get_machine_info() + { + if ($this->_machine_info === null) { + $this->_machine_info = array(); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + if (CommonFunctions::executeProgram('systemd-detect-virt', '-v', $resultv, false)) { + $this->system_detect_virt = $resultv; + } + } + $vendor_array = array(); + if (((($dmesg = $this->_get_dmesg_f()) !== null) && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $dmesg, $ar_buf)) || + ((($dmesg = $this->_get_dmesg_c()) !== null) && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $dmesg, $ar_buf))) { + $this->_machine_info['machine'] = trim($ar_buf[1]); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) { + /* Test this before sys_vendor to detect KVM over QEMU */ + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = $product_name = trim($buf); + } else { + $product_name = ''; + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + if ($product_name != "") { + $vendor_array[] = trim($buf)." ".$product_name; + } else { + $vendor_array[] = trim($buf); + } + } else { + $vendor_array[] = $this->_machine_info['machine']; + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + } + } else { // 'machine' data from /sys/devices/virtual/dmi/id/ + $bios = ""; + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) { + // Test this before sys_vendor to detect KVM over QEMU + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = $product_name = trim($buf); + } else { + $product_name = ''; + } + + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + if ($product_name != "") { + $this->_machine_info['machine'] = trim($buf)." ".$product_name; + } else { + $this->_machine_info['machine'] = trim($buf); + } + $vendor_array[] = $this->_machine_info["machine"]; + } elseif ($product_name != "") { + $this->_machine_info['machine'] = $product_name; + } + + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) { + $vendor_array[] = trim($buf); + } + } else { + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $this->_machine_info['machine'] = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + if (isset($this->_machine_info['machine'])) { + $this->_machine_info['machine'] .= " ".trim($buf); + } else { + $this->_machine_info['machine'] = trim($buf); + } + } + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + if (isset($this->_machine_info['machine'])) { + $this->_machine_info['machine'] .= "/".trim($buf); + } else { + $this->_machine_info['machine'] = trim($buf); + } + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) { + $bios = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) { + $bios = trim($bios." ".trim($buf)); + } + if ($bios != "") { + if (isset($this->_machine_info['machine'])) { + $this->_machine_info['machine'] .= ", BIOS ".$bios; + } else { + $this->_machine_info['machine'] = "BIOS ".$bios; + } + } + } + if (isset($this->_machine_info['machine'])) { + $this->_machine_info['machine'] = trim(preg_replace("/^\/,?/", "", preg_replace("/ ?(To be filled by O\.E\.M\.|System manufacturer|System Product Name|Not Specified|Default string) ?/i", "", $this->_machine_info['machine']))); + } + + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && count($vendor_array) > 0) { + $virt = CommonFunctions::decodevirtualizer($vendor_array); + if ($virt !== null) { + $this->_machine_info['hypervisor'] = $virt; + } + } + } + + return $this->_machine_info; + } + + /** + * Get kernel string + * + * @return string + */ + private function _get_kernel_string() + { + if ($this->_kernel_string === null) { + $this->_kernel_string = ""; + if ($this->sys->getOS() !== 'SSH') { + if ((CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) && ($strBuf !== '')) || // show effective kernel if ksplice uptrack is installed + (CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG) && ($strBuf !== ''))) { + $this->_kernel_string = $strBuf; + if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG) && ($strBuf !== '')) { + if (preg_match('/ SMP /', $strBuf)) { + $this->_kernel_string .= ' (SMP)'; + } + } + if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG) && ($strBuf !== '')) { + $this->_kernel_string .= ' '.$strBuf; + } + } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1)) { + if (preg_match('/\/Hurd-([^\)]+)/', $strBuf, $ar_buf)) { + $this->_kernel_string = $ar_buf[1]; + } elseif (preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) { + $this->_kernel_string = $ar_buf[1]; + if (preg_match('/ SMP /', $strBuf)) { + $this->_kernel_string .= ' (SMP)'; + } + } + } + } + } + + return $this->_kernel_string; + } + + /** + * check OS type + */ + public function __construct($blockname = false) + { + parent::__construct($blockname); + + if (($this->sys->getOS() == 'SSH') && CommonFunctions::executeProgram('uname', '-s', $strBuf, false) && ($strBuf !== '')) { + $this->sys->setOS($strBuf); + } } /** @@ -44,47 +271,31 @@ class Linux extends OS * * @return void */ - private function _machine() + protected function _machine() { - if ((CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false) - && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf)) - ||(CommonFunctions::executeProgram('dmesg', '', $result, false) - && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))) { - $this->sys->setMachine(trim($ar_buf[1])); - } else { //data from /sys/devices/virtual/dmi/id/ + $machine_info = $this->_get_machine_info(); + if (isset($machine_info['machine'])) { + $machine = $machine_info['machine']; + } else { $machine = ""; - $product = ""; - $board = ""; - $bios = ""; - if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { - $machine = trim($buf); - } - if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) { - $product = trim($buf); - } - if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) { - $board = trim($buf); - } - if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) { - $bios = trim($buf); - } - if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) { - $bios = trim($bios." ".trim($buf)); - } - if ($product != "") { - $machine .= " ".$product; - } - if ($board != "") { - $machine .= "/".$board; - } - if ($bios != "") { - $machine .= ", BIOS ".$bios; - } + } - if ($machine != "") { - $this->sys->setMachine(trim($machine)); + if (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf") // QNAP detection + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf) + && CommonFunctions::fileexists($filename="/etc/platform.conf") // Platform detection + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match("/^DISPLAY_NAME\s*=\s*(\S+)/m", $buf, $mach_buf) && ($mach_buf[1]!=="")) { + if ($machine !== "") { + $machine = "QNAP ".$mach_buf[1].' - '.$machine; + } else { + $machine = "QNAP ".$mach_buf[1]; } } + + if ($machine !== "") { + $this->sys->setMachine($machine); + } } /** @@ -94,34 +305,21 @@ class Linux extends OS */ protected function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST && !defined('PSI_EMU_PORT')) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { - if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1)) { + if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) { $result = trim($result); $ip = gethostbyname($result); if ($ip != $result) { - $this->sys->setHostname(gethostbyaddr($ip)); + $this->sys->setHostname(trim(gethostbyaddr($ip), ".")); } + } elseif (CommonFunctions::executeProgram('hostname', '', $ret, false)) { + $this->sys->setHostname($ret); + } elseif (CommonFunctions::executeProgram('uname', '-n', $ret, false)) { + $this->sys->setHostname($ret); } - } - } - /** - * IP - * - * @return void - */ - protected function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!isset($_SERVER['SERVER_ADDR']) || !($result = $_SERVER['SERVER_ADDR'])) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } } } @@ -130,37 +328,224 @@ class Linux extends OS * * @return void */ - private function _kernel() + protected function _kernel() { - $result = ""; - if (CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) || // show effective kernel if ksplice uptrack is installed - CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG)) { - $result = trim($strBuf); - if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG)) { - if (preg_match('/SMP/', $strBuf)) { - $result .= ' (SMP)'; - } - } - if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG)) { - $result .= ' '.trim($strBuf); - } - } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) && preg_match('/version (.*?) /', $strBuf, $ar_buf)) { - $result = $ar_buf[1]; - if (preg_match('/SMP/', $strBuf)) { - $result .= ' (SMP)'; - } + if (($verBuf = $this->_get_kernel_string()) != "") { + $this->sys->setKernel($verBuf); } - if ($result != "") { - if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) { - if (preg_match('/:\/lxc\//m', $strBuf2)) { - $result .= ' [lxc]'; - } elseif (preg_match('/:\/docker\//m', $strBuf2)) { - $result .= ' [docker]'; - } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) { - $result .= ' [docker]'; + } + + /** + * Virtualizer info + * + * @return void + */ + protected function _virtualizer() + { + if (!defined('PSI_SHOW_VIRTUALIZER_INFO') || !PSI_SHOW_VIRTUALIZER_INFO) { + return; + } + if ($this->system_detect_virt !== null) { + if (($this->system_detect_virt !== "") && ($this->system_detect_virt !== "none")) { + $this->sys->setVirtualizer($this->system_detect_virt); + } + if (($verBuf = $this->_get_kernel_string()) !== "") { + if (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) { + $this->sys->setVirtualizer('wsl2', 'wsl'); // Windows Subsystem for Linux 2 + } + } + if (CommonFunctions::executeProgram('systemd-detect-virt', '-c', $resultc, false) && ($resultc !== "") && ($resultc !== "none")) { + $this->sys->setVirtualizer($resultc); + } + } else { + $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo() + + $novm = true; + // code based on src/basic/virt.c from systemd-detect-virt source code (https://github.com/systemd/systemd) + + // First, try to detect Oracle Virtualbox, Amazon EC2 Nitro and Parallels, even if they use KVM, + // as well as Xen even if it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also + // since it runs as a user-process nested inside other VMs. Also check for Xen now, because Xen PV + // mode does not override CPUID when nested inside another hypervisor. + $machine_info = $this->_get_machine_info(); + if (isset($machine_info['hypervisor'])) { + $hypervisor = $machine_info['hypervisor']; + if (($hypervisor === 'oracle') || ($hypervisor === 'amazon') || ($hypervisor === 'xen') || ($hypervisor === 'parallels')) { + $this->sys->setVirtualizer($hypervisor); + $novm = false; + } + } + + // Detect UML + if ($novm) { + if (isset($cpuvirt["cpuid:UserModeLinux"])) { + $this->sys->setVirtualizer('uml'); // User-mode Linux + $novm = false; + } + } + + // Detect Xen + if ($novm && is_dir('/proc/xen')) { + // xen Dom0 is detected as XEN in hypervisor and maybe others. + // In order to detect the Dom0 as not virtualization we need to + // double-check it + if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) { + if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set + $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0) + $novm = false; + } + } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities + $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0) + $novm = false; + } + } + + // Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is overwritten. + // Since the vendor_id in /proc/cpuinfo is overwritten on virtualization we use values from msr-cpuid. + if ($novm && CommonFunctions::executeProgram('msr-cpuid', '', $bufr, false) + && (preg_match('/^40000000 00000000: [0-9a-f]{8} \S{4} [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4})/m', $bufr, $cpuid))) { + $virt = CommonFunctions::decodevirtualizer($cpuid[1].$cpuid[2].$cpuid[3]); + if ($virt !== null) { + $this->sys->setVirtualizer($virt); + } + } + + // Third, try to detect from DMI. + if ($novm && isset($hypervisor)) { + $this->sys->setVirtualizer($hypervisor); + $novm = false; + } + + // Check high-level hypervisor sysfs file + if ($novm && CommonFunctions::rfts('/sys/hypervisor/type', $type, 1, 4096, false) && ($type === "xen")) { + $this->sys->setVirtualizer('xen'); // Xen hypervisor + $novm = false; + } + + if ($novm) { + if (CommonFunctions::rfts('/proc/device-tree/hypervisor/compatible', $compatible, 1, 4096, false)) { + switch ($compatible) { + case 'linux,kvm': + $this->sys->setVirtualizer('kvm'); // KVM + $novm = false; + break; + case 'vmware': + $this->sys->setVirtualizer('vmware'); // VMware + $novm = false; + break; + case 'xen': + $this->sys->setVirtualizer('xen'); // Xen hypervisor + $novm = false; + } + } else { + if (CommonFunctions::fileexists('/proc/device-tree/ibm,partition-name') + && CommonFunctions::fileexists('/proc/device-tree/hmc-managed?') + && CommonFunctions::fileexists('/proc/device-tree/chosen/qemu,graphic-width')) { + $this->sys->setVirtualizer('powervm'); // IBM PowerVM hypervisor + $novm = false; + } else { + $names = CommonFunctions::findglob('/proc/device-tree', GLOB_NOSORT); + if (is_array($names) && (($total = count($names)) > 0)) { + for ($i = 0; $i < $total; $i++) { + if (preg_match('/fw-cfg/', $names[$i])) { + $this->sys->setVirtualizer('qemu'); // QEMU + $novm = false; + break; + } + } + } + if (CommonFunctions::rfts('/proc/device-tree/compatible', $compatible, 1, 4096, false) && ($compatible === "qemu,pseries")) { + $this->sys->setVirtualizer('qemu'); // QEMU + $novm = false; + } + } + } + } + + if ($novm && CommonFunctions::rfts('/proc/sysinfo', $sysinfo, 0, 4096, false) && preg_match('//VM00 Control Program:\s*(\S+)/m', $sysinfo, $vcp)) { + if ($vcp[1] === 'z/VM') { + $this->sys->setVirtualizer('zvm'); // s390 z/VM + } else { + $this->sys->setVirtualizer('kvm'); // KVM + } + $novm = false; + } + + // Additional tests outside of the systemd-detect-virt source code + if ($novm && ( + ((($dmesg = $this->_get_dmesg_f()) !== null) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $dmesg, $ar_buf)) || + ((($dmesg = $this->_get_dmesg_c()) !== null) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $dmesg, $ar_buf)))) { + switch (trim($ar_buf[1])) { + case 'VMware': + $this->sys->setVirtualizer('vmware'); // VMware + $novm = false; + break; + case 'KVM': + $this->sys->setVirtualizer('kvm'); // KVM + $novm = false; + break; + case 'Microsoft HyperV': + case 'Microsoft Hyper-V': + $this->sys->setVirtualizer('microsoft'); // Hyper-V + $novm = false; + break; + case 'ACRN': + $this->sys->setVirtualizer('acrn'); // ACRN hypervisor + $novm = false; + break; + case 'Jailhouse': + $this->sys->setVirtualizer('jailhouse'); // Jailhouse + $novm = false; + break; + case 'Xen': + case 'Xen PV': + case 'Xen HVM': + // xen Dom0 is detected as XEN in hypervisor and maybe others. + // In order to detect the Dom0 as not virtualization we need to + // double-check it + if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) { + if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set + $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0) + $novm = false; + } + } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities + $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0) + $novm = false; + } + } + } + + // Detect QEMU cpu + if ($novm && isset($cpuvirt["cpuid:QEMU"])) { + $this->sys->setVirtualizer('qemu'); // QEMU + $novm = false; + } + + if ($novm && isset($cpuvirt["hypervisor"])) { + $this->sys->setVirtualizer('unknown'); + } + + if ((count(CommonFunctions::gdc('/proc/vz', false)) == 0) && (count(CommonFunctions::gdc('/proc/bc', false)) > 0)) { + $this->sys->setVirtualizer('openvz'); // OpenVZ/Virtuozzo + } + + if (($verBuf = $this->_get_kernel_string()) !== "") { + if (preg_match('/^[\d\.-]+-Microsoft/', $verBuf)) { + $this->sys->setVirtualizer('wsl'); // Windows Subsystem for Linux + } elseif (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) { + $this->sys->setVirtualizer('wsl2'); // Windows Subsystem for Linux 2 + } + } + + if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) { + if (preg_match('/:\/lxc\//m', $strBuf2)) { + $this->sys->setVirtualizer('lxc'); // Linux container + } elseif (preg_match('/:\/docker\//m', $strBuf2)) { + $this->sys->setVirtualizer('docker'); // Docker + } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) { + $this->sys->setVirtualizer('docker'); // Docker } } - $this->sys->setKernel($result); } } @@ -170,24 +555,41 @@ class Linux extends OS * * @return void */ - protected function _uptime() + protected function _uptime($bufu = null) { - CommonFunctions::rfts('/proc/uptime', $buf, 1); - $ar_buf = preg_split('/ /', $buf); - $this->sys->setUptime(trim($ar_buf[0])); - } - - /** - * Number of Users - * - * @return void - */ - private function _users() - { - if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) { - if (strlen(trim($strBuf)) > 0) { - $lines = preg_split('/\n/', $strBuf); - $this->sys->setUsers(count($lines)); + if (CommonFunctions::rfts('/proc/uptime', $buf, 1, 4096, PSI_OS != 'Android')) { + $ar_buf = preg_split('/ /', $buf); + $this->sys->setUptime(trim($ar_buf[0])); + } elseif (($this->_uptime !== null) || ($bufu !== null) || CommonFunctions::executeProgram('uptime', '', $bufu)) { + if (($this->_uptime === null) && ($bufu !== null)) { + $this->_uptime = $bufu; + } + if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } elseif (preg_match("/up (\d+) day[s]?,[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) { + $min = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $min * 60); + } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) { + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60); + } elseif (preg_match("/up[ ]+(\d+):(\d+):(\d+)/", $this->_uptime, $ar_buf)) { + $sec = $ar_buf[3]; + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60 + $sec); + } elseif (preg_match("/up[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) { + $min = $ar_buf[1]; + $this->sys->setUptime($min * 60); + } elseif (preg_match("/up[ ]+(\d+) day[s]?,[ ]+(\d+) hour[s]?,[ ]+(\d+) minute[s]?/", $this->_uptime, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); } } } @@ -198,13 +600,15 @@ class Linux extends OS * * @return void */ - protected function _loadavg() + protected function _loadavg($buf = null) { - if (CommonFunctions::rfts('/proc/loadavg', $buf)) { + if ((($buf !== null) || CommonFunctions::rfts('/proc/loadavg', $buf, 1, 4096, PSI_OS != 'Android')) && preg_match("/^\d/", trim($buf))) { $result = preg_split("/\s/", $buf, 4); // don't need the extra values, only first three unset($result[3]); $this->sys->setLoad(implode(' ', $result)); + } elseif (($buf === null) && ((($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) && preg_match("/load average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf))) { + $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); } if (PSI_LOAD_BAR) { $this->sys->setLoadPercent($this->_parseProcStat('cpu')); @@ -216,53 +620,56 @@ class Linux extends OS * * @param String $cpuline cpu for which load should be meassured * - * @return Integer + * @return int */ protected function _parseProcStat($cpuline) { - if (is_null($this->_cpu_loads)) { + if ($this->_cpu_loads === null) { $this->_cpu_loads = array(); - if (CommonFunctions::rfts('/proc/stat', $buf)) { + $cpu_tmp = array(); + if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) { if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) { foreach ($matches as $line) { $cpu = $line[1]; $buf2 = $line[2]; - $this->_cpu_loads[$cpu] = array(); + $cpu_tmp[$cpu] = array(); $ab = 0; $ac = 0; $ad = 0; $ae = 0; sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae); - $this->_cpu_loads[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys - $this->_cpu_loads[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total + $cpu_tmp[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys + $cpu_tmp[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total } } - } - // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) - if (PSI_LOAD_BAR) { - sleep(1); - } - if (CommonFunctions::rfts('/proc/stat', $buf)) { - if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) { - foreach ($matches as $line) { - $cpu = $line[1]; - $buf2 = $line[2]; - $ab = 0; - $ac = 0; - $ad = 0; - $ae = 0; - sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae); - $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys - $total2 = $ab + $ac + $ad + $ae; // cpu.total - $total = $this->_cpu_loads[$cpu]['total']; - $load = $this->_cpu_loads[$cpu]['load']; - $this->_cpu_loads[$cpu] = 0; - if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) { - $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total); + // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) + sleep(1); + + if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG)) { + if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) { + foreach ($matches as $line) { + $cpu = $line[1]; + if (isset($cpu_tmp[$cpu])) { + $buf2 = $line[2]; + + $ab = 0; + $ac = 0; + $ad = 0; + $ae = 0; + sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae); + $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys + $total2 = $ab + $ac + $ad + $ae; // cpu.total + $total = $cpu_tmp[$cpu]['total']; + $load = $cpu_tmp[$cpu]['load']; + $this->_cpu_loads[$cpu] = 0; + if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) { + $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total); + } + } } } } @@ -271,9 +678,9 @@ class Linux extends OS if (isset($this->_cpu_loads[$cpuline])) { return $this->_cpu_loads[$cpuline]; + } else { + return null; } - - return 0; } /** @@ -282,24 +689,116 @@ class Linux extends OS * * @return void */ - protected function _cpuinfo() + protected function _cpuinfo($bufr = null) { - if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) { + if (($bufr !== null) || CommonFunctions::rfts('/proc/cpuinfo', $bufr)) { + $cpulist = null; + $raslist = null; + + // sparc + if (preg_match('/\nCpu(\d+)Bogo\s*:/i', $bufr)) { + $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\nCpu0ClkTck:", preg_replace('/\nCpu(\d+)Bogo\s*:/i', "\n\nprocessor: $1\nCpu0Bogo:", $bufr)); + } else { + $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\n\nprocessor: $1\nCpu0ClkTck:", $bufr); + } + + if (preg_match('/\nprocessor\s*:\s*\d+\r?\nprocessor\s*:\s*\d+/', $bufr)) { + $bufr = preg_replace('/^(processor\s*:\s*\d+)\r?$/m', "$1\n", $bufr); + } + + // IBM/S390 + $bufr = preg_replace('/\ncpu number\s*:\s*(\d+)\r?\ncpu MHz dynamic\s*:\s*(\d+)/m', "\nprocessor:$1\nclock:$2", $bufr); + + // machine + $bufr = preg_replace('/(\nmachine\s*:\s*[^\r\n]+)/m', "$1\n", $bufr); + $processors = preg_split('/\s?\n\s?\n/', trim($bufr)); + + //first stage + $_arch = null; + $_impl = null; + $_part = null; + $_vari = null; + $_hard = null; + $_revi = null; + $_cpus = null; + $_buss = null; + $_bogo = null; + $_vend = null; + $_system = null; $procname = null; - foreach ($processors as $processor) { + foreach ($processors as $processor) if (!preg_match('/^\s*processor\s*:/mi', $processor)) { + $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); + foreach ($details as $detail) { + if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) { + switch (strtolower(trim($arrBuff[1]))) { + case 'cpu architecture': + $_arch = $arrBuff2; + break; + case 'cpu implementer': + $_impl = $arrBuff2; + break; + case 'cpu part': + $_part = $arrBuff2; + break; + case 'cpu variant': + $_vari = $arrBuff2; + break; + case 'system type': + $_system = $arrBuff2; + break; + case 'machine': + case 'hardware': + $_hard = $arrBuff2; + break; + case 'revision': + $_revi = $arrBuff2; + break; + case 'cpu frequency': + if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) { + $_cpus = round($bufr2[1]/1000000); + } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) { + $_cpus = $bufr2[1]; + } + break; + case 'system bus frequency': + if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) { + $_buss = round($bufr2[1]/1000000); + } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) { + $_buss = $bufr2[1]; + } + break; + case 'bogomips per cpu': + $_bogo = round($arrBuff2); + break; + case 'vendor_id': + $_vend = $arrBuff2; + break; + case 'cpu': + $procname = $arrBuff2; + } + } + } + } + + //second stage + $cpucount = 0; + $speedset = false; + foreach ($processors as $processor) if (preg_match('/^\s*processor\s*:/mi', $processor)) { $proc = null; $arch = null; + $impl = null; + $part = null; + $vari = null; $dev = new CpuDevice(); $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); foreach ($details as $detail) { - $arrBuff = preg_split('/\s*:\s*/', trim($detail)); - if (count($arrBuff) == 2) { - switch (strtolower($arrBuff[0])) { + if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) { + switch (strtolower(trim($arrBuff[1]))) { case 'processor': - $proc = trim($arrBuff[1]); + $proc = $arrBuff2; if (is_numeric($proc)) { - if (strlen($procname)>0) { + if (($procname !== null) && (strlen($procname) > 0)) { $dev->setModel($procname); } } else { @@ -311,52 +810,100 @@ class Linux extends OS case 'cpu model': case 'cpu type': case 'cpu': - $dev->setModel($arrBuff[1]); + $dev->setModel($arrBuff2); + break; + case 'cpu frequency': + if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) { + if (($tmpsp = round($bufr2[1]/1000000)) > 0) { + $dev->setCpuSpeed($tmpsp); + $speedset = true; + } + } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) { + if ($bufr2[1] > 0) { + $dev->setCpuSpeed($bufr2[1]); + $speedset = true; + } + } break; case 'cpu mhz': case 'clock': - if ($arrBuff[1] > 0) { //openSUSE fix - $dev->setCpuSpeed($arrBuff[1]); + if ($arrBuff2 > 0) { + $dev->setCpuSpeed($arrBuff2); + $speedset = true; } break; + case 'cpu mhz static': + $dev->setCpuSpeedMax($arrBuff2); + break; case 'cycle frequency [hz]': - $dev->setCpuSpeed($arrBuff[1] / 1000000); + if (($tmpsp = round($arrBuff2/1000000)) > 0) { + $dev->setCpuSpeed($tmpsp); + $speedset = true; + } break; - case 'cpu0clktck': - $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64 + case 'cpu0clktck': // Linux sparc64 + if (($tmpsp = round(hexdec($arrBuff2)/1000000)) > 0) { + $dev->setCpuSpeed($tmpsp); + $speedset = true; + } break; - case 'l2 cache': + case 'l3 cache': case 'cache size': - $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024); + $dev->setCache(trim(preg_replace("/[a-zA-Z]/", "", $arrBuff2)) * 1024); break; case 'initial bogomips': case 'bogomips': case 'cpu0bogo': - $dev->setBogomips($arrBuff[1]); + $dev->setBogomips(round($arrBuff2)); break; case 'flags': - if (preg_match("/ vmx/", $arrBuff[1])) { + if (preg_match("/ vmx/", $arrBuff2)) { $dev->setVirt("vmx"); - } elseif (preg_match("/ svm/", $arrBuff[1])) { + } elseif (preg_match("/ svm/", $arrBuff2)) { $dev->setVirt("svm"); - } elseif (preg_match("/ hypervisor/", $arrBuff[1])) { - $dev->setVirt("hypervisor"); + } + if (preg_match("/ hypervisor/", $arrBuff2)) { + if ($dev->getVirt() === null) { + $dev->setVirt("hypervisor"); + } + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) { + $this->sys->setVirtualizer("hypervisor", false); + } } break; case 'i size': case 'd size': if ($dev->getCache() === null) { - $dev->setCache($arrBuff[1] * 1024); + $dev->setCache($arrBuff2 * 1024); } else { - $dev->setCache($dev->getCache() + ($arrBuff[1] * 1024)); + $dev->setCache($dev->getCache() + ($arrBuff2 * 1024)); } break; case 'cpu architecture': - $arch = trim($arrBuff[1]); + $arch = $arrBuff2; break; + case 'cpu implementer': + $impl = $arrBuff2; + break; + case 'cpu part': + $part = $arrBuff2; + break; + case 'cpu variant': + $vari = $arrBuff2; + break; + case 'vendor_id': + $dev->setVendorId($arrBuff2); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $arrBuff2)) { + $this->sys->setVirtualizer("cpuid:UserModeLinux", false); + } } } } + if ($arch === null) $arch = $_arch; + if ($impl === null) $impl = $_impl; + if ($part === null) $part = $_part; + if ($vari === null) $vari = $_vari; + // sparc64 specific code follows // This adds the ability to display the cache that a CPU has // Originally made by Sven Blumenstein in 2004 @@ -364,43 +911,157 @@ class Linux extends OS $sparclist = array('SUNW,UltraSPARC@0,0', 'SUNW,UltraSPARC-II@0,0', 'SUNW,UltraSPARC@1c,0', 'SUNW,UltraSPARC-IIi@1c,0', 'SUNW,UltraSPARC-II@1c,0', 'SUNW,UltraSPARC-IIe@0,0'); foreach ($sparclist as $name) { if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) { - $dev->setCache(base_convert($buf, 16, 10)); + $dev->setCache(base_convert(trim($buf), 16, 10)); } } // sparc64 specific code ends // XScale detection code - if (($arch === "5TE") && ($dev->getBogomips() != null)) { - $dev->setCpuSpeed($dev->getBogomips()); //BogoMIPS are not BogoMIPS on this CPU, it's the speed + if (($arch === "5TE") && (($bogo = $dev->getBogomips()) !== null) && ($bogo > 0)) { + $dev->setCpuSpeed($bogo); // BogoMIPS are not BogoMIPS on this CPU, it's the speed + $speedset = true; $dev->setBogomips(null); // no BogoMIPS available, unset previously set BogoMIPS } - if ($proc != null) { + if (($dev->getBusSpeed() == 0) && ($_buss !== null)) { + $dev->setBusSpeed($_buss); + } + if (($dev->getCpuSpeed() == 0) && ($_cpus !== null) && ($_cpus > 0)) { + $dev->setCpuSpeed($_cpus); + $speedset = true; + } + if (($dev->getBogomips() == 0) && ($_bogo !== null)) { + $dev->setBogomips($_bogo); + } + if (($dev->getVendorId() === null) && ($_vend !== null)) { + $dev->setVendorId($_vend); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $_vend)) { + $this->sys->setVirtualizer("cpuid:UserModeLinux", false); + } + } + + if ($proc !== null) { if (!is_numeric($proc)) { $proc = 0; } // variable speed processors specific code follows - if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)) { - $dev->setCpuSpeed($buf / 1000); - } elseif (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) { - $dev->setCpuSpeed($buf / 1000); + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false) + || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) { + if (round(trim($buf)/1000) > 0) { + $dev->setCpuSpeed(round(trim($buf)/1000)); + $speedset = true; + } } - if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)) { - $dev->setCpuSpeedMax($buf / 1000); + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false) + || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_max_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeedMax(round(trim($buf)/1000)); } - if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)) { - $dev->setCpuSpeedMin($buf / 1000); + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false) + || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_min_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeedMin(round(trim($buf)/1000)); } // variable speed processors specific code ends if (PSI_LOAD_BAR) { $dev->setLoad($this->_parseProcStat('cpu'.$proc)); } - - if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)) { - $dev->setTemp(substr($buf, 25, 2)); +/* + if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false) + && preg_match("/(\S+)\sC$/", $buf, $value)) { + $dev->setTemp(value[1]); } - if ($dev->getModel() === "") { - $dev->setModel("unknown"); +*/ + if (($arch !== null) && ($impl !== null) && ($part !== null)) { + if (($impl === '0x41') + && (($_hard === 'BCM2708') || ($_hard === 'BCM2709') || ($_hard === 'BCM2710') || ($_hard === 'BCM2711') || ($_hard === 'BCM2712') || ($_hard === 'BCM2835') || ($_hard === 'BCM2836') || ($_hard === 'BCM2837') || ($_hard === 'BCM2838')) + && ($_revi !== null)) { // Raspberry Pi detection (instead of 'cat /proc/device-tree/model') + if ($raslist === null) $raslist = @parse_ini_file(PSI_APP_ROOT."/data/raspberry.ini", true); + $oldmach = $this->sys->getMachine(); + if (($oldmach !== '') && preg_match("/^raspberrypi rpi(,.+)/", $oldmach, $machbuf)) { + $oldmachend = $machbuf[1]; + } else { + $oldmachend = ''; + } + if ($raslist && !preg_match('/[^0-9a-f]/', $_revi)) { + if (($revidec = hexdec($_revi)) & 0x800000) { + if (($oldmach === '') || ($oldmachend !== '')) { + $manufacturer = ($revidec >> 16) & 15; + if (isset($raslist['manufacturer'][$manufacturer])) { + $manuf = ' '.$raslist['manufacturer'][$manufacturer]; + } else { + $manuf = ''; + } + $model = ($revidec >> 4) & 255; + if (isset($raslist['model'][$model])) { + $this->sys->setMachine('Raspberry Pi '.$raslist['model'][$model].' (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend); + } else { + $this->sys->setMachine('Raspberry Pi (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend); + } + } + } else { + if (($oldmach === '') || ($oldmachend !== '')) { + if (isset($raslist['old'][$revidec & 0x7fffff])) { + $this->sys->setMachine('Raspberry Pi '.$raslist['old'][$revidec & 0x7fffff].$oldmachend); + } else { + $this->sys->setMachine('Raspberry Pi'.$oldmachend); + } + } + } + } + } elseif ($this->sys->getMachine() === '') { // other ARM hardware + if ($_hard !== null) { + if ($_system !== null) { + $this->sys->setMachine($_hard." - ".$_system); + } else { + $this->sys->setMachine($_hard); + } + } elseif ($_system !== null) { + $this->sys->setMachine($_system); + } + } + if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true); + if ($cpulist && (((($vari !== null) && isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part.','.$vari)])) + || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part)])))) { + if (($cpumodel = $dev->getModel()) !== '') { + $dev->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]); + } else { + $dev->setModel($cpulist['cpu'][$cpufromlist]); + } + } + } elseif ($this->sys->getMachine() === '') { // other hardware + if ($_hard !== null) { + if ($_system !== null) { + $this->sys->setMachine($_hard." - ".$_system); + } else { + $this->sys->setMachine($_hard); + } + } elseif ($_system !== null) { + $this->sys->setMachine($_system); + } + } + + $cpumodel = $dev->getModel(); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && preg_match('/^QEMU Virtual CPU version /', $cpumodel)) { + $this->sys->setVirtualizer("cpuid:QEMU", false); + } + if ($cpumodel === "") { + if (($vendid = $dev->getVendorId()) !== "") { + $dev->setModel($vendid); + } else { + $dev->setModel("unknown"); + } + } + $cpucount++; + $this->sys->setCpus($dev); + } + } + + $cpudevices = CommonFunctions::findglob('/sys/devices/system/cpu/cpu[0-9]*/uevent', GLOB_NOSORT); + if (is_array($cpudevices) && (($cpustopped = count($cpudevices)-$cpucount) > 0)) { + for (; $cpustopped > 0; $cpustopped--) { + $dev = new CpuDevice(); + $dev->setModel("stopped"); + if ($speedset) { + $dev->setCpuSpeed(-1); } $this->sys->setCpus($dev); } @@ -415,29 +1076,67 @@ class Linux extends OS */ private function _pci() { - if (!$arrResults = Parser::lspci()) { - if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) { - $booDevice = false; - $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); - foreach ($arrBuf as $strLine) { - if (preg_match('/Bus/', $strLine)) { - $booDevice = true; - continue; - } - if ($booDevice) { - list($strKey, $strValue) = preg_split('/: /', $strLine, 2); - if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) { - $dev = new HWDevice(); - $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strValue))); - $this->sys->setPciDevices($dev); - } - $booDevice = false; + if ($arrResults = Parser::lspci()) { + foreach ($arrResults as $dev) { + $this->sys->setPciDevices($dev); + } + } elseif (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) { + $booDevice = false; + $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrBuf as $strLine) { + if (preg_match('/^\s*Bus\s/', $strLine)) { + $booDevice = true; + continue; + } + if ($booDevice) { + $dev = new HWDevice(); + $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strLine))); + $this->sys->setPciDevices($dev); +/* + list($strKey, $strValue) = preg_split('/: /', $strLine, 2); + if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) { + $dev = new HWDevice(); + $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strValue))); + $this->sys->setPciDevices($dev); } +*/ + $booDevice = false; } } } else { - foreach ($arrResults as $dev) { - $this->sys->setPciDevices($dev); + $pcidevices = CommonFunctions::findglob('/sys/bus/pci/devices/*/uevent', GLOB_NOSORT); + if (is_array($pcidevices) && (($total = count($pcidevices)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($pcidevices[$i], $buf, 0, 4096, false) && (trim($buf) != "")) { + $pcibuf = ""; + if (preg_match("/^PCI_CLASS=(\S+)/m", trim($buf), $subbuf)) { + $pcibuf = "Class ".$subbuf[1].":"; + } + if (preg_match("/^PCI_ID=(\S+)/m", trim($buf), $subbuf)) { + $pcibuf .= " Device ".$subbuf[1]; + } + if (preg_match("/^DRIVER=(\S+)/m", trim($buf), $subbuf)) { + $pcibuf .= " Driver ".$subbuf[1]; + } + $dev = new HWDevice(); + if (trim($pcibuf) != "") { + $dev->setName(trim($pcibuf)); + } else { + $dev->setName("unknown"); + } + $this->sys->setPciDevices($dev); + } + } + } elseif (($dmesg = $this->_get_dmesg_c()) !== null) { + $arrBuf = preg_split("/\n/", $dmesg, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrBuf as $strLine) { + if (preg_match('/^[\s\[\]\.\d]*pci\s+\d\d\d\d:\d\d:\d\d.\d: (\[[^\]]+\].*)/', $strLine, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1])); + $this->sys->setPciDevices($dev); + } + } } } } @@ -454,10 +1153,10 @@ class Linux extends OS if (preg_match('/^hd/', $file)) { $dev = new HWDevice(); $dev->setName(trim($file)); - if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { if (trim($buf) == 'disk') { if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) { - $dev->setCapacity(trim($buf) * 512 / 1024); + $dev->setCapacity(trim($buf) * 512); } } } @@ -476,22 +1175,45 @@ class Linux extends OS */ private function _scsi() { - $get_type = false; + $getline = 0; $device = null; + $scsiid = null; if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) { $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { - if (preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices)) { - $get_type = true; + if (preg_match('/Host: scsi(\d+) Channel: (\d+) Target: (\d+) Lun: (\d+)/i', $buf, $scsiids) + || preg_match('/Host: scsi(\d+) Channel: (\d+) Id: (\d+) Lun: (\d+)/i', $buf, $scsiids)) { + $scsiid = $scsiids; + $getline = 1; + continue; + } + if ($getline == 1) { + preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices); + $getline = 2; $device = $devices; continue; } - if ($get_type) { + if ($getline == 2) { preg_match('/Type:\s+(\S+)/i', $buf, $dev_type); + $dev = new HWDevice(); $dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')'); + + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && ($dev_type[1]==='Direct-Access')) { + $sizelist = CommonFunctions::findglob('/sys/bus/scsi/devices/'.intval($scsiid[1]).':'.intval($scsiid[2]).':'.intval($scsiid[3]).':'.intval($scsiid[4]).'/*/*/size', GLOB_NOSORT); + if (is_array($sizelist) && (($total = count($sizelist)) > 0)) { + $buf = ""; + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($sizelist[$i], $buf, 1, 4096, false) && (($buf=trim($buf)) != "") && ($buf > 0)) { + $dev->setCapacity($buf * 512); + break; + } + } + } + } $this->sys->setScsiDevices($dev); - $get_type = false; + $getline = 0; } } } @@ -500,47 +1222,161 @@ class Linux extends OS /** * USB devices * - * @return array + * @return void */ - private function _usb() + protected function _usb($bufu = null) { - $devnum = -1; - if (!CommonFunctions::executeProgram('lsusb', '', $bufr, PSI_DEBUG)) { - if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) { + $usbarray = array(); + if ($nobufu = ($bufu === null)) { + if (CommonFunctions::executeProgram('lsusb', (PSI_OS != 'Android')?'':'2>/dev/null', $bufr, PSI_DEBUG && (PSI_OS != 'Android'), 5) && ($bufr !== "")) { $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { - if (preg_match('/^T/', $buf)) { - $devnum += 1; - $results[$devnum] = ""; - } elseif (preg_match('/^S:/', $buf)) { - list($key, $value) = preg_split('/: /', $buf, 2); - list($key, $value2) = preg_split('/=/', $value, 2); - if (trim($key) != "SerialNumber") { - $results[$devnum] .= " ".trim($value2); + $device = preg_split("/ /", $buf, 7); + if (((isset($device[6]) && trim($device[6]) != "")) || + ((isset($device[5]) && trim($device[5]) != ""))) { + $usbid = intval($device[1]).'-'.intval(trim($device[3], ':')).' '.$device[5]; + if ((isset($device[6]) && trim($device[6]) != "")) { + $usbarray[$usbid]['name'] = trim($device[6]); + } else { + $usbarray[$usbid]['name'] = 'unknown'; } } } - foreach ($results as $var) { - $dev = new HWDevice(); - $dev->setName($var); - $this->sys->setUsbDevices($dev); + } + + $usbdevices = CommonFunctions::findglob('/sys/bus/usb/devices/*/idProduct', GLOB_NOSORT); + if (is_array($usbdevices) && (($total = count($usbdevices)) > 0)) { + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($usbdevices[$i], $idproduct, 1, 4096, false) && (($idproduct=trim($idproduct)) != "")) { // is readable + $busnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/busnum'); + $devnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/devnum'); + $idvendor = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/idVendor'); + if (($busnum!==null) && ($devnum!==null) && ($idvendor!==null)) { + $usbid = intval($busnum).'-'.intval($devnum).' '.$idvendor.':'.$idproduct; + $manufacturer = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/manufacturer'); + if ($manufacturer!==null) { + $usbarray[$usbid]['manufacturer'] = $manufacturer; + } + $product = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/product'); + if ($product!==null) { + $usbarray[$usbid]['product'] = $product; + } + $speed = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/speed'); + if ($product!==null) { + $usbarray[$usbid]['speed'] = $speed; + } + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $serial = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/serial'); + if (($serial!==null) && !preg_match('/\W/', $serial)) { + $usbarray[$usbid]['serial'] = $serial; + } + } + } + } } } - } else { + } + + if (!$nobufu || ((count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/usb/devices', $bufu, 0, 4096, false))) { // usb-devices + $devnum = -1; + $bufe = preg_split("/\n/", $bufu, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/^T/', $buf)) { + $devnum++; + if (preg_match('/\sSpd=([\d\.]+)/', $buf, $bufr) + && isset($bufr[1]) && ($bufr[1]!=="")) { + $usbarray[$devnum]['speed'] = $bufr[1]; + } + } elseif (preg_match('/^S:/', $buf)) { + list($key, $value) = preg_split('/: /', $buf, 2); + list($key, $value2) = preg_split('/=/', $value, 2); + switch (trim($key)) { + case 'Manufacturer': + $usbarray[$devnum]['manufacturer'] = trim($value2); + break; + case 'Product': + $usbarray[$devnum]['product'] = trim($value2); + break; + case 'SerialNumber': + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL + && !preg_match('/\W/', trim($value2))) { + $usbarray[$devnum]['serial'] = trim($value2); + } + } + } + } + } + + if ($nobufu && (count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/input/devices', $bufr, 0, 4096, false)) { + $devnam = "unknown"; $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { - $device = preg_split("/ /", $buf, 7); - if (isset($device[6]) && trim($device[6]) != "") { - $dev = new HWDevice(); - $dev->setName(trim($device[6])); - $this->sys->setUsbDevices($dev); - } elseif (isset($device[5]) && trim($device[5]) != "") { - $dev = new HWDevice(); - $dev->setName("unknown"); - $this->sys->setUsbDevices($dev); + if (preg_match('/^I:\s+(.+)/', $buf, $bufr) + && isset($bufr[1]) && (trim($bufr[1])!=="")) { + $devnam = trim($bufr[1]); + $usbarray[$devnam]['phys'] = 'unknown'; + } elseif (preg_match('/^N:\s+Name="([^"]+)"/', $buf, $bufr2) + && isset($bufr2[1]) && (trim($bufr2[1])!=="")) { + $usbarray[$devnam]['name'] = trim($bufr2[1]); + } elseif (preg_match('/^P:\s+Phys=(.*)/', $buf, $bufr2) + && isset($bufr2[1]) && (trim($bufr2[1])!=="")) { + $usbarray[$devnam]['phys'] = trim($bufr2[1]); + } elseif (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS + && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL + && preg_match('/^U:\s+Uniq=(.+)/', $buf, $bufr2) + && isset($bufr2[1]) && (trim($bufr2[1])!=="")) { + $usbarray[$devnam]['serial'] = trim($bufr2[1]); } } } + + foreach ($usbarray as $usbdev) if (!isset($usbdev['phys']) || preg_match('/^usb-/', $usbdev['phys'])) { + $dev = new HWDevice(); + + if (isset($usbdev['manufacturer']) && (($manufacturer=$usbdev['manufacturer']) !== 'no manufacturer')) { + if (preg_match("/^linux\s/i", $manufacturer)) { + $manufacturer = 'Linux Foundation'; + } + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setManufacturer($manufacturer); + } + } else { + $manufacturer = ''; + } + + if (isset($usbdev['product'])) { + $product = $usbdev['product']; + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setProduct($product); + } + } else { + $product = ''; + } + + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($usbdev['speed'])) { + $dev->setSpeed($usbdev['speed']); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL + && isset($usbdev['serial'])) { + $dev->setSerial($usbdev['serial']); + } + } + + if (isset($usbdev['name']) && (($name=$usbdev['name']) !== 'unknown')) { + $dev->setName($name); + } else { + if (($newname = trim($manufacturer.' '.$product)) !== '') { + $dev->setName($newname); + } else { + $dev->setName('unknown'); + } + } + + $this->sys->setUsbDevices($dev); + } } /** @@ -550,17 +1386,92 @@ class Linux extends OS */ protected function _i2c() { - $i2cdevices = glob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT); - if (($total = count($i2cdevices)) > 0) { + $i2cdevices = CommonFunctions::findglob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT); + if (is_array($i2cdevices) && (($total = count($i2cdevices)) > 0)) { $buf = ""; for ($i = 0; $i < $total; $i++) { - if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false)) { - if (trim($buf) != "") { + if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false) && (trim($buf) != "")) { + $dev = new HWDevice(); + $dev->setName(trim($buf, ": \n\r\t\v\x00")); + $this->sys->setI2cDevices($dev); + } + } + } + } + + /** + * NVMe devices + * + * @return void + */ + protected function _nvme() + { + if (CommonFunctions::executeProgram('nvme', 'list', $bufr, PSI_DEBUG) && ($bufr!="")) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $count = 0; + $nlocate = array(); + $nsize = array(); + foreach ($bufe as $buf) { + if ($count == 1) { + $locid = 0; + $nlocate[0] = 0; + $total = strlen($buf); + $begin = true; + for ($i = 0; $i < $total; $i++) { + if ($begin) { + if ($buf[$i] !== '-') { + $nsize[$locid] = $i - $nlocate[$locid]; + $locid++; + $begin = false; + } + } else { + if ($buf[$i] === '-') { + $nlocate[$locid] = $i; + $begin = true; + } + } + } + if ($begin) { + $nsize[$locid] = $i - $nlocate[$locid]; + } + } elseif ($count > 1) { + if (isset($nlocate[2]) && isset($nsize[2]) && (($nvname=trim(substr($buf, $nlocate[2], $nsize[2]))) !== '')) { $dev = new HWDevice(); - $dev->setName(trim($buf)); - $this->sys->setI2cDevices($dev); + $dev->setName($nvname); + if (defined('PSI_SHOW_DEVICES_INFOS') && (PSI_SHOW_DEVICES_INFOS)) { + if (isset($nlocate[4]) && isset($nsize[4])) { + if (preg_match('/\/\s*([0-9\.]+)\s*(B|KB|MB|GB|TB|PB)$/', str_replace(',', '.', trim(substr($buf, $nlocate[4], $nsize[4]))), $tmpbuf)) { + switch ($tmpbuf[2]) { + case 'B': + $dev->setCapacity($tmpbuf[1]); + break; + case 'KB': + $dev->setCapacity(1000*$tmpbuf[1]); + break; + case 'MB': + $dev->setCapacity(1000*1000*$tmpbuf[1]); + break; + case 'GB': + $dev->setCapacity(1000*1000*1000*$tmpbuf[1]); + break; + case 'TB': + $dev->setCapacity(1000*1000*1000*1000*$tmpbuf[1]); + break; + case 'PB': + $dev->setCapacity(1000*1000*1000*1000*1000*$tmpbuf[1]); + } + } + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + if (isset($nlocate[1]) && isset($nsize[1])) { + $dev->setSerial(trim(substr($buf, $nlocate[1], $nsize[1]))); + } + } + } + $this->sys->setNvmeDevices($dev); } } + $count++; } } } @@ -571,9 +1482,9 @@ class Linux extends OS * * @return void */ - protected function _network() + protected function _network($bufr = null) { - if (CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) { + if (($bufr === null) && CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) { $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { if (preg_match('/:/', $buf)) { @@ -585,54 +1496,232 @@ class Linux extends OS $dev->setTxBytes($stats[8]); $dev->setErrors($stats[2] + $stats[10]); $dev->setDrops($stats[3] + $stats[11]); - if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG))) { - $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); - foreach ($bufe2 as $buf2) { -// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) - if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) - || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2) - || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)) { - if ($ar_buf2[1] != $ar_buf2[2]) { - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); - } else { - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + if (((defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) || (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE)) + && CommonFunctions::executeProgram('ip', 'addr show '.trim($dev_name), $bufr2, PSI_DEBUG) && (trim($bufr2)!="")) { + if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE && preg_match("/^\d+:\s+([^\s:@]+).+\s+master\s+(\S+)/", $bufr2, $brbufr)) { + $dev->setBridge($brbufr[2]); + } + } else { + $bufr2 = ""; + } + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + $macaddr = ""; + if (($bufr2!="") || CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG)) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { +// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) + if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) + || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $buf2, $ar_buf2) + || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2) + || preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $buf2, $ar_buf2) + || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) { + $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1])); + if (($macaddr === '00-00-00-00-00-00') || ($macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') || ($macaddr === '--') || ($macaddr === '0.0.0.0')) { // empty + $macaddr = ""; + } } - } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2) - || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2) - || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2) - || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2) - || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $buf2, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2) + /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $buf2, $ar_buf2)*/) { + if ($ar_buf2[1] != $ar_buf2[2]) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2) + || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $buf2, $ar_buf2)) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } + } + } + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + if ((!CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) && + (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) { + if ($speed > 1000) { + $speed = $speed/1000; + $unit = "G"; + } else { + $unit = "M"; + } + if (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s '.$duplex); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s'); + } } } $this->sys->setNetDevices($dev); } } - } elseif (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { + } elseif (($bufr === null) && CommonFunctions::executeProgram('ip', 'addr show', $bufr, PSI_DEBUG) && ($bufr!="")) { $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); - $notwas = true; + $was = false; + $macaddr = ""; + $speedinfo = ""; + $dev = null; foreach ($lines as $line) { - if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) { - if (!$notwas) { + if (preg_match("/^\d+:\s+([^\s:@]+)(.*)/", $line, $ar_buf)) { + if ($was) { + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + if ($speedinfo != "") { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } + $this->sys->setNetDevices($dev); + } + $speedinfo = ""; + $macaddr = ""; + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE + && isset($ar_buf[2]) && (($ar_buf[2] = trim($ar_buf[2])) !=="") && preg_match("/\s+master\s+(\S+)/", $ar_buf[2], $bufr2)) { + $dev->setBridge($bufr2[1]); + } + if (CommonFunctions::executeProgram('ip', '-s link show '.$ar_buf[1], $bufr2, false) && ($bufr2!="") + && preg_match("/\n\s+RX:\s[^\n]+\n\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)[^\n]+\n\s+TX:\s[^\n]+\n\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)/m", $bufr2, $ar_buf2)) { + $dev->setRxBytes($ar_buf2[1]); + $dev->setTxBytes($ar_buf2[4]); + $dev->setErrors($ar_buf2[2]+$ar_buf2[5]); + $dev->setDrops($ar_buf2[3]+$ar_buf2[6]); + } elseif (CommonFunctions::executeProgram('ifconfig', $ar_buf[1], $bufr2, false) && ($bufr2!="")) { + if (preg_match('/\sRX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) { + $dev->setRxBytes($ar_buf2[1]); + } + if (preg_match('/\sTX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) { + $dev->setTxBytes($ar_buf2[1]); + } + $errors = 0; + $drops = 0; + if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[2]; + } + if (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[2]; + } $dev->setErrors($errors); $dev->setDrops($drops); + } + $was = true; + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) && + (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) { + if ($speed > 1000) { + $speed = $speed/1000; + $unit = "G"; + } else { + $unit = "M"; + } + if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) { + $speedinfo = $speed.$unit.'b/s '.$duplex; + } else { + $speedinfo = $speed.$unit.'b/s'; + } + } + } + } else { + if ($was) { + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $line, $ar_buf2) + || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $line, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) { + $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1])); + if (($macaddr === '00-00-00-00-00-00') || ($macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') || ($macaddr === '--') || ($macaddr === '0.0.0.0')) { // empty + $macaddr = ""; + } + } + } elseif (preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2) + /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $line, $ar_buf2)*/) { + if ($ar_buf2[1] != $ar_buf2[2]) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } elseif (preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } + } + } + } + } + if ($was) { + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + if ($speedinfo != "") { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } + $this->sys->setNetDevices($dev); + } + } elseif (($bufr !== null) || CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $was = false; + $errors = 0; + $drops = 0; + $macaddr = ""; + $speedinfo = ""; + $dev = null; + foreach ($lines as $line) { + if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) { + if ($was) { + $dev->setErrors($errors); + $dev->setDrops($drops); + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + if ($speedinfo != "") { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } $this->sys->setNetDevices($dev); } $errors = 0; $drops = 0; + $speedinfo = ""; + $macaddr = ""; $dev = new NetDevice(); $dev->setName($ar_buf[1]); - $notwas = false; + $was = true; if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { - if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2)) + if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) && + (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) { + if ($speed > 1000) { + $speed = $speed/1000; + $unit = "G"; + } else { + $unit = "M"; + } + if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) { + $speedinfo = $speed.$unit.'b/s '.$duplex; + } else { + $speedinfo = $speed.$unit.'b/s'; + } + } + if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2) + || preg_match('/^'.$ar_buf[1].'\s+Link\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $line, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) { + $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1])); + if ($macaddr === '00-00-00-00-00-00') { // empty + $macaddr = ""; + } + } + } elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2)) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); } } else { - if (!$notwas) { + if ($was) { if (preg_match('/\sRX bytes:(\d+)\s/i', $line, $ar_buf2)) { $dev->setRxBytes($ar_buf2[1]); } @@ -650,28 +1739,42 @@ class Linux extends OS if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2) - || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2) - || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) { - if ($ar_buf2[1] != $ar_buf2[2]) { - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); - } else { - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $line, $ar_buf2) + || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) { + $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1])); + if ($macaddr === '00-00-00-00-00-00') { // empty + $macaddr = ""; } - } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2) + } + } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) { + if ($ar_buf2[1] != $ar_buf2[2]) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2) || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2) - || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2) - || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $line, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); - + || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2) + || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $line, $ar_buf2) + || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $line, $ar_buf2)) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } } } } } - if (!$notwas) { + if ($was) { $dev->setErrors($errors); $dev->setDrops($drops); + if ($macaddr != "") { + $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():'')); + } + if ($speedinfo != "") { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } $this->sys->setNetDevices($dev); } } @@ -682,27 +1785,33 @@ class Linux extends OS * * @return void */ - protected function _memory() + protected function _memory($mbuf = null, $sbuf = null) { - if (CommonFunctions::rfts('/proc/meminfo', $mbuf)) { + if (($mbuf !== null) || CommonFunctions::rfts('/proc/meminfo', $mbuf)) { + $swaptotal = null; + $swapfree = null; $bufe = preg_split("/\n/", $mbuf, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe as $buf) { - if (preg_match('/^MemTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + if (preg_match('/^MemTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { $this->sys->setMemTotal($ar_buf[1] * 1024); - } elseif (preg_match('/^MemFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + } elseif (preg_match('/^MemFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { $this->sys->setMemFree($ar_buf[1] * 1024); - } elseif (preg_match('/^Cached:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + } elseif (preg_match('/^Cached:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { $this->sys->setMemCache($ar_buf[1] * 1024); - } elseif (preg_match('/^Buffers:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + } elseif (preg_match('/^Buffers:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { $this->sys->setMemBuffer($ar_buf[1] * 1024); + } elseif (preg_match('/^SwapTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { + $swaptotal = $ar_buf[1] * 1024; + } elseif (preg_match('/^SwapFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) { + $swapfree = $ar_buf[1] * 1024; } } $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); // values for splitting memory usage - if ($this->sys->getMemCache() !== null && $this->sys->getMemBuffer() !== null) { + if (($this->sys->getMemCache() !== null) && ($this->sys->getMemBuffer() !== null)) { $this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer()); } - if (CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) { + if (($sbuf !== null) || CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) { $swaps = preg_split("/\n/", $sbuf, -1, PREG_SPLIT_NO_EMPTY); unset($swaps[0]); foreach ($swaps as $swap) { @@ -715,6 +1824,13 @@ class Linux extends OS $dev->setFree($dev->getTotal() - $dev->getUsed()); $this->sys->setSwapDevices($dev); } + } elseif (($swaptotal !== null) && ($swapfree !== null) && ($swaptotal > 0)) { + $dev = new DiskDevice(); + $dev->setName("SWAP"); + $dev->setTotal($swaptotal); + $dev->setFree($swapfree); + $dev->setUsed($dev->getTotal() - $dev->getFree()); + $this->sys->setSwapDevices($dev); } } } @@ -724,7 +1840,7 @@ class Linux extends OS * * @return void */ - private function _filesystems() + protected function _filesystems() { $df_args = ""; $hideFstypes = array(); @@ -739,7 +1855,7 @@ class Linux extends OS $df_args .= "-x $Fstype "; } if ($df_args !== "") { - $df_args = trim($df_args); //trim spaces + $df_args = trim($df_args); // trim spaces $arrResult = Parser::df("-P $df_args 2>/dev/null"); } else { $arrResult = Parser::df("-P 2>/dev/null"); @@ -754,60 +1870,120 @@ class Linux extends OS * * @return void */ - private function _distro() + protected function _distro() { $this->sys->setDistribution("Linux"); - $list = @parse_ini_file(APP_ROOT."/data/distros.ini", true); + $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true); if (!$list) { return; } + $_ignore_lsb_release = false; + $_Distrib = ""; + $_DistribIcon = ""; // We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown - if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && (strlen(trim($distro_info)) > 0)) { - $distro_tmp = preg_split("/\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY); + if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && strlen($distro_info) > 0) { + $distro_tmp = preg_split("/\r?\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY); foreach ($distro_tmp as $info) { $info_tmp = preg_split('/:/', $info, 2); - if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "") && - isset($distro_tmp[1]) && !is_null($distro_tmp[1]) && (trim($distro_tmp[1]) != "")) { + if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "") && + isset($distro_tmp[1]) && ($distro_tmp[1] !== null) && (trim($distro_tmp[1]) != "")) { $distro[trim($info_tmp[0])] = trim($info_tmp[1]); } } + if (!isset($distro['Distributor ID']) && !isset($distro['Description'])) { // Systems like StartOS - if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "")) { - $this->sys->setDistribution(trim($distro_tmp[0])); + if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "")) { + $_Distrib = trim($distro_tmp[0]); if (preg_match('/^(\S+)\s*/', $distro_tmp[0], $id_buf) - && isset($list[trim($id_buf[1])]['Image'])) { - $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + && isset($list[strtolower(trim($id_buf[1]))]['Image'])) { + $_DistribIcon = $list[strtolower(trim($id_buf[1]))]['Image']; + // set ignore lsb_release for some distributions + if (isset($list[strtolower(trim($id_buf[1]))]['Test']) && ($list[strtolower(trim($id_buf[1]))]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true; } } } else { - if (isset($distro['Description']) - && preg_match('/^NAME=\s*(.+)\s*$/', $distro['Description'], $name_tmp)) { - $distro['Description'] = $name_tmp[1]; + if (isset($distro['Description'])) { + if (preg_match('/^NAME=\s*"?([^"\r\n]+)"?\s*$/', $distro['Description'], $name_tmp)) { + $distro['Description'] = trim($name_tmp[1]); + } elseif (($distro['Description']==="Rolling Release") && isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) { + $distro['Description'] = $distro['Distributor ID']." ".$distro['Description']; + } } if (isset($distro['Description']) && ($distro['Description'] != "n/a") - && !isset($distro['Distributor ID'])) { - $this->sys->setDistribution($distro['Description']); - } elseif (isset($distro['Description']) - && ($distro['Description'] != "n/a") - && isset($distro['Distributor ID']) - && ($distro['Distributor ID'] != "n/a") - && ($distro['Description'] != $distro['Distributor ID'])) { - $this->sys->setDistribution($distro['Description']); - } elseif (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) { - $this->sys->setDistribution($distro['Distributor ID']); - if (isset($distro['Release']) && ($distro['Release'] != "n/a")) { - $this->sys->setDistribution($this->sys->getDistribution()." ".$distro['Release']); + && (!isset($distro['Distributor ID']) + || (($distro['Distributor ID'] != "n/a") + && ($distro['Description'] != $distro['Distributor ID'])))) { + $_Distrib = $distro['Description']; + if (isset($distro['Release']) && ($distro['Release'] != "n/a") + && ($distro['Release'] != $distro['Description']) && strstr($distro['Release'], ".")){ + if (preg_match("/^(\d+)\.[0]+$/", $distro['Release'], $match_buf)) { + $tofind = $match_buf[1]; + } else { + $tofind = $distro['Release']; + } + if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", $distro['Description'])) { + $_Distrib .= " ".$distro['Release']; + } } - if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) { - $this->sys->setDistribution($this->sys->getDistribution()." (".$distro['Codename'].")"); + } elseif (isset($distro['Distributor ID'])) { + if ($distro['Distributor ID'] != "n/a") { + $_Distrib = $distro['Distributor ID']; + if (isset($distro['Release']) && ($distro['Release'] != "n/a")) { + $_Distrib .= " ".$distro['Release']; + } + if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) { + $_Distrib .= " (".$distro['Codename'].")"; + } + } elseif (isset($distro['Description']) && ($distro['Description'] != "n/a")) { + $_Distrib = $distro['Description']; } } - if (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a") && isset($list[$distro['Distributor ID']]['Image'])) { - $this->sys->setDistributionIcon($list[$distro['Distributor ID']]['Image']); + if (isset($distro['Distributor ID'])) { + $distrib = $distro['Distributor ID']; + $distrib2 = $distrib; + $distrib3 = $distrib; + if (isset($distro['Description'])) { + $distarr = preg_split("/\s/", $distro['Description'], -1, PREG_SPLIT_NO_EMPTY); + if (isset($distarr[0])) { + if ($distrib != "n/a") { + $distrib2 .= ' '.$distarr[0]; + } else { + $distrib2 = $distarr[0]; + } + } + if (isset($distarr[1])) { + if ($distrib != "n/a") { + $distrib3 .= ' '.$distarr[0].' '.$distarr[1]; + } else { + $distrib3 = $distarr[0].' '.$distarr[1]; + } + } + } + if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) { + $_DistribIcon = $list[strtolower($distrib3)]['Image']; + // set ignore lsb_release for some distributions + if (isset($list[strtolower($distrib3)]['Test']) && ($list[strtolower($distrib3)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true; + } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) { + $_DistribIcon = $list[strtolower($distrib2)]['Image']; + // set ignore lsb_release for some distributions + if (isset($list[strtolower($distrib2)]['Test']) && ($list[strtolower($distrib2)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true; + } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) { + $_DistribIcon = $list[strtolower($distrib)]['Image']; + // set ignore lsb_release for some distributions + if (isset($list[strtolower($distrib)]['Test']) && ($list[strtolower($distrib)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true; + } } } - } else { + } + + if (!$_ignore_lsb_release) { // don't ignore lsb_release + if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib)); + if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon); + } + + // if the distribution is still unknown + if ($this->sys->getDistribution() == "Linux") { /* default error handler */ if (function_exists('errorHandlerPsi')) { restore_error_handler(); @@ -819,25 +1995,56 @@ class Linux extends OS // Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release if (CommonFunctions::fileexists($filename="/etc/lsb-release") && CommonFunctions::rfts($filename, $buf, 0, 4096, false) - && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) { - if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf) + && (preg_match('/^DISTRIB_ID="?([^"\r\n]+)/m', $buf, $id_buf) || preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $id_buf))) { + if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf) && (trim($desc_buf[1])!=trim($id_buf[1]))) { - $this->sys->setDistribution(trim($desc_buf[1])); + if ($desc_buf[1]==="Rolling Release") { + $desc_buf[1] = $id_buf[1]." ".$desc_buf[1]; + } + $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1]))); + if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf) + && (trim($vers_buf[1])!=trim($desc_buf[1])) && strstr($vers_buf[1], ".")){ + if (preg_match("/^(\d+)\.[0]+$/", trim($vers_buf[1]), $match_buf)) { + $tofind = $match_buf[1]; + } else { + $tofind = trim($vers_buf[1]); + } + if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", trim($desc_buf[1]))) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } + } + $distrib = trim($id_buf[1]); + $distrib2 = $distrib; + $distrib3 = $distrib; + $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY); + if (isset($distarr[0])) { + $distrib2 .= ' '.$distarr[0]; + } + if (isset($distarr[1])) { + $distrib3 .= ' '.$distarr[0].' '.$distarr[1]; + } + if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']); + } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']); + } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']); + } } else { - if (isset($list[trim($id_buf[1])]['Name'])) { - $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); + if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) { + $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name'])); } else { $this->sys->setDistribution(trim($id_buf[1])); } - if (preg_match('/^DISTRIB_RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) { + if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf)) { $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); } - if (preg_match('/^DISTRIB_CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) { + if (preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) { $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); } - } - if (isset($list[trim($id_buf[1])]['Image'])) { - $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']); + } } } else { // otherwise find files specific for distribution foreach ($list as $section=>$distribution) { @@ -852,29 +2059,37 @@ class Linux extends OS } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="execute")) { if (!CommonFunctions::executeProgram($filename, '2>/dev/null', $buf, PSI_DEBUG)) { $buf = ""; + } elseif (preg_match('/^pve-manager\/([\d.]+)\//', $buf, $vers_buf)) { // Proxmox version + $buf = $vers_buf[1]; } } else { if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) { $buf = ""; + if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) { + break; + } } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) { - if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf) + if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf) && isset($list[trim($id_buf[1])]['Image'])) { $distro = $list[trim($id_buf[1])]; } } } + if (($buf !== null) && (trim($buf) !== "")) { + $buf = preg_replace("/ - Version:| Build:| Release| version| build/i", "", $buf); + } if (isset($distro['Image'])) { $this->sys->setDistributionIcon($distro['Image']); } if (isset($distribution['Name'])) { - if (is_null($buf) || (trim($buf) == "")) { + if (($buf === null) || (trim($buf) == "")) { $this->sys->setDistribution($distribution['Name']); } else { $this->sys->setDistribution($distribution['Name']." ".trim($buf)); } } else { - if (is_null($buf) || (trim($buf) == "")) { - $this->sys->setDistribution($section); + if (($buf === null) || (trim($buf) == "")) { + $this->sys->setDistribution(preg_replace('/linux/', 'Linux', ucwords($section))); } else { $this->sys->setDistribution(trim($buf)); } @@ -882,22 +2097,45 @@ class Linux extends OS if (isset($distribution['Files2'])) { foreach (preg_split("/;/", $distribution['Files2'], -1, PREG_SPLIT_NO_EMPTY) as $filename2) { if (CommonFunctions::fileexists($filename2) && CommonFunctions::rfts($filename2, $buf, 0, 4096, false)) { - if (preg_match('/^majorversion="?([^"\n]+)"?/m', $buf, $maj_buf) - && preg_match('/^minorversion="?([^"\n]+)"?/m', $buf, $min_buf)) { + if (preg_match('/^majorversion="?([^"\r\n]+)/m', $buf, $maj_buf) + && preg_match('/^minorversion="?([^"\r\n]+)/m', $buf, $min_buf)) { $distr2=$maj_buf[1].'.'.$min_buf[1]; - if (preg_match('/^buildphase="?([^"\n]+)"?/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) { + if (preg_match('/^buildphase="?([^"\r\n]+)/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) { $distr2.='.'.$pha_buf[1]; } - if (preg_match('/^buildnumber="?([^"\n]+)"?/m', $buf, $num_buf)) { + if (preg_match('/^buildnumber="?([^"\r\n]+)/m', $buf, $num_buf)) { $distr2.='-'.$num_buf[1]; } - if (preg_match('/^builddate="?([^"\n]+)"?/m', $buf, $dat_buf)) { + if (preg_match('/^builddate="?([^"\r\n]+)/m', $buf, $dat_buf)) { $distr2.=' ('.$dat_buf[1].')'; } $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2); + } elseif (preg_match('/^elive-codename:\s*([^\r\n]+)/m', $buf, $cod_buf) + && preg_match('/^elive-version:\s*([^\r\n]+)/m', $buf, $ver_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($cod_buf[1])." ".trim($ver_buf[1])); + } elseif (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/im', $buf, $vers_buf) + || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } elseif (preg_match('/^DISTRIB_ID=[\'"]?([^\'"\r\n]+)/m', $buf, $id_buf)) { + if (preg_match('/^DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf) + && (trim($desc_buf[1])!=trim($id_buf[1]))) { + $this->sys->setDistribution(trim($desc_buf[1])); + } else { + if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) { + $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name'])); + } else { + $this->sys->setDistribution(trim($id_buf[1])); + } + if (preg_match('/^RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf) || preg_match('/^DISTRIB_RELEASE=[\'"]?([^\'"\r\n]+)/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } + if (preg_match('/^CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); + } + } } else { $distr2=trim(substr($buf, 0, strpos($buf, "\n"))); - if (!is_null($distr2) && ($distr2 != "")) { + if (($distr2 !== null) && ($distr2 != "")) { $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2); } } @@ -913,116 +2151,171 @@ class Linux extends OS } // if the distribution is still unknown if ($this->sys->getDistribution() == "Linux") { - if (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS") - && CommonFunctions::rfts($filename, $buf, 0, 4096, false) - && preg_match('/^DISTRO_NAME=\'(.+)\'/m', $buf, $id_buf)) { - if (isset($list[trim($id_buf[1])]['Name'])) { - $dist = trim($list[trim($id_buf[1])]['Name']); - } else { - $dist = trim($id_buf[1]); - } - if (preg_match('/^DISTRO_VERSION=(.+)/m', $buf, $vers_buf)) { - $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1]))); - } else { - $this->sys->setDistribution($dist); - } - if (isset($list[trim($id_buf[1])]['Image'])) { - $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); - } else { - if (isset($list['Puppy']['Image'])) { - $this->sys->setDistributionIcon($list['Puppy']['Image']); - } - } - } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release") - && CommonFunctions::rfts($filename, $buf, 1, 4096, false) - && !is_null($buf) && (trim($buf) != "")) - || (CommonFunctions::fileexists($filename="/etc/system-release") - && CommonFunctions::rfts($filename, $buf, 1, 4096, false) - && !is_null($buf) && (trim($buf) != ""))) { - $this->sys->setDistribution(trim($buf)); - if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf) - && isset($list[trim($id_buf[1])]['Image'])) { - $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); - } - } elseif (CommonFunctions::fileexists($filename="/etc/solydxk/info") - && CommonFunctions::rfts($filename, $buf, 0, 4096, false) - && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) { - if (preg_match('/^DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf) - && (trim($desc_buf[1])!=trim($id_buf[1]))) { - $this->sys->setDistribution(trim($desc_buf[1])); - } else { - if (isset($list[trim($id_buf[1])]['Name'])) { - $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); - } else { - $this->sys->setDistribution(trim($id_buf[1])); - } - if (preg_match('/^RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) { - $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); - } - if (preg_match('/^CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) { - $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); - } - } - if (isset($list[trim($id_buf[1])]['Image'])) { - $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); - } else { - $this->sys->setDistributionIcon($list['SolydXK']['Image']); - } - } elseif (CommonFunctions::fileexists($filename="/etc/os-release") - && CommonFunctions::rfts($filename, $buf, 0, 4096, false) - && (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf) - || preg_match('/^NAME="?([^"\n]+)"?/m', $buf, $id_buf))) { - if (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)) { - if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)) { + if ($_ignore_lsb_release) { // if lsb_release was ignored + if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib)); + if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon); + } + } + // if the distribution is still unknown + if ($this->sys->getDistribution() == "Linux") { + if (((defined('PSI_EMU_PORT') && CommonFunctions::executeProgram('cat', '/etc/os-release', $buf, false)) + || (!defined('PSI_EMU_PORT') && CommonFunctions::fileexists($filename="/etc/os-release") && CommonFunctions::rfts($filename, $buf, 0, 4096, false))) + && (preg_match('/^TAILS_VERSION_ID="?([^"\r\n]+)/m', $buf, $tid_buf) || preg_match('/^NAME=["\']?([^"\'\r\n]+)/m', $buf, $id_buf) || preg_match('/^DISTRIB_ID=["\']?([^"\'\r\n]+)/m', $buf, $id_buf))) { + if (preg_match('/^TAILS_VERSION_ID="?([^"\r\n]+)/m', $buf, $tid_buf)) { + if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\r\n]+)/m', $buf, $desc_buf)) { $this->sys->setDistribution(trim($desc_buf[1])." ".trim($tid_buf[1])); } else { - if (isset($list['Tails']['Name'])) { - $this->sys->setDistribution(trim($list['Tails']['Name'])." ".trim($tid_buf[1])); + if (isset($list['tails']['Name'])) { + $this->sys->setDistribution(trim($list['tails']['Name'])." ".trim($tid_buf[1])); } else { $this->sys->setDistribution('Tails'." ".trim($tid_buf[1])); } } - $this->sys->setDistributionIcon($list['Tails']['Image']); + $this->sys->setDistributionIcon($list['tails']['Image']); } else { - if (preg_match('/^PRETTY_NAME="?([^"\n]+)"?/m', $buf, $desc_buf) - && !preg_match('/\$/', $desc_buf[1])) { //if is not defined by variable - $this->sys->setDistribution(trim($desc_buf[1])); - } else { - if (isset($list[trim($id_buf[1])]['Name'])) { - $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); + $addversion = false; + $distrib = trim($id_buf[1]); + if (preg_match('/^PRETTY_NAME=["\']?([^"\'\r\n]+)/m', $buf, $desc_buf) + && !preg_match('/\$/', $desc_buf[1]) // if is not defined by variable + && ($distrib!==trim($desc_buf[1]))) { + if (isset($list[strtolower($distrib)]['Name']) && !preg_match("/".$list[strtolower($distrib)]['Name']."/i", trim($desc_buf[1]))) { + $this->sys->setDistribution($list[strtolower($distrib)]['Name'] ." ". preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1]))); } else { - $this->sys->setDistribution(trim($id_buf[1])); + $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1]))); } - if (preg_match('/^VERSION="?([^"\n]+)"?/m', $buf, $vers_buf)) { - $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); - } elseif (preg_match('/^VERSION_ID="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $distrib2 = $distrib; + $distrib3 = $distrib; + $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY); + if (isset($distarr[0])) { + $distrib2 .= ' '.$distarr[0]; + } + if (isset($distarr[1])) { + $distrib3 .= ' '.$distarr[0].' '.$distarr[1]; + } + if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']); + if (count($distarr) == 2) { + $addversion = true; + } + } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']); + if (count($distarr) == 1) { + $addversion = true; + } + } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']); + } + } else { + if (isset($list[strtolower($distrib)]['Name'])) { + $this->sys->setDistribution(trim($list[strtolower($distrib)]['Name'])); + } else { + $this->sys->setDistribution($distrib); + } + if (isset($list[strtolower($distrib)]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']); + } + $addversion = true; + } + if ($addversion) { + if (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf) + || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf) + || preg_match('/^DISTRIB_RELEASE=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf) + || preg_match('/^IMAGE_VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) { $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); } + if (!strstr($this->sys->getDistribution(), "(") && (preg_match('/^VERSION_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf) + || preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf))) { + $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); + } } - if (isset($list[trim($id_buf[1])]['Image'])) { + } + } elseif (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match('/^DISTRO_NAME=["\']([^"\']+)/m', $buf, $id_buf)) { + if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) { + $dist = trim($list[strtolower(trim($id_buf[1]))]['Name']); + } else { + $dist = trim($id_buf[1]); + } + if (preg_match('/^DISTRO_VERSION=([^$#\n\r]+)/m', $buf, $vers_buf)) { + $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1]))); + } else { + $this->sys->setDistribution($dist); + } + if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) { + $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']); + } else { + if (isset($list['puppy']['Image'])) { + $this->sys->setDistributionIcon($list['puppy']['Image']); + if (!preg_match("/puppy/i", $dist = $this->sys->getDistribution())) { + $this->sys->setDistribution("Puppy ".$dist); + } + } + } + } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release") + && CommonFunctions::rfts($filename, $buf, 1, 4096, false) + && ($buf !== null) && (trim($buf) != "")) + || (CommonFunctions::fileexists($filename="/etc/system-release") + && CommonFunctions::rfts($filename, $buf, 1, 4096, false) + && ($buf !== null) && (trim($buf) != ""))) { + $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($buf))); + if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf) + && isset($list[trim($id_buf[1])]['Image'])) { $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); - } } } elseif (CommonFunctions::fileexists($filename="/etc/debian_version")) { if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) { $buf = ""; } - if (isset($list['Debian']['Image'])) { - $this->sys->setDistributionIcon($list['Debian']['Image']); + if (isset($list['debian']['Image'])) { + $this->sys->setDistributionIcon($list['debian']['Image']); } - if (isset($list['Debian']['Name'])) { - if (is_null($buf) || (trim($buf) == "")) { - $this->sys->setDistribution($list['Debian']['Name']); + if (isset($list['debian']['Name'])) { + if (($buf === null) || (trim($buf) == "")) { + $this->sys->setDistribution($list['debian']['Name']); } else { - $this->sys->setDistribution($list['Debian']['Name']." ".trim($buf)); + $this->sys->setDistribution($list['debian']['Name']." ".trim($buf)); } } else { - if (is_null($buf) || (trim($buf) == "")) { + if (($buf === null) || (trim($buf) == "")) { $this->sys->setDistribution('Debian'); } else { $this->sys->setDistribution(trim($buf)); } } + } elseif (CommonFunctions::fileexists($filename="/etc/slackware-version")) { + if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) { + $buf = ""; + } + if (isset($list['slackware']['Image'])) { + $this->sys->setDistributionIcon($list['slackware']['Image']); + } + if (isset($list['slackware']['Name'])) { + if (($buf === null) || (trim($buf) == "")) { + $this->sys->setDistribution($list['slackware']['Name']); + } else { + $this->sys->setDistribution($list['slackware']['Name']." ".trim($buf)); + } + } else { + if (($buf === null) || (trim($buf) == "")) { + $this->sys->setDistribution('Slackware'); + } else { + $this->sys->setDistribution(trim($buf)); + } + } + } elseif (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf) + && preg_match("/^Version\s*=\s*([\d\.]+)\r?\nBuild\sNumber\s*=\s*(\S+)/m", $buf, $ver_buf)) { + $buf = $ver_buf[1]."-".$ver_buf[2]; + if (isset($list['qts']['Image'])) { + $this->sys->setDistributionIcon($list['qts']['Image']); + } + if (isset($list['qts']['Name'])) { + $this->sys->setDistribution($list['qts']['Name']." ".trim($buf)); + } else { + $this->sys->setDistribution(trim($buf)); + } } } /* restore error level */ @@ -1041,14 +2334,13 @@ class Linux extends OS */ protected function _processes() { - $process = glob('/proc/*/status', GLOB_NOSORT); - if (($total = count($process)) > 0) { - + $process = CommonFunctions::findglob('/proc/*/status', GLOB_NOSORT); + if (is_array($process) && (($total = count($process)) > 0)) { $processes['*'] = 0; $buf = ""; for ($i = 0; $i < $total; $i++) { if (CommonFunctions::rfts($process[$i], $buf, 0, 4096, false)) { - $processes['*']++; //current total + $processes['*']++; // current total if (preg_match('/^State:\s+(\w)/m', $buf, $state)) { if (isset($processes[$state[1]])) { $processes[$state[1]]++; @@ -1059,7 +2351,7 @@ class Linux extends OS } } if (!($processes['*'] > 0)) { - $processes['*'] = $processes[' '] = $total; //all unknown + $processes['*'] = $processes[' '] = $total; // all unknown } $this->sys->setProcesses($processes); } @@ -1070,27 +2362,38 @@ class Linux extends OS * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_machine(); - $this->_uptime(); - $this->_users(); - $this->_cpuinfo(); - $this->_pci(); - $this->_ide(); - $this->_scsi(); - $this->_usb(); - $this->_i2c(); - $this->_network(); - $this->_memory(); - $this->_filesystems(); - $this->_loadavg(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_machine(); + $this->_cpuinfo(); + $this->_virtualizer(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_nvme(); + $this->_usb(); + $this->_i2c(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.Minix.inc.php b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php index 43fd4bf..154d861 100644 --- a/root/opt/phpsysinfo/includes/os/class.Minix.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php @@ -8,7 +8,7 @@ * @package PSI Minix OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Minix.inc.php 687 2012-09-06 20:54:49Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,26 +20,23 @@ * @package PSI Minix OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class Minix extends OS { + /** + * uptime command result. + */ + private $_uptime = null; + /** * content of the syslog * * @var array */ - private $_dmesg = array(); - - /** - * call parent constructor - */ - public function __construct() - { - parent::__construct(); - } + private $_dmesg = null; /** * read /var/log/messages, but only if we haven't already @@ -48,11 +45,13 @@ class Minix extends OS */ protected function readdmesg() { - if (count($this->_dmesg) === 0) { + if ($this->_dmesg === null) { if (CommonFunctions::rfts('/var/log/messages', $buf)) { - $parts = preg_split("/kernel: APIC/", $buf, -1, PREG_SPLIT_NO_EMPTY); -// $parts = preg_split("/ syslogd: restart\n/", $buf, -1, PREG_SPLIT_NO_EMPTY); + $blocks = preg_replace("/\s(kernel: MINIX \d+\.\d+\.\d+\.)/", '$1', $buf); + $parts = preg_split("//", $blocks, -1, PREG_SPLIT_NO_EMPTY); $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY); + } else { + $this->_dmesg = array(); } } @@ -62,7 +61,7 @@ class Minix extends OS /** * get the cpu information * - * @return array + * @return void */ protected function _cpuinfo() { @@ -73,31 +72,32 @@ class Minix extends OS $dev = new CpuDevice(); $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); foreach ($details as $detail) { - $arrBuff = preg_split('/\s+:\s+/', trim($detail)); - if (count($arrBuff) == 2) { - switch (strtolower($arrBuff[0])) { + if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) { + switch (strtolower(trim($arrBuff[1]))) { case 'model name': - $_n = $arrBuff[1]; + $_n = $arrBuff2; break; case 'cpu mhz': - $dev->setCpuSpeed($arrBuff[1]); + $dev->setCpuSpeed($arrBuff2); break; case 'cpu family': - $_f = $arrBuff[1]; + $_f = $arrBuff2; break; case 'model': - $_m = $arrBuff[1]; + $_m = $arrBuff2; break; case 'stepping': - $_s = $arrBuff[1]; + $_s = $arrBuff2; break; case 'flags': - if (preg_match("/ vmx/", $arrBuff[1])) { + if (preg_match("/ vmx/", $arrBuff2)) { $dev->setVirt("vmx"); - } elseif (preg_match("/ svm/", $arrBuff[1])) { + } elseif (preg_match("/ svm/", $arrBuff2)) { $dev->setVirt("svm"); } - break; + break; + case 'vendor_id': + $dev->setVendorId($arrBuff2); } } } @@ -129,6 +129,7 @@ class Minix extends OS { if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) { $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + $arrResults = array(); foreach ($arrLines as $strLine) { $arrParams = preg_split('/\s+/', trim($strLine), 4); if (count($arrParams) == 4) @@ -144,7 +145,7 @@ class Minix extends OS $this->sys->setPciDevices($dev); } } - if (!(isset($arrResults) && is_array($arrResults)) && is_array($results = Parser::lspci())) { + if (!(isset($arrResults) && is_array($arrResults)) && ($results = Parser::lspci())) { /* if access error: chmod 4755 /usr/bin/lspci */ foreach ($results as $dev) { $this->sys->setPciDevices($dev); @@ -159,12 +160,13 @@ class Minix extends OS */ private function _kernel() { - foreach ($this->readdmesg() as $line) { - if (preg_match('/kernel: MINIX (.*) \((.*)\)/', $line, $ar_buf)) { - $branch = $ar_buf[2]; - } - } if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) { + foreach ($this->readdmesg() as $line) { + if (preg_match('/kernel: MINIX (\d+\.\d+\.\d+)\. \((.+)\)/', $line, $ar_buf)) { + $branch = $ar_buf[2]; + break; + } + } if (isset($branch)) $this->sys->setKernel($ret.' ('.$branch.')'); else @@ -195,13 +197,13 @@ class Minix extends OS */ private function _uptime() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/up (\d+) day[s]?,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) { $min = $ar_buf[3]; $hours = $ar_buf[2]; $days = $ar_buf[1]; $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); - } elseif (preg_match("/up (\d+):(\d+),/", $buf, $ar_buf)) { + } elseif (preg_match("/up (\d+):(\d+),/", $this->_uptime, $ar_buf)) { $min = $ar_buf[2]; $hours = $ar_buf[1]; $this->sys->setUptime($hours * 3600 + $min * 60); @@ -217,27 +219,13 @@ class Minix extends OS */ private function _loadavg() { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) { + if (preg_match("/load averages: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) { $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); } } } - /** - * Number of Users - * - * @return void - */ - private function _users() - { - if (CommonFunctions::executeProgram('uptime', '', $buf)) { - if (preg_match("/, (.*) users, load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) { - $this->sys->setUsers($ar_buf[1]); - } - } - } - /** * Virtual Host Name * @@ -245,8 +233,8 @@ class Minix extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { $ip = gethostbyname($result); @@ -257,23 +245,6 @@ class Minix extends OS } } - /** - * IP of the Virtual Host Name - * - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } /** * Physical memory information and Swap Space information @@ -360,23 +331,32 @@ class Minix extends OS /** * get the information * - * @return Void + * @return void */ public function build() { - $this->error->addError("WARN", "The Minix version of phpSysInfo is a work in progress, some things currently don't work"); - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_loadavg(); - $this->_pci(); - $this->_cpuinfo(); - $this->_memory(); - $this->_filesystems(); - $this->_network(); - $this->_processes(); + $this->error->addWarning("The Minix version of phpSysInfo is a work in progress, some things currently don't work"); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_pci(); + $this->_cpuinfo(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php index d43e79c..7a802ec 100644 --- a/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php @@ -8,7 +8,7 @@ * @package PSI NetBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.NetBSD.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI NetBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -29,29 +29,17 @@ class NetBSD extends BSDCommon /** * define the regexp for log parser */ - public function __construct() + public function __construct($blockname = false) { - parent::__construct(); - $this->setCPURegExp1("^cpu(.*)\, (.*) MHz"); + parent::__construct($blockname); + //$this->setCPURegExp1("/^cpu(.*)\, (.*) MHz/"); $this->setCPURegExp2("/user = (.*), nice = (.*), sys = (.*), intr = (.*), idle = (.*)/"); - $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*"); - $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); - $this->setPCIRegExp1("/(.*) at pci[0-9] dev [0-9]* function [0-9]*: (.*)$/"); + $this->setSCSIRegExp1("/^(.*) at scsibus.*: <(.*)> .*/"); + $this->setSCSIRegExp2("/^(sd[0-9]+): (.*)([MG])B,/"); + $this->setPCIRegExp1("/(.*) at pci[0-9]+ dev [0-9]* function [0-9]*: (.*)$/"); $this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/"); } - /** - * UpTime - * time the system is running - * - * @return void - */ - private function _uptime() - { - $a = $this->grabkey('kern.boottime'); - $this->sys->setUptime(time() - $a); - } - /** * get network information * @@ -66,13 +54,39 @@ class NetBSD extends BSDCommon for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); - if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[3]) || ($ar_buf_n[3] === "0"))) { $dev = new NetDevice(); $dev->setName($ar_buf_b[0]); $dev->setTxBytes($ar_buf_b[4]); $dev->setRxBytes($ar_buf_b[3]); $dev->setDrops($ar_buf_n[8]); $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf_b[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { + $speedinfo = ""; + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+address:\s+(\S+)/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) { + if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") { + $unit = "G"; + } else { + $unit = "M"; + } + if (preg_match('/\s(\S+)-duplex/i', $buf2, $ar_buf3)) + $speedinfo = $ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]); + else + $speedinfo = $ar_buf2[1].$unit.'b/s'; + } + } + if ($speedinfo != "") $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } $this->sys->setNetDevices($dev); } } @@ -86,15 +100,34 @@ class NetBSD extends BSDCommon protected function ide() { foreach ($this->readdmesg() as $line) { - if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9] (.*): <(.*)>/', $line, $ar_buf)) { + if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9]+ (.*): <(.*)>/', $line, $ar_buf) + || preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9]+ /', $line, $ar_buf)) { $dev = new HWDevice(); - $dev->setName($ar_buf[1]); - // now loop again and find the capacity - foreach ($this->readdmesg() as $line2) { - if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { - $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049); - } elseif (preg_match("/^(".$ar_buf[1]."): (.*) MB, (.*), (.*), .*$/", $line2, $ar_buf_n)) { - $dev->setCapacity($ar_buf_n[2] * 2048); + if (isset($ar_buf[4])) { + $dev->setName($ar_buf[4]); + } else { + $dev->setName($ar_buf[1]); + // now loop again and find the name + foreach ($this->readdmesg() as $line2) { + if (preg_match("/^(".$ar_buf[1]."): <(.*)>$/", $line2, $ar_buf_n)) { + $dev->setName($ar_buf_n[2]); + break; + } + } + } + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + // now loop again and find the capacity + foreach ($this->readdmesg() as $line2) { + if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[4] * 1024 * 1024); + break; + } elseif (preg_match("/^(".$ar_buf[1]."): (.*) MB, (.*), (.*), .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[2] * 1024 * 1024); + break; + } elseif (preg_match("/^(".$ar_buf[1]."): (.*) GB, (.*), (.*), .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[2] * 1024 * 1024 * 1024); + break; + } } } $this->sys->setIdeDevices($dev); @@ -102,6 +135,77 @@ class NetBSD extends BSDCommon } } + /** + * CPU information + * + * @return void + */ + protected function cpuinfo() + { + $was = false; + $cpuarray = array(); + foreach ($this->readdmesg() as $line) { + if (preg_match("/^cpu([0-9])+: (.*)/", $line, $ar_buf)) { + $was = true; + $ar_buf[2] = trim($ar_buf[2]); + if (preg_match("/^(.+), ([\d\.]+) MHz/", $ar_buf[2], $ar_buf2)) { + if (($model = trim($ar_buf2[1])) !== "") { + $cpuarray[$ar_buf[1]]['model'] = $model; + } + if (($speed = trim($ar_buf2[2])) > 0) { + $cpuarray[$ar_buf[1]]['speed'] = $speed; + } + } elseif (preg_match("/^L2 cache (\d+) ([KM])B /", $ar_buf[2], $ar_buf2)) { + if ($ar_buf2[2]=="M") { + $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024*1024; + } elseif ($ar_buf2[2]=="K") { + $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024; + } + } + } elseif (!preg_match("/^cpu[0-9]+ /", $line) && $was) { + break; + } + } + + $ncpu = $this->grabkey('hw.ncpu'); + if (($ncpu === "") || !($ncpu >= 1)) { + $ncpu = 1; + } + $ncpu = max($ncpu, count($cpuarray)); + + $model = $this->grabkey('machdep.cpu_brand'); + $model2 = $this->grabkey('hw.model'); + if ($cpuspeed = $this->grabkey('machdep.tsc_freq')) { + $speed = round($cpuspeed / 1000000); + } else { + $speed = ""; + } + + for ($cpu = 0 ; $cpu < $ncpu ; $cpu++) { + $dev = new CpuDevice(); + + if (isset($cpuarray[$cpu]['model'])) { + $dev->setModel($cpuarray[$cpu]['model']); + } elseif ($model !== "") { + $dev->setModel($model); + } elseif ($model2 !== "") { + $dev->setModel($model2); + } + if (isset($cpuarray[$cpu]['speed'])) { + $dev->setCpuSpeed($cpuarray[$cpu]['speed']); + } elseif ($speed !== "") { + $dev->setCpuSpeed($speed); + } + if (isset($cpuarray[$cpu]['cache'])) { + $dev->setCache($cpuarray[$cpu]['cache']); + } + if (($ncpu == 1) && PSI_LOAD_BAR) { + $dev->setLoad($this->cpuusage()); + } + $this->sys->setCpus($dev); + } + } + /** * get icon name * @@ -146,14 +250,17 @@ class NetBSD extends BSDCommon * * @see BSDCommon::build() * - * @return Void + * @return void */ public function build() { parent::build(); - $this->_distroicon(); - $this->_network(); - $this->_uptime(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distroicon(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.OS.inc.php b/root/opt/phpsysinfo/includes/os/class.OS.inc.php index eadf92b..c509e32 100644 --- a/root/opt/phpsysinfo/includes/os/class.OS.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.OS.inc.php @@ -8,7 +8,7 @@ * @package PSI OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.OS.inc.php 699 2012-09-15 11:57:13Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,10 +28,17 @@ abstract class OS implements PSI_Interface_OS /** * object for error handling * - * @var Error + * @var PSI_Error */ protected $error; + /** + * block name + * + * @var string + */ + protected $blockname = false; + /** * @var System */ @@ -40,10 +47,12 @@ abstract class OS implements PSI_Interface_OS /** * build the global Error object */ - public function __construct() + public function __construct($blockname = false) { - $this->error = Error::singleton(); + $this->error = PSI_Error::singleton(); $this->sys = new System(); + $this->blockname = $blockname; + $this->sys->setOS(get_class($this)); } /** @@ -57,6 +66,7 @@ abstract class OS implements PSI_Interface_OS { return PSI_SYSTEM_CODEPAGE; } + /** * get os specific language * @@ -69,6 +79,180 @@ abstract class OS implements PSI_Interface_OS return PSI_SYSTEM_LANG; } + /** + * get block name + * + * @see PSI_Interface_OS::getBlockName() + * + * @return string + */ + public function getBlockName() + { + return $this->blockname; + } + + /** + * Number of Users + * + * @return void + */ + protected function _users() + { + if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) { + if (strlen($strBuf) > 0) { + $lines = preg_split('/\n/', $strBuf); + $this->sys->setUsers(count($lines)); + } + } elseif (CommonFunctions::executeProgram('uptime', '', $buf, PSI_DEBUG) && preg_match("/,\s+(\d+)\s+user[s]?,/", $buf, $ar_buf)) { + //} elseif (CommonFunctions::executeProgram('uptime', '', $buf) && preg_match("/,\s+(\d+)\s+user[s]?,\s+load average[s]?:\s+(.*),\s+(.*),\s+(.*)$/", $buf, $ar_buf)) { + $this->sys->setUsers($ar_buf[1]); + } else { + $processlist = CommonFunctions::findglob('/proc/*/cmdline', GLOB_NOSORT); + if (is_array($processlist) && (($total = count($processlist)) > 0)) { + $count = 0; + $buf = ""; + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($processlist[$i], $buf, 0, 4096, false)) { + $name = str_replace(chr(0), ' ', trim($buf)); + if (preg_match("/^-/", $name)) { + $count++; + } + } + } + if ($count > 0) { + $this->sys->setUsers($count); + } + } + } + } + + /** + * IP of the Host + * + * @return void + */ + protected function _ip() + { + if (PSI_USE_VHOST && !defined('PSI_EMU_HOSTNAME')) { + if ((CommonFunctions::readenv('SERVER_ADDR', $result) || CommonFunctions::readenv('LOCAL_ADDR', $result)) //is server address defined + && !strstr($result, '.') && strstr($result, ':')) { //is IPv6, quick version of preg_match('/\(([[0-9A-Fa-f\:]+)\)/', $result) + $dnsrec = dns_get_record($this->sys->getHostname(), DNS_AAAA); + if (isset($dnsrec[0]['ipv6'])) { //is DNS IPv6 record + $this->sys->setIp($dnsrec[0]['ipv6']); //from DNS (avoid IPv6 NAT translation) + } else { + $this->sys->setIp(preg_replace('/^::ffff:/i', '', $result)); //from SERVER_ADDR or LOCAL_ADDR + } + } else { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); //IPv4 only + } + } elseif (((PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) && (CommonFunctions::readenv('SERVER_ADDR', $result) || CommonFunctions::readenv('LOCAL_ADDR', $result))) { + $this->sys->setIp(preg_replace('/^::ffff:/i', '', $result)); + } else { + //$this->sys->setIp(gethostbyname($this->sys->getHostname())); + $hn = $this->sys->getHostname(); + $ghbn = gethostbyname($hn); + if (defined('PSI_EMU_HOSTNAME') && ($hn === $ghbn)) { + $this->sys->setIp(PSI_EMU_HOSTNAME); + } else { + $this->sys->setIp($ghbn); + } + } + } + + /** + * MEM information from dmidecode + * + * @return void + */ + protected function _dmimeminfo() + { + $dmimd = CommonFunctions::readdmimemdata(); + if (!empty($dmimd)) { + foreach ($dmimd as $mem) { + if (isset($mem['Size']) && preg_match('/^(\d+)\s(M|G)B$/', $mem['Size'], $size) && ($size[1] > 0)) { + $dev = new HWDevice(); + $name = ''; + if (isset($mem['Part Number']) && !preg_match("/^PartNum\d+$/", $part = $mem['Part Number']) && ($part != 'None') && ($part != 'N/A') && ($part != 'Not Specified') && ($part != 'NOT AVAILABLE')) { + $name = $part; + } + if (isset($mem['Locator']) && (($dloc = $mem['Locator']) != 'None') && ($dloc != 'N/A') && ($dloc != 'Not Specified')) { + if ($name != '') { + $name .= ' - '.$dloc; + } else { + $name = $dloc; + } + } + if (isset($mem['Bank Locator']) && (($bank = $mem['Bank Locator']) != 'None') && ($bank != 'N/A') && ($bank != 'Not Specified')) { + if ($name != '') { + $name .= ' in '.$bank; + } else { + $name = 'Physical Memory in '.$bank; + } + } + if ($name != '') { + $dev->setName(trim($name)); + } else { + $dev->setName('Physical Memory'); + } + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($mem['Manufacturer']) && !preg_match("/^([A-F\d]{4}|[A-F\d]{12}|[A-F\d]{16})$/", $manufacturer = $mem['Manufacturer']) && !preg_match("/^Manufacturer\d+$/", $manufacturer) && !preg_match("/^Mfg \d+$/", $manufacturer) && !preg_match("/^JEDEC ID:/", $manufacturer) && ($manufacturer != 'None') && ($manufacturer != 'N/A') && ($manufacturer != 'Not Specified') && ($manufacturer != 'UNKNOWN')) { + $dev->setManufacturer($manufacturer); + } + if ($size[2] == 'G') { + $dev->setCapacity($size[1]*1024*1024*1024); + } else { + $dev->setCapacity($size[1]*1024*1024); + } + $memtype = ''; + if (isset($mem['Type']) && (($type = $mem['Type']) != 'None') && ($type != 'N/A') && ($type != 'Not Specified') && ($type != 'Other') && ($type != 'Unknown') && ($type != '')) { + if (isset($mem['Speed']) && preg_match('/^(\d+)\s(MHz|MT\/s)/', $mem['Speed'], $speed) && ($speed[1] > 0) && (preg_match('/^(DDR\d*)(.*)/', $type, $dr) || preg_match('/^(SDR)AM(.*)/', $type, $dr))) { + if (isset($mem['Minimum Voltage']) && isset($mem['Maximum Voltage']) && + preg_match('/^([\d\.]+)\sV$/', $mem['Minimum Voltage'], $minv) && preg_match('/^([\d\.]+)\sV$/', $mem['Maximum Voltage'], $maxv) && + ($minv[1] > 0) && ($maxv[1] >0) && ($minv[1] < $maxv[1])) { + $lv = 'L'; + } else { + $lv = ''; + } + if (isset($dr[2])) { + $memtype = $dr[1].$lv.'-'.$speed[1].' '.$dr[2]; + } else { + $memtype = $dr[1].$lv.'-'.$speed[1]; + } + } else { + $memtype = $type; + } + } + if (isset($mem['Form Factor']) && (($form = $mem['Form Factor']) != 'None') && ($form != 'N/A') && ($form != 'Not Specified') && ($form != 'Other') && ($form != 'Unknown') && !preg_match('/ '.$form.'$/', $memtype)) { + $memtype .= ' '.$form; + } + if (isset($mem['Data Width']) && isset($mem['Total Width']) && + preg_match('/^(\d+)\sbits$/', $mem['Data Width'], $dataw) && preg_match('/^(\d+)\sbits$/', $mem['Total Width'], $totalw) && + ($dataw[1] > 0) && ($totalw[1] >0) && ($dataw[1] < $totalw[1])) { + $memtype .= ' ECC'; + } + if (isset($mem['Type Detail']) && preg_match('/Registered/', $mem['Type Detail'])) { + $memtype .= ' REG'; + } + if (($memtype = trim($memtype)) != '') { + $dev->setProduct($memtype); + } + if (isset($mem['Configured Clock Speed']) && preg_match('/^(\d+)\s(MHz|MT\/s)$/', $mem['Configured Clock Speed'], $clock) && ($clock[1] > 0)) { + $dev->setSpeed($clock[1]); + } + if (isset($mem['Configured Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Configured Voltage'], $voltage) && ($voltage[1] > 0)) { + $dev->setVoltage($voltage[1]); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && + isset($mem['Serial Number']) && !preg_match("/^SerNum\d+$/", $serial = $mem['Serial Number']) && ($serial != 'None') && ($serial != 'Not Specified')) { + $dev->setSerial($serial); + } + } + $this->sys->setMemDevices($dev); + } + } + } + } + /** * get the filled or unfilled (with default values) System object * @@ -79,6 +263,12 @@ abstract class OS implements PSI_Interface_OS final public function getSys() { $this->build(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_ip(); + } + if ((!$this->blockname || $this->blockname==='hardware') && (PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) { + $this->_dmimeminfo(); + } return $this->sys; } diff --git a/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php index e642d42..9568f09 100644 --- a/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php @@ -8,7 +8,7 @@ * @package PSI OpenBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.OpenBSD.inc.php 621 2012-07-29 18:49:04Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @package PSI OpenBSD OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -29,29 +29,17 @@ class OpenBSD extends BSDCommon /** * define the regexp for log parser */ - public function __construct() + public function __construct($blockname = false) { - parent::__construct(); - $this->setCPURegExp1("^cpu(.*) (.*) MHz"); + parent::__construct($blockname); +// $this->setCPURegExp1("/^cpu(.*) (.*) MHz/"); $this->setCPURegExp2("/(.*),(.*),(.*),(.*),(.*)/"); - $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*"); - $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); - $this->setPCIRegExp1("/(.*) at pci[0-9] .* \"(.*)\"/"); + $this->setSCSIRegExp1("/^(.*) at scsibus.*: <(.*)> .*/"); + $this->setSCSIRegExp2("/^(sd[0-9]+): (.*)MB,/"); + $this->setPCIRegExp1("/(.*) at pci[0-9]+ .* \"(.*)\"/"); $this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/"); } - /** - * UpTime - * time the system is running - * - * @return void - */ - private function _uptime() - { - $a = $this->grabkey('kern.boottime'); - $this->sys->setUptime(time() - $a); - } - /** * get network information * @@ -66,13 +54,43 @@ class OpenBSD extends BSDCommon for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); - if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[3]) || ($ar_buf_n[3] === "0"))) { $dev = new NetDevice(); $dev->setName($ar_buf_b[0]); $dev->setTxBytes($ar_buf_b[4]); $dev->setRxBytes($ar_buf_b[3]); - $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); - $dev->setDrops($ar_buf_n[8]); + if (sizeof($ar_buf_n) == 9) { + $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); + $dev->setDrops($ar_buf_n[8]); + } elseif (sizeof($ar_buf_n) == 8) { + $dev->setDrops($ar_buf_n[4] + $ar_buf_n[6]); + } + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf_b[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { + $speedinfo = ""; + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+lladdr\s+(\S+)/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); + } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) { + if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") { + $unit = "G"; + } else { + $unit = "M"; + } + if (preg_match('/\s(\S+)-duplex/i', $buf2, $ar_buf3)) + $speedinfo = $ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]); + else + $speedinfo = $ar_buf2[1].$unit.'b/s'; + } + } + if ($speedinfo != "") $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo); + } $this->sys->setNetDevices($dev); } } @@ -86,13 +104,16 @@ class OpenBSD extends BSDCommon protected function ide() { foreach ($this->readdmesg() as $line) { - if (preg_match('/^(.*) at pciide[0-9] (.*): <(.*)>/', $line, $ar_buf)) { + if (preg_match('/^(.*) at pciide[0-9]+ (.*): <(.*)>/', $line, $ar_buf)) { $dev = new HWDevice(); - $dev->setName($ar_buf[0]); - // now loop again and find the capacity - foreach ($this->readdmesg() as $line2) { - if (preg_match("/^(".$ar_buf[0]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { - $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049); + $dev->setName($ar_buf[3]); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + // now loop again and find the capacity + foreach ($this->readdmesg() as $line2) { + if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[4] * 1024 * 1024); + break; + } } } $this->sys->setIdeDevices($dev); @@ -107,13 +128,81 @@ class OpenBSD extends BSDCommon */ protected function cpuinfo() { - $dev = new CpuDevice(); - $dev->setModel($this->grabkey('hw.model')); - $dev->setCpuSpeed($this->grabkey('hw.cpuspeed')); + $was = false; + $cpuarray = array(); + foreach ($this->readdmesg() as $line) { + if (preg_match("/^cpu([0-9])+: (.*)/", $line, $ar_buf)) { + $was = true; + $ar_buf[2] = trim($ar_buf[2]); + if (preg_match("/^(.+), ([\d\.]+) MHz/", $ar_buf[2], $ar_buf2)) { + if (($model = trim($ar_buf2[1])) !== "") { + $cpuarray[$ar_buf[1]]['model'] = $model; + } + if (($speed = trim($ar_buf2[2])) > 0) { + $cpuarray[$ar_buf[1]]['speed'] = $speed; + } + } elseif (preg_match("/(\d+)([KM])B \S+ \S+ L[23] cache$/", $ar_buf[2], $ar_buf2)) { + if ($ar_buf2[2]=="M") { + $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024*1024; + } elseif ($ar_buf2[2]=="K") { + $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024; + } + } else { + $feats = preg_split("/,/", strtolower($ar_buf[2]), -1, PREG_SPLIT_NO_EMPTY); + foreach ($feats as $feat) { + if (($feat=="vmx") || ($feat=="svm")) { + $cpuarray[$ar_buf[1]]['virt'] = $feat; + } elseif ($feat=="hv") { + if (!isset($cpuarray[$ar_buf[1]]['virt'])) { + $cpuarray[$ar_buf[1]]['virt'] = 'hypervisor'; + } + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $this->sys->setVirtualizer("hypervisor", false); + } + } + } + } + } elseif (!preg_match("/^cpu[0-9]+|^mtrr: |^acpitimer[0-9]+: /", $line) && $was) { + break; + } + } + $ncpu = $this->grabkey('hw.ncpu'); - if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + if (($ncpu === "") || !($ncpu >= 1)) { $ncpu = 1; - for ($ncpu ; $ncpu > 0 ; $ncpu--) { + } + $ncpu = max($ncpu, count($cpuarray)); + + $model = $this->grabkey('hw.model'); + $speed = $this->grabkey('hw.cpuspeed'); + $vendor = $this->grabkey('machdep.cpuvendor'); + + for ($cpu = 0 ; $cpu < $ncpu ; $cpu++) { + $dev = new CpuDevice(); + + if (isset($cpuarray[$cpu]['model'])) { + $dev->setModel($cpuarray[$cpu]['model']); + } elseif ($model !== "") { + $dev->setModel($model); + } + if (isset($cpuarray[$cpu]['speed'])) { + $dev->setCpuSpeed($cpuarray[$cpu]['speed']); + } elseif ($speed !== "") { + $dev->setCpuSpeed($speed); + } + if (isset($cpuarray[$cpu]['cache'])) { + $dev->setCache($cpuarray[$cpu]['cache']); + } + if (isset($cpuarray[$cpu]['virt'])) { + $dev->setVirt($cpuarray[$cpu]['virt']); + } + if ($vendor !== "") { + $dev->setVendorId($vendor); + } + if (($ncpu == 1) && PSI_LOAD_BAR) { + $dev->setLoad($this->cpuusage()); + } + $this->sys->setCpus($dev); } } @@ -161,14 +250,17 @@ class OpenBSD extends BSDCommon * * @see BSDCommon::build() * - * @return Void + * @return void */ public function build() { parent::build(); - $this->_distroicon(); - $this->_network(); - $this->_uptime(); - $this->_processes(); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distroicon(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.QNX.inc.php b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php index 203dae3..3b6fd23 100644 --- a/root/opt/phpsysinfo/includes/os/class.QNX.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php @@ -8,7 +8,7 @@ * @package PSI QNX OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.QNX.inc.php 687 2012-09-06 20:54:49Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,31 +20,16 @@ * @package PSI QNX OS class * @author Mieczyslaw Nalewaj * @copyright 2012 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class QNX extends OS { - /** - * content of the syslog - * - * @var array - */ - private $_dmesg = array(); - - /** - * call parent constructor - */ - public function __construct() - { - parent::__construct(); - } - /** * get the cpu information * - * @return array + * @return void */ protected function _cpuinfo() { @@ -103,23 +88,9 @@ class QNX extends OS if (CommonFunctions::executeProgram('pidin', 'info', $buf) && preg_match('/^.* BootTime:(.*)/', $buf, $bstart) && CommonFunctions::executeProgram('date', '', $bstop)) { - /* default error handler */ - if (function_exists('errorHandlerPsi')) { - restore_error_handler(); - } - /* fatal errors only */ - $old_err_rep = error_reporting(); - error_reporting(E_ERROR); - + date_default_timezone_set('UTC'); $uptime = strtotime($bstop)-strtotime($bstart[1]); if ($uptime > 0) $this->sys->setUptime($uptime); - - /* restore error level */ - error_reporting($old_err_rep); - /* restore error handler */ - if (function_exists('errorHandlerPsi')) { - set_error_handler('errorHandlerPsi'); - } } } @@ -128,7 +99,7 @@ class QNX extends OS * * @return void */ - private function _users() + protected function _users() { $this->sys->setUsers(1); } @@ -140,8 +111,8 @@ class QNX extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { $ip = gethostbyname($result); @@ -152,24 +123,6 @@ class QNX extends OS } } - /** - * IP of the Virtual Host Name - * - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * Physical memory information and Swap Space information * @@ -207,20 +160,21 @@ class QNX extends OS { if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); - $notwas = true; + $was = false; + $dev = null; foreach ($lines as $line) { if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) { - if (!$notwas) { + if ($was) { $this->sys->setNetDevices($dev); } $dev = new NetDevice(); $dev->setName($ar_buf[1]); - $notwas = false; + $was = true; } else { - if (!$notwas) { + if ($was) { if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { if (preg_match('/^\s+address:\s*(\S+)/i', $line, $ar_buf2)) { - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2)) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); @@ -228,7 +182,7 @@ class QNX extends OS } } } - if (!$notwas) { + if ($was) { $this->sys->setNetDevices($dev); } } @@ -237,20 +191,29 @@ class QNX extends OS /** * get the information * - * @return Void + * @return void */ public function build() { - $this->error->addError("WARN", "The QNX version of phpSysInfo is a work in progress, some things currently don't work"); - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_cpuinfo(); - $this->_memory(); - $this->_filesystems(); - $this->_network(); + $this->error->addWarning("The QNX version of phpSysInfo is a work in progress, some things currently don't work"); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_cpuinfo(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.SSH.inc.php b/root/opt/phpsysinfo/includes/os/class.SSH.inc.php new file mode 100644 index 0000000..b8e8ea4 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.SSH.inc.php @@ -0,0 +1,857 @@ + + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version SVN: $Id: class.SSH.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * SSH sysinfo class + * get all the required information from SSH + * + * @category PHP + * @package PSI SSH class + * @author Mieczyslaw Nalewaj + * @copyright 2022 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SSH extends GNU +{ + /** + * content of the system status + * + * @var string + */ + private $_sysstatus = null; + + /** + * content of the system performance status + * + * @var string + */ + private $_sysperformance = null; + + /** + * content of the sys ver systeminfo + * + * @var string + */ + private $_sysversysteminfo = null; + + /** + * content of the show status + * + * @var string + */ + private $_showstatus = null; + + /** + * OS type + * + * @var string + */ + private $_ostype = null; + + /** + * check system type + */ + public function __construct($blockname = false) + { + parent::__construct($blockname); + $this->_ostype = $this->sys->getOS(); + switch ($this->_ostype) { + case '4.2BSD': + case 'AIX': + case 'Darwin': + case 'DragonFly': + case 'FreeBSD': + case 'HI-UX/MPP': + case 'Haiku': + case 'Minix': + case 'NetBSD': + case 'OpenBSD': + case 'QNX': + case 'SunOS': + $this->error->addError("__construct()", "OS ".$this->_ostype. " is not supported via SSH"); + break; + case 'GNU': + case 'Linux': + break; + case 'SSH': + $this->error->addError("__construct()", "SSH connection error"); + break; + default: + if ($this->getSystemStatus() !== '') { + $this->_ostype = 'FortiOS'; + $this->sys->setOS('Linux'); + } elseif ($this->getSysVerSysteminfo() !== '') { + $this->_ostype = 'DrayOS'; + $this->sys->setOS('DrayOS'); + } + } + } + + /** + * get os specific encoding + * + * @see PSI_Interface_OS::getEncoding() + * + * @return string + */ + public function getEncoding() + { +// if (($this->_ostype === 'FortiOS') || ($this->_ostype === 'DrayOS') || ($this->_ostype === 'SSH')) { +// return 'UTF-8'; +// } + //return null; + } + + /** + * get os specific language + * + * @see PSI_Interface_OS::getLanguage() + * + * @return string + */ + public function getLanguage() + { + //return null; + } + + private function getSystemStatus() + { + if ($this->_sysstatus === null) { + if (CommonFunctions::executeProgram('get', 'system status', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $this->_sysstatus = substr($resulte, strlen($resulto[1][0])); + } else { + $this->_sysstatus = ''; + } + } + + return $this->_sysstatus; + } + + private function getSystemPerformance() + { + if ($this->_sysperformance === null) { + if (CommonFunctions::executeProgram('get', 'system performance status', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $this->_sysperformance = substr($resulte, strlen($resulto[1][0])); + } else { + $this->_sysperformance = ''; + } + } + + return $this->_sysperformance; + } + + private function getSysVerSysteminfo() + { + if ($this->_sysversysteminfo === null) { + if (CommonFunctions::executeProgram('sys', 'ver systeminfo', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "") + && preg_match('/([\s\S]+> sys ver systeminfo)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $this->_sysversysteminfo = substr($resulte, strlen($resulto[1][0])); + } else { + $this->_sysversysteminfo = ''; + } + } + + return $this->_sysversysteminfo; + } + + private function getShowStatus() + { + if ($this->_showstatus === null) { + if (CommonFunctions::executeProgram('show', 'status', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "") + && preg_match('/([\s\S]+> show status)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $this->_showstatus = substr($resulte, strlen($resulto[1][0])); + } else { + $this->_showstatus = ''; + } + } + + return $this->_showstatus; + } + /** + * Physical memory information and Swap Space information + * + * @return void + */ + protected function _memory($mbuf = null, $sbuf = null) + { + switch ($this->_ostype) { + case 'FortiOS': + if (CommonFunctions::executeProgram('get', 'hardware memory', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + parent::_memory(substr($resulte, strlen($resulto[1][0]))); + } + break; + case 'DrayOS': + if (($sysstat = $this->getSysVerSysteminfo()) !== '') { + $machine= ''; + if (preg_match("/ Total memory usage : \d+ % \((\d+)K\/(\d+)K\)/", $sysstat, $buf)) { + $this->sys->setMemTotal($buf[2]*1024); + $this->sys->setMemUsed($buf[1]*1024); + $this->sys->setMemFree(($buf[2]-$buf[1])*1024); + } + } + break; + case 'GNU': + case 'Linux': + if (!CommonFunctions::executeProgram('cat', '/proc/meminfo', $mbuf, false) || ($mbuf === "")) { + $mbuf = null; + } + if (!CommonFunctions::executeProgram('cat', '/proc/swaps', $sbuf, false) || ($sbuf === "")) { + $sbuf = null; + } + if (($mbuf !== null) || ($sbuf !== null)) { + parent::_memory($mbuf, $sbuf); + } + } + + } + + /** + * USB devices + * + * @return void + */ + protected function _usb($bufu = null) + { + switch ($this->_ostype) { + case 'FortiOS': + $bufr = ''; + if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/bus/usb/devices', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $resulti = substr($resulte, strlen($resulto[1][0])); + if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) { + $bufr = substr($resulti, 0, $resulto[1][1]); + if (count(preg_split('/\n/', $bufr, -1, PREG_SPLIT_NO_EMPTY)) >= 2) { + parent::_usb($bufr); + } + } + } + break; + case 'GNU': + case 'Linux': + parent::_usb(); + } + } + + /** + * Network devices + * includes also rx/tx bytes + * + * @return void + */ + protected function _network($bufr = null) + { + switch ($this->_ostype) { + case 'FortiOS': + $bufr = ''; + if (CommonFunctions::executeProgram('fnsysctl', 'ifconfig', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $resulti = substr($resulte, strlen($resulto[1][0])); + if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) { + $bufr = substr($resulti, 0, $resulto[1][1]); + if (count(preg_split('/\n/', $bufr, -1, PREG_SPLIT_NO_EMPTY)) < 2) { + $bufr = ''; + } + } + } + + if ($bufr !== '') { + parent::_network($bufr); + } else { + $netdevs = array(); + if (CommonFunctions::executeProgram('diagnose', 'ip address list', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $strBuf = substr($resulte, strlen($resulto[1][0])); + $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) if (preg_match('/^IP=(\S+)->.+ devname=(\S+)$/', $line, $buf)) { + if (!isset($netdevs[$buf[2]])) { + $netdevs[$buf[2]] = $buf[1]; + } else { + $netdevs[$buf[2]] .= ';'.$buf[1]; + } + } + } + if (CommonFunctions::executeProgram('diagnose', 'ipv6 address list', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $strBuf = substr($resulte, strlen($resulto[1][0])); + $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) if (preg_match('/ devname=(\S+) .+ addr=(\S+)/', $line, $buf)) { + if (!preg_match('/^fe80::/i', $buf[2])) { + if (!isset($netdevs[$buf[1]])) { + $netdevs[$buf[1]] = $buf[2]; + } else { + $netdevs[$buf[1]] .= ';'.$buf[2]; + } + } + } + } + + foreach ($netdevs as $netname=>$netinfo) { + if (!preg_match('/^vsys_/i', $netname)) { + $dev = new NetDevice(); +// if ($netname === 'root') { +// $dev->setName('lo'); +// } else { + $dev->setName($netname); +// } + $this->sys->setNetDevices($dev); + $dev->setInfo($netinfo); + } + } + } + break; + case 'DrayOS': + $macarray = array(); + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR)) { + if (CommonFunctions::executeProgram('sys', 'iface', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "") + && preg_match('/([\s\S]+> sys iface)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $lines = preg_split("/\n/", substr($resulte, strlen($resulto[1][0])), -1, PREG_SPLIT_NO_EMPTY); + $ipaddr = 'LAN'; + foreach ($lines as $line) { + if (preg_match("/^IP Address:\s+([\d\.]+)\s/", trim($line), $ar_buf)) { + if ($ipaddr === false) { + $ipaddr = $ar_buf[1]; + } + } elseif (preg_match("/^MAC:\s+([\d\-A-F]+)/", trim($line), $ar_buf)) { + if ($ipaddr !== '0.0.0.0') { + $macarray[$ipaddr] = $ar_buf[1]; + } + $ipaddr = false; + } + } + } + } + + $lantxrate = false; + $lanrxrate = false; + if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) { + if ((($bufr = $this->getShowStatus()) !== '') && preg_match('/IP Address:[\d\.]+[ ]+Tx Rate:(\d+)[ ]+Rx Rate:(\d+)/m', $bufr, $ar_buf)) { + $lantxrate = $ar_buf[1]; + $lanrxrate = $ar_buf[2]; + } + } + + $notwaslan = true; + if (CommonFunctions::executeProgram('show', 'lan', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "") + && preg_match('/([\s\S]+> show lan)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $lines = preg_split("/\n/", substr($resulte, strlen($resulto[1][0])), -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + if (preg_match("/^\[V\](\S+)\s+([\d\.]+)\s/", trim($line), $ar_buf)) { + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + $dev->setInfo($ar_buf[2]); + if (isset($macarray['LAN'])) { + $dev->setInfo($macarray['LAN'].';'.$ar_buf[2]); + } else { + $dev->setInfo($ar_buf[2]); + } + } + if ($lantxrate !== false) { + $dev->setTxRate($lantxrate); + } + if ($lanrxrate !== false) { + $dev->setRxRate($lanrxrate); + } + $this->sys->setNetDevices($dev); + if (preg_match('/^LAN/', $ar_buf[1])) { + $notwaslan = false; + } + } + } + } + if (($bufr = $this->getShowStatus()) !== '') { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $last = false; + $dev = null; + foreach ($lines as $line) { + if (preg_match("/^(.+) Status/", trim($line), $ar_buf)) { + if (($last !== false) && (($last !== 'LAN') || $notwaslan)) { + $this->sys->setNetDevices($dev); + } + $dev = new NetDevice(); + $last = preg_replace('/\s+/', '', $ar_buf[1]); + $dev->setName($last); + } else { + if ($last !== false) { + if (preg_match('/ IP:([\d\.]+)[ ]+GW/', $line, $ar_buf) || preg_match('/IP Address:([\d\.]+)[ ]+Tx/', $line, $ar_buf)) { + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if ($last === 'LAN') { + if (isset($macarray['LAN'])) { + $dev->setInfo($macarray['LAN'].';'.$ar_buf[1]); + } + if ($lantxrate !== false) { + $dev->setTxRate($lantxrate); + } + if ($lanrxrate !== false) { + $dev->setRxRate($lanrxrate); + } + } elseif (isset($macarray[$ar_buf[1]])) { + $dev->setInfo($macarray[$ar_buf[1]].';'.$ar_buf[1]); + } else { + $dev->setInfo($ar_buf[1]); + } + } + } elseif (preg_match('/TX Packets:\d+[ ]+TX Rate\(bps\):(\d+)[ ]+RX Packets:\d+[ ]+RX Rate\(bps\):(\d+)/', $line, $ar_buf)) { + if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) { + $dev->setTxRate($ar_buf[1]); + $dev->setRxRate($ar_buf[2]); + } + } + } + } + } + if (($last !== false) && (($last !== 'LAN') || $notwaslan)) { + $this->sys->setNetDevices($dev); + } + } + break; + case 'GNU': + case 'Linux': + parent::_network(); + } + } + + /** + * CPU information + * All of the tags here are highly architecture dependant. + * + * @return void + */ + protected function _cpuinfo($bufr = null) + { + switch ($this->_ostype) { + case 'FortiOS': + if (CommonFunctions::executeProgram('get', 'hardware cpu', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + parent::_cpuinfo(substr($resulte, strlen($resulto[1][0]))); + } + break; + case 'DrayOS': + if (preg_match_all("/CPU(\d+) speed:[ ]*(\d+) MHz/m", $sysinfo = $this->getSysVerSysteminfo(), $bufarr)) { + foreach ($bufarr[1] as $index=>$nr) { + $dev = new CpuDevice(); + $dev->setModel('CPU'.$nr); + $dev->setCpuSpeed($bufarr[2][$index]); + if (PSI_LOAD_BAR) { + $dev->setLoad($this->_parseProcStat('cpu'.$nr)); + } + $this->sys->setCpus($dev); + } +// $this->_cpu_loads['cpu'] = $buf[1]; +// if (preg_match("/CPU1 speed/", $sysinfo)) { +// $this->_cpu_loads['cpu0'] = $buf[1]; +// } + } + break; + case 'GNU': + case 'Linux': + if (CommonFunctions::executeProgram('cat', '/proc/cpuinfo', $resulte, false) && ($resulte !== "")) { + parent::_cpuinfo($resulte); + } + } + } + + /** + * Machine + * + * @return void + */ + protected function _machine() + { + switch ($this->_ostype) { + case 'FortiOS': + if (($sysstat = $this->getSystemStatus()) !== '') { + $machine= ''; + if (preg_match("/^Version: (\S+) v/", $sysstat, $buf)) { + $machine = $buf[1]; + } + if (preg_match("/\nSystem Part-Number: (\S+)\n/", $sysstat, $buf)) { + $machine .= ' '.$buf[1]; + } + if (preg_match("/\nBIOS version: (\S+)\n/", $sysstat, $buf)) { + if (trim($machine) !== '') { + $machine .= ', BIOS '.$buf[1]; + } else { + $machine = 'BIOS '.$buf[1]; + } + } + $machine = trim($machine); + + if ($machine !== '') { + $this->sys->setMachine($machine); + } + } + break; + case 'DrayOS': + if (($sysstat = $this->getSysVerSysteminfo()) !== '') { + $machine= ''; + if (preg_match("/[\r\n]Router Model: (\S+) /", $sysstat, $buf)) { + $machine = $buf[1]; + } + if (preg_match("/[\r\n]Revision: (.+)[\r\n]/", $sysstat, $buf)) { + $machine .= ' '.$buf[1]; + } + $machine = trim($machine); + + if ($machine !== '') { + $this->sys->setMachine($machine); + } + } + break; + + case 'GNU': + case 'Linux': + parent::_machine(); + } + } + + /** + * Hostname + * + * @return void + */ + protected function _hostname() + { + switch ($this->_ostype) { + case 'FortiOS': +// $hostname = PSI_EMU_HOSTNAME; + if (preg_match("/\nHostname: ([^\n]+)\n/", $this->getSystemStatus(), $buf)) { + $this->sys->setHostname(trim($buf[1])); +// $hostname = trim($buf[1]); + } + +// $ip = gethostbyname($hostname); +// if ($ip != $hostname) { +// $this->sys->setHostname(gethostbyaddr($ip)); +// } else { +// $this->sys->setHostname($hostname); +// } + break; + case 'DrayOS': + if (preg_match("/[\r\n]Router Name: ([^\n\r]+)[\r\n]/", $this->getSysVerSysteminfo(), $buf)) { + $this->sys->setHostname(trim($buf[1])); + } + break; + case 'GNU': + case 'Linux': + parent::_hostname(); + } + + } + + /** + * filesystem information + * + * @return void + */ + protected function _filesystems() + { + switch ($this->_ostype) { + case 'FortiOS': + if (CommonFunctions::executeProgram('fnsysctl', 'df -k', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $resulti = substr($resulte, $resulto[1][1]); + $df = preg_split("/\n/", $resulti, -1, PREG_SPLIT_NO_EMPTY); + foreach ($df as $df_line) { + $df_buf1 = preg_split("/(\%\s)/", $df_line, 3); + if (count($df_buf1) != 2) { + continue; + } + if (preg_match("/(.*)(\s+)(([0-9]+)(\s+)([0-9]+)(\s+)([\-0-9]+)(\s+)([0-9]+)$)/", $df_buf1[0], $df_buf2)) { + $df_buf = array($df_buf2[1], $df_buf2[4], $df_buf2[6], $df_buf2[8], $df_buf2[10], $df_buf1[1]); + if (count($df_buf) == 6) { + $df_buf[5] = trim($df_buf[5]); + $dev = new DiskDevice(); + $dev->setName(trim($df_buf[0])); + if ($df_buf[2] < 0) { + $dev->setTotal($df_buf[3] * 1024); + $dev->setUsed($df_buf[3] * 1024); + } else { + $dev->setTotal($df_buf[1] * 1024); + $dev->setUsed($df_buf[2] * 1024); + if ($df_buf[3]>0) { + $dev->setFree($df_buf[3] * 1024); + } + } + if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[5]); + $dev->setFsType('unknown'); + $this->sys->setDiskDevices($dev); + } + } + } + } + break; + case 'DrayOS': + if (CommonFunctions::executeProgram('nand', 'usage', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "") + && preg_match('/([\s\S]+> nand usage)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $df = substr($resulte, strlen($resulto[1][0])); + + if (preg_match('/Usecfg/', $df)) { // fix for Vigor2135ac v4.4.2 + $df = preg_replace("/(cfg|bin)/", "\n$1", substr($resulte, strlen($resulto[1][0]))); + $percent = ''; + } else { + $percent = '%'; + } + + $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + foreach ($df as $df_line) { + if (preg_match("/^(\S+)[ ]+(\d+)[ ]+(\d+)[ ]+(\d+)[ ]+(\d+)".$percent."/", trim($df_line), $df_buf)) { + $dev = new DiskDevice(); + $dev->setName($df_buf[1]); + $dev->setTotal($df_buf[2]); + $dev->setUsed($df_buf[3]); + $dev->setFree($df_buf[4]); + $dev->setFsType('NAND'); + $this->sys->setDiskDevices($dev); + } + } + } + break; + case 'GNU': + case 'Linux': + parent::_filesystems(); + } + } + + /** + * Distribution + * + * @return void + */ + protected function _distro() + { + switch ($this->_ostype) { + case 'SSH': + $this->sys->setOS('Unknown'); + $this->sys->setDistributionIcon('Unknown.png'); + break; + case 'FortiOS': + if (preg_match("/^Version: \S+ (v[^\n]+)\n/", $this->getSystemStatus(), $buf)) { + $this->sys->setDistribution('FortiOS '.trim($buf[1])); + } + $this->sys->setDistributionIcon('FortiOS.png'); + break; + case 'DrayOS': + if (preg_match("/ Version: ([^\n]+)\n/", $this->getSysVerSysteminfo(), $buf)) { + $this->sys->setDistribution('DrayOS '.trim($buf[1])); + } + $this->sys->setDistributionIcon('DrayOS.png'); + break; + case 'GNU': + case 'Linux': + parent::_distro(); + } +// if ($this->_ostype !== null) { +// $this->sys->setDistributionIcon($this->_ostype); +// } + } + + /** + * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu + * + * @param String $cpuline cpu for which load should be meassured + * + * @return int + */ + protected function _parseProcStat($cpuline) + { + if ($this->_cpu_loads === null) { + $this->_cpu_loads = array(); + switch ($this->_ostype) { + case 'FortiOS': + if (($strBuf = $this->getSystemPerformance()) !== '') { + $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) if (preg_match('/^CPU(\d*) states: \d+% user \d+% system \d+% nice (\d+)% idle /', $line, $buf)) { + $this->_cpu_loads['cpu'.$buf[1]] = 100-$buf[2]; + } + } + break; + case 'DrayOS': + if (preg_match("/CPU usage :[ ]*(\d+) %/", $sysinfo = $this->getSysVerSysteminfo(), $buf)) { + $this->_cpu_loads['cpu'] = $buf[1]; + if (preg_match("/CPU1 speed/", $sysinfo) && !preg_match("/CPU2 speed/", $sysinfo)) { //only one cpu + $this->_cpu_loads['cpu1'] = $buf[1]; + } + } + } + } + if (isset($this->_cpu_loads[$cpuline])) { + return $this->_cpu_loads[$cpuline]; + } else { + return null; + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + protected function _loadavg($bufr = null) + { + switch ($this->_ostype) { + case 'FortiOS': + if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/loadavg', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + parent::_loadavg(substr($resulte, strlen($resulto[1][0]))); + } + break; + case 'DrayOS': + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($this->_parseProcStat('cpu')); + } + break; + case 'GNU': + case 'Linux': + parent::_loadavg(); + } + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + protected function _uptime($bufu = null) + { + switch ($this->_ostype) { + case 'FortiOS': + if (preg_match("/\nUptime: ([^\n]+)\n/", $this->getSystemPerformance(), $buf)) { + parent::_uptime('up '.trim($buf[1])); + } + break; + case 'DrayOS': + if (preg_match("/System Uptime:([\d:]+)/", $this->getShowStatus(), $buf)) { + parent::_uptime('up '.trim($buf[1])); + } + break; + case 'GNU': + case 'Linux': + if (CommonFunctions::executeProgram('cat', '/proc/uptime', $resulte, false) && ($resulte !== "")) { + $ar_buf = preg_split('/ /', $resulte); + $this->sys->setUptime(trim($ar_buf[0])); + } else { + parent::_uptime(); + } + } + } + + /** + * Kernel Version + * + * @return void + */ + protected function _kernel() + { + switch ($this->_ostype) { + case 'FortiOS': + if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/version', $resulte, false) && ($resulte !== "") + && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) { + $strBuf = substr($resulte, $resulto[1][1]); + if (preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) { + $verBuf = $ar_buf[1]; + if (preg_match('/ SMP /', $strBuf)) { + $verBuf .= ' (SMP)'; + } + $this->sys->setKernel($verBuf); + } + } + break; + case 'GNU': + case 'Linux': + parent::_kernel(); + } + } + + /** + * get the information + * + * @return void + */ + public function build() + { + $this->error->addWarning("The SSH version of phpSysInfo is a work in progress, some things currently don't work"); + switch ($this->_ostype) { + case 'SSH': + $this->_distro(); + break; + case 'FortiOS': + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); +// $this->_users(); + $this->_loadavg(); +// $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_machine(); + $this->_cpuinfo(); + //$this->_virtualizer(); +// $this->_pci(); + $this->_usb(); +// $this->_i2c(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } + break; + case 'DrayOS': + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); +// $this->_kernel(); + $this->_uptime(); +//// $this->_users(); + $this->_loadavg(); +//// $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_machine(); + $this->_cpuinfo(); +// //$this->_virtualizer(); +//// $this->_pci(); +// $this->_usb(); +//// $this->_i2c(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } + break; + case 'GNU': + case 'Linux': + parent::build(); + } + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php index e9dee30..89fdad0 100644 --- a/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php @@ -8,7 +8,7 @@ * @package PSI SunOS OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.SunOS.inc.php 687 2012-09-06 20:54:49Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,12 +20,89 @@ * @package PSI SunOS OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class SunOS extends OS { + + /** + * content of prtconf -v + * + * @var array + */ + private $_prtconf = null; + + /** + * Execute prtconf -v and save ass array + * + * @return array + */ + protected function prtconf() + { + if ($this->_prtconf === null) { + $this->_prtconf = array(); + if (CommonFunctions::executeProgram('prtconf', '-v', $buf, PSI_DEBUG) && ($buf!="")) { + $blocks = preg_split('/\n(?= \S)/', $buf, -1, PREG_SPLIT_NO_EMPTY); + if (!empty($blocks) && (count($blocks)>2)) { + array_shift($blocks); + foreach ($blocks as $block) { + if (preg_match('/^ (\S+) /', $block, $ar_buf)) { + $group = trim($ar_buf[1], ','); + $grouparr = array(); + $blocks1 = preg_split('/\n(?= \S)/', $block, -1, PREG_SPLIT_NO_EMPTY); + if (!empty($blocks1) && count($blocks1)) { + array_shift($blocks1); + foreach ($blocks1 as $block1) { + if (!preg_match('/^ name=\'([^\']+)\'/', $block1) + && preg_match('/^ (\S+) /', $block1, $ar_buf)) { + $device = trim($ar_buf[1], ','); + $devicearr = array(); + $blocks2 = preg_split('/\n(?= \S)/', $block1, -1, PREG_SPLIT_NO_EMPTY); + if (!empty($blocks2) && count($blocks2)) { + array_shift($blocks2); + foreach ($blocks2 as $block2) { + if (!preg_match('/^ name=\'([^\']+)\'/', $block2) + && preg_match('/^ (\S+) /', $block2, $ar_buf)) { + $subdev = trim($ar_buf[1], ','); + $subdevarr = array(); + $blocks3 = preg_split('/\n(?= \S)/', $block2, -1, PREG_SPLIT_NO_EMPTY); + if (!empty($blocks3) && count($blocks3)) { + array_shift($blocks3); + foreach ($blocks3 as $block3) { + if (preg_match('/^ name=\'([^\']+)\' [\s\S]+ value=\'?([^\']+)\'?/m', $block3, $ar_buf)) { + if ($subdev==='Hardware') { + $subdevarr[$ar_buf[1]] = $ar_buf[2]; + $subdevarr['device'] = $device; + } + } + } + if (count($subdevarr)) { + $devicearr = $subdevarr; + } + } + } + } + } + if (count($devicearr)) { + $grouparr[$device][] = $devicearr; + } + } + } + } + if (count($grouparr)) { + $this->_prtconf[$group][] = $grouparr; + } + } + } + } + } + } + + return $this->_prtconf; + } + /** * Extract kernel values via kstat() interface * @@ -35,11 +112,10 @@ class SunOS extends OS */ private function _kstat($key) { - if (CommonFunctions::executeProgram('kstat', '-p d '.$key, $m, PSI_DEBUG) && - !is_null($m) && (trim($m)!=="")) { - list($key, $value) = preg_split("/\t/", trim($m), 2); + if (CommonFunctions::executeProgram('kstat', '-p d '.$key, $m, PSI_DEBUG) && ($m!=="")) { + list($key, $value) = preg_split("/\t/", $m, 2); - return $value; + return trim($value); } else { return ''; } @@ -52,8 +128,8 @@ class SunOS extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - $this->sys->setHostname(getenv('SERVER_NAME')); + if (PSI_USE_VHOST) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { $ip = gethostbyname($result); @@ -64,24 +140,6 @@ class SunOS extends OS } } - /** - * IP of the Virtual Host Name - * - * @return void - */ - private function _ip() - { - if (PSI_USE_VHOST === true) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - if (!($result = getenv('SERVER_ADDR'))) { - $this->sys->setIp(gethostbyname($this->sys->getHostname())); - } else { - $this->sys->setIp($result); - } - } - } - /** * Kernel Version * @@ -89,12 +147,17 @@ class SunOS extends OS */ private function _kernel() { - if (CommonFunctions::executeProgram('uname', '-s', $os, PSI_DEBUG)) { - if (CommonFunctions::executeProgram('uname', '-r', $version, PSI_DEBUG)) { - $this->sys->setKernel($os.' '.$version); - } else { - $this->sys->setKernel($os); + if (CommonFunctions::executeProgram('uname', '-s', $kernel, PSI_DEBUG) && ($kernel != "")) { + if (CommonFunctions::executeProgram('uname', '-r', $version, PSI_DEBUG) && ($version != "")) { + $kernel.=' '.$version; } + if (CommonFunctions::executeProgram('uname', '-v', $subversion, PSI_DEBUG) && ($subversion != "")) { + $kernel.=' ('.$subversion.')'; + } + if (CommonFunctions::executeProgram('uname', '-i', $platform, PSI_DEBUG) && ($platform != "")) { + $kernel.=' '.$platform; + } + $this->sys->setKernel($kernel); } } @@ -109,19 +172,6 @@ class SunOS extends OS $this->sys->setUptime(time() - $this->_kstat('unix:0:system_misc:boot_time')); } - /** - * Number of Users - * - * @return void - */ - private function _users() - { - if (CommonFunctions::executeProgram('who', '-q', $buf, PSI_DEBUG)) { - $who = preg_split('/=/', $buf); - $this->sys->setUsers($who[1]); - } - } - /** * Processor Load * optionally create a loadbar @@ -143,13 +193,75 @@ class SunOS extends OS */ private function _cpuinfo() { - $dev = new CpuDevice(); - if (CommonFunctions::executeProgram('uname', '-i', $buf, PSI_DEBUG)) { - $dev->setModel(trim($buf)); + if (CommonFunctions::executeProgram('kstat', '-p d cpu_info:*:cpu_info*:core_id', $m, PSI_DEBUG) && ($m!=="")) { + $cpuc = count(preg_split('/\n/', $m, -1, PREG_SPLIT_NO_EMPTY)); + for ($cpu=0; $cpu < $cpuc; $cpu++) { + $dev = new CpuDevice(); + if (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':current_clock_Hz')) !== "") { + $dev->setCpuSpeed($buf/1000000); + } elseif (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':clock_MHz')) !== "") { + $dev->setCpuSpeed($buf); + } + if (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':supported_frequencies_Hz')) !== "") { + $cpuarr = preg_split('/:/', $buf, -1, PREG_SPLIT_NO_EMPTY); + if (($cpuarrc=count($cpuarr))>1) { + $dev->setCpuSpeedMin($cpuarr[0]/1000000); + $dev->setCpuSpeedMax($cpuarr[$cpuarrc-1]/1000000); + } + } + if (($buf =$this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':brand')) !== "") { + $dev->setModel($buf); + } elseif (($buf =$this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':cpu_type')) !== "") { + $dev->setModel($buf); + } elseif (CommonFunctions::executeProgram('uname', '-p', $buf, PSI_DEBUG) && ($buf!="")) { + $dev->setModel($buf); + } elseif (CommonFunctions::executeProgram('uname', '-i', $buf, PSI_DEBUG) && ($buf!="")) { + $dev->setModel($buf); + } + $this->sys->setCpus($dev); + } + } + } + + /** + * PCI devices + * + * @return void + */ + protected function _pci() + { + $prtconf = $this->prtconf(); + if ((count($prtconf)>1) && isset($prtconf['pci'])) { + foreach ($prtconf['pci'] as $prt) { + foreach ($prt as $pci) { + foreach ($pci as $pcidev) { + if (isset($pcidev['device'])) { + $dev = new HWDevice(); + if (isset($pcidev['model'])) { + $name = $pcidev['model']; + } else { + $name = $pcidev['device']; + } + if (isset($pcidev['device-name'])) { + $name .= ': '.$pcidev['device-name']; + } + $dev->setName($name); + + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($pcidev['subsystem-name']) && ($pcidev['subsystem-name']!=='unknown subsystem')) { + $dev->setProduct($pcidev['subsystem-name']); + } + if (isset($pcidev['vendor-name'])) { + $dev->setManufacturer($pcidev['vendor-name']); + } + } + + $this->sys->setPciDevices($dev); + } + } + } + } } - $dev->setCpuSpeed($this->_kstat('cpu_info:0:cpu_info0:clock_MHz')); - $dev->setCache($this->_kstat('cpu_info:0:cpu_info0:cpu_type') * 1024); - $this->sys->setCpus($dev); } /** @@ -189,23 +301,22 @@ class SunOS extends OS } } if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { - if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0], $bufr2, PSI_DEBUG) - && !is_null($bufr2) && (trim($bufr2) !== "")) { + if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0], $bufr2, PSI_DEBUG) && ($bufr2!=="")) { $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe2 as $buf2) { - if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); - elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) { + if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1]))); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) { $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } } } - if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' inet6', $bufr2, PSI_DEBUG) - && !is_null($bufr2) && (trim($bufr2) !== "")) { + if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' inet6', $bufr2, PSI_DEBUG) && ($bufr2!=="")) { $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); foreach ($bufe2 as $buf2) { if (preg_match('/^\s+inet6\s+([^\s\/]+)/i', $buf2, $ar_buf2) - && !preg_match('/^fe80::/i', $ar_buf2[1])) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1])); } } } @@ -227,14 +338,16 @@ class SunOS extends OS $this->sys->setMemTotal($this->_kstat('unix:0:system_pages:pagestotal') * $pagesize); $this->sys->setMemUsed($this->_kstat('unix:0:system_pages:pageslocked') * $pagesize); $this->sys->setMemFree($this->_kstat('unix:0:system_pages:pagesfree') * $pagesize); - $dev = new DiskDevice(); - $dev->setName('SWAP'); - $dev->setFsType('swap'); - $dev->setMountPoint('SWAP'); - $dev->setTotal($this->_kstat('unix:0:vminfo:swap_avail') / 1024); - $dev->setUsed($this->_kstat('unix:0:vminfo:swap_alloc') / 1024); - $dev->setFree($this->_kstat('unix:0:vminfo:swap_free') / 1024); - $this->sys->setSwapDevices($dev); + if (($swap=$this->_kstat('unix:0:vminfo:swap_avail')) > 0) { + $dev = new DiskDevice(); + $dev->setName('SWAP'); + $dev->setFsType('swap'); + $dev->setMountPoint('SWAP'); + $dev->setTotal($swap / 1024); + $dev->setUsed($this->_kstat('unix:0:vminfo:swap_alloc') / 1024); + $dev->setFree($this->_kstat('unix:0:vminfo:swap_free') / 1024); + $this->sys->setSwapDevices($dev); + } } /** @@ -289,8 +402,21 @@ class SunOS extends OS */ private function _distro() { - $this->sys->setDistribution('SunOS'); - $this->sys->setDistributionIcon('SunOS.png'); + if (CommonFunctions::rfts('/etc/release', $buf, 1, 4096, false) && (trim($buf)!="")) { + $this->sys->setDistribution(trim($buf)); + $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true); + if ($list && preg_match('/^(\S+)\s*/', preg_replace('/^open\s+/', 'open', preg_replace('/^oracle\s+/', 'oracle', strtolower(trim($buf)))), $id_buf) && isset($list[$distid=(trim($id_buf[1].' sunos'))]['Image'])) { + $this->sys->setDistributionIcon($list[$distid]['Image']); + if (isset($list[trim($distid)]['Name'])) { + $this->sys->setDistribution(trim($list[$distid]['Name']).' '.$this->sys->getDistribution()); + } + } else { + $this->sys->setDistributionIcon('SunOS.png'); + } + } else { + $this->sys->setDistribution('SunOS'); + $this->sys->setDistributionIcon('SunOS.png'); + } } /** @@ -328,22 +454,32 @@ class SunOS extends OS * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->error->addError("WARN", "The SunOS version of phpSysInfo is a work in progress, some things currently don't work"); - $this->_distro(); - $this->_hostname(); - $this->_ip(); - $this->_kernel(); - $this->_uptime(); - $this->_users(); - $this->_loadavg(); - $this->_cpuinfo(); - $this->_network(); - $this->_memory(); - $this->_filesystems(); - $this->_processes(); + $this->error->addWarning("The SunOS version of phpSysInfo is a work in progress, some things currently don't work"); + if (!$this->blockname || $this->blockname==='vitals') { + $this->_distro(); + $this->_hostname(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_cpuinfo(); + $this->_pci(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); + } } } diff --git a/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php index ff5eac5..5cc8758 100644 --- a/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php +++ b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php @@ -8,7 +8,7 @@ * @package PSI WINNT OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.WINNT.inc.php 699 2012-09-15 11:57:13Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,25 +21,109 @@ * @package PSI WINNT OS class * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class WINNT extends OS { /** - * holds the COM object that we pull all the WMI data from + * holds codepage for chcp + * + * @var int + */ + private static $_cp = null; + + /** + * holds the data from WMI Win32_OperatingSystem + * + * @var array + */ + private static $_Win32_OperatingSystem = null; + + /** + * holds the data from WMI Win32_ComputerSystem + * + * @var array + */ + private $_Win32_ComputerSystem = null; + + /** + * holds the data from WMI Win32_Processor + * + * @var array + */ + private static $_Win32_Processor = null; + + /** + * holds the data from WMI Win32_PhysicalMemory + * + * @var array + */ + private static $_Win32_PhysicalMemory = null; + + /** + * holds the data from WMI Win32_PerfFormattedData_PerfOS_Processor + * + * @var array + */ + private $_Win32_PerfFormattedData_PerfOS_Processor = null; + + /** + * holds the data from systeminfo command + * + * @var string + */ + private $_systeminfo = null; + + /** + * holds the COM object that we pull WMI root\CIMv2 data from * * @var Object */ - private $_wmi = null; + private static $_wmi = null; + + /** + * holds the COM object that we pull all the EnumKey and RegRead data from + * + * @var Object + */ + private $_reg = null; + + /** + * holds result of 'cmd /c ver' + * + * @var string + */ + private $_ver = ""; + + /** + * holds system manufacturer + * + * @var string + */ + private $_Manufacturer = ""; + + /** + * holds system model + * + * @var string + */ + private $_Model = ""; /** * holds all devices, which are in the system * * @var array */ - private $_wmidevices; + private $_wmidevices = null; + + /** + * holds all disks, which are in the system + * + * @var array + */ + private $_wmidisks = array(); /** * store language encoding of the system to convert some output to utf-8 @@ -55,28 +139,493 @@ class WINNT extends OS */ private $_syslang = null; + /** + * value of checking run as administrator + * + * @var boolean + */ + private static $_asadmin = null; + + /** + * returns codepage for chcp + * + * @return int + */ + public static function getcp() + { + return self::$_cp; + } + + /** + * returns the COM object that we pull WMI root\CIMv2 data from + * + * @return Object + */ + public static function getcimv2wmi() + { + return self::$_wmi; + } + + /** + * reads the data from WMI Win32_OperatingSystem + * + * @return array + */ + public static function _get_Win32_OperatingSystem() + { + if (self::$_Win32_OperatingSystem === null) self::$_Win32_OperatingSystem = self::getWMI(self::$_wmi, 'Win32_OperatingSystem', array('CodeSet', 'Locale', 'LastBootUpTime', 'LocalDateTime', 'Version', 'ServicePackMajorVersion', 'Caption', 'TotalVisibleMemorySize', 'FreePhysicalMemory')); + return self::$_Win32_OperatingSystem; + } + + /** + * reads the data from WMI Win32_ComputerSystem + * + * @return array + */ + private function _get_Win32_ComputerSystem() + { + if ($this->_Win32_ComputerSystem === null) $this->_Win32_ComputerSystem = self::getWMI(self::$_wmi, 'Win32_ComputerSystem', array('Name', 'Manufacturer', 'Model', 'SystemFamily')); + return $this->_Win32_ComputerSystem; + } + + /** + * reads the data from WMI Win32_Processor + * + * @return array + */ + public static function _get_Win32_Processor() + { + if (self::$_Win32_Processor === null) self::$_Win32_Processor = self::getWMI(self::$_wmi, 'Win32_Processor', array('DeviceID', 'LoadPercentage', 'AddressWidth', 'Name', 'L2CacheSize', 'L3CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'NumberOfLogicalProcessors', 'MaxClockSpeed', 'Manufacturer', 'Architecture', 'Caption', 'CurrentVoltage')); + return self::$_Win32_Processor; + } + + /** + * reads the data from WMI Win32_PhysicalMemory + * + * @return array + */ + public static function _get_Win32_PhysicalMemory() + { + if (self::$_Win32_PhysicalMemory === null) self::$_Win32_PhysicalMemory = self::getWMI(self::$_wmi, 'Win32_PhysicalMemory', array('PartNumber', 'DeviceLocator', 'Capacity', 'Manufacturer', 'SerialNumber', 'Speed', 'ConfiguredClockSpeed', 'ConfiguredVoltage', 'MemoryType', 'SMBIOSMemoryType', 'FormFactor', 'DataWidth', 'TotalWidth', 'BankLabel', 'MinVoltage', 'MaxVoltage')); + return self::$_Win32_PhysicalMemory; + } + + /** + * reads the data from WMI Win32_PerfFormattedData_PerfOS_Processor + * + * @return array + */ + private function _get_Win32_PerfFormattedData_PerfOS_Processor() + { + if ($this->_Win32_PerfFormattedData_PerfOS_Processor === null) { + $this->_Win32_PerfFormattedData_PerfOS_Processor = array(); + $buffer = $this->_get_Win32_OperatingSystem(); + if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "5.1", ">=")) { // minimal windows 2003 or windows XP + $cpubuffer = self::getWMI(self::$_wmi, 'Win32_PerfFormattedData_PerfOS_Processor', array('Name', 'PercentProcessorTime')); + foreach ($cpubuffer as $cpu) { + if (isset($cpu['Name']) && isset($cpu['PercentProcessorTime'])) { + $this->_Win32_PerfFormattedData_PerfOS_Processor['cpu'.$cpu['Name']] = $cpu['PercentProcessorTime']; + } + } + } + } + + return $this->_Win32_PerfFormattedData_PerfOS_Processor; + } + + /** + * reads the data from systeminfo + * + * @return string + */ + private function _get_systeminfo() + { + if (!defined('PSI_EMU_HOSTNAME')) { + if ($this->_systeminfo === null) CommonFunctions::executeProgram('systeminfo', '', $this->_systeminfo, false); + return $this->_systeminfo; + } else { + return ''; + } + } + + /** + * checks WINNT and 'run as Administrator' mode + * + * @return boolean + */ + public static function isAdmin() + { + if (self::$_asadmin == null) { + if (PSI_OS == 'WINNT') { + $strBuf = ''; + CommonFunctions::executeProgram('sfc', '2>&1', $strBuf, false); // 'net session' for detection does not work if "Server" (LanmanServer) service is stopped + if (preg_match('/^\/SCANNOW\s/m', preg_replace('/(\x00)/', '', $strBuf))) { // SCANNOW checking - also if Unicode + self::$_asadmin = true; + } else { + self::$_asadmin = false; + } + } else { + self::$_asadmin = false; + } + } + + return self::$_asadmin; + } + + /** + * function for getting a list of values in the specified context + * optionally filter this list, based on the list from third parameter + * + * @param $wmi object holds the COM object that we pull the WMI data from + * @param string $strClass name of the class where the values are stored + * @param array $strValue filter out only needed values, if not set all values of the class are returned + * + * @return array content of the class stored in an array + */ + public static function getWMI($wmi, $strClass, $strValue = array()) + { + $arrData = array(); + if (gettype($wmi) === "object") { + $value = ""; + try { + $objWEBM = $wmi->Get($strClass); + $arrProp = $objWEBM->Properties_; + $arrWEBMCol = $objWEBM->Instances_(); + foreach ($arrWEBMCol as $objItem) { + if (is_array($arrProp)) { + reset($arrProp); + } + $arrInstance = array(); + foreach ($arrProp as $propItem) { + $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";"); + if (empty($strValue)) { + if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); + else $arrInstance[$propItem->Name] = $value; + } else { + if (in_array($propItem->Name, $strValue)) { + if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); + else $arrInstance[$propItem->Name] = $value; + } + } + } + $arrData[] = $arrInstance; + } + } catch (Exception $e) { + if (PSI_DEBUG && (($message = trim($e->getMessage())) !== "Source: SWbemServicesEx
Description: Not found")) { + $error = PSI_Error::singleton(); + $error->addError("getWMI()", preg_replace('//', "\n", preg_replace('/|<\/b>/', '', $message))); + } + } + } elseif ((gettype($wmi) === "string") && (PSI_OS == 'Linux')) { + $delimeter = '@@@DELIM@@@'; + if (CommonFunctions::executeProgram('wmic', '--delimiter="'.$delimeter.'" '.$wmi.' '.$strClass.'" 2>/dev/null', $strBuf, true) && preg_match("/^CLASS:\s/", $strBuf)) { + if (self::$_cp) { + if (self::$_cp == 932) { + $codename = ' (SJIS)'; + } elseif (self::$_cp == 949) { + $codename = ' (EUC-KR)'; + } elseif (self::$_cp == 950) { + $codename = ' (BIG-5)'; + } else { + $codename = ''; + } + self::convertCP($strBuf, 'windows-'.self::$_cp.$codename); + } + $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY); + if (count($lines) >=3) { + unset($lines[0]); + $names = preg_split('/'.$delimeter.'/', $lines[1], -1, PREG_SPLIT_NO_EMPTY); + $namesc = count($names); + unset($lines[1]); + foreach ($lines as $line) { + $arrInstance = array(); + $values = preg_split('/'.$delimeter.'/', $line, -1); + if (count($values) == $namesc) { + foreach ($values as $id=>$value) { + if (empty($strValue)) { + if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value); + else $arrInstance[$names[$id]] = null; + } else { + if (in_array($names[$id], $strValue)) { + if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value); + else $arrInstance[$names[$id]] = null; + } + } + } + $arrData[] = $arrInstance; + } + } + } + } + } + + return $arrData; + } + + /** + * readReg function + * + * @return boolean command successfull or not + */ + public static function readReg($reg, $strName, &$strBuffer, $booErrorRep = true, $dword = false, $bits64 = false) + { + $strBuffer = ''; + + if ($reg === false) { + if (defined('PSI_EMU_HOSTNAME')) { + return false; + } + $last = strrpos($strName, "\\"); + $keyname = substr($strName, $last + 1); + if ($bits64) { + $param = ' /reg:64'; + } else { + $param = ''; + } + if ($dword) { + $valtype = "DWORD"; + } else { + $valtype = "SZ|EXPAND_SZ"; + } + if (self::$_cp) { + if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) { + if ($dword) { + $strBuffer = strval(hexdec($buffer2[2])); + } else { + $strBuffer = $buffer2[2]; + } + } else { + return false; + } + } else { + if (CommonFunctions::executeProgram('reg', 'query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) { + if ($dword) { + $strBuffer = strval(hexdec($buffer2[2])); + } else { + $strBuffer = $buffer2[2]; + } + } else { + return false; + } + } + } elseif (gettype($reg) === "object") { + $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006); + $first = strpos($strName, "\\"); + $last = strrpos($strName, "\\"); + $hkey = substr($strName, 0, $first); + if (isset($_hkey[$hkey])) { + $sub_keys = new VARIANT(); + try { + if ($dword) { + $reg->Get("StdRegProv")->GetDWORDValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys); + } else { + $reg->Get("StdRegProv")->GetStringValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys); + } + } catch (Exception $e) { + if ($booErrorRep) { + $error = PSI_Error::singleton(); + $error->addError("GetStringValue()", preg_replace('//', "\n", preg_replace('/|<\/b>/', '', $e->getMessage()))); + } + + return false; + } + if (variant_get_type($sub_keys) !== VT_NULL) { + $strBuffer = strval($sub_keys); + } else { + return false; + } + } else { + return false; + } + } + + return true; + } + + /** + * enumKey function + * + * @return boolean command successfull or not + */ + public static function enumKey($reg, $strName, &$arrBuffer, $booErrorRep = true) + { + $arrBuffer = array(); + + if ($reg === false) { + if (defined('PSI_EMU_HOSTNAME')) { + return false; + } + if (self::$_cp) { + if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) { + foreach ($buffer2[1] as $sub_key) { + $arrBuffer[] = trim($sub_key); + } + } else { + return false; + } + } else { + if (CommonFunctions::executeProgram('reg', 'query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) { + foreach ($buffer2[1] as $sub_key) { + $arrBuffer[] = trim($sub_key); + } + } else { + return false; + } + } + } elseif (gettype($reg) === "object") { + $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006); + $first = strpos($strName, "\\"); + $hkey = substr($strName, 0, $first); + if (isset($_hkey[$hkey])) { + $sub_keys = new VARIANT(); + try { + $reg->Get("StdRegProv")->EnumKey(strval($_hkey[$hkey]), substr($strName, $first+1), $sub_keys); + } catch (Exception $e) { + if ($booErrorRep) { + $error = PSI_Error::singleton(); + $error->addError("enumKey()", preg_replace('//', "\n", preg_replace('/|<\/b>/', '', $e->getMessage())));; + } + + return false; + } + if (variant_get_type($sub_keys) !== VT_NULL) { + foreach ($sub_keys as $sub_key) { + $arrBuffer[] = $sub_key; + } + } else { + return false; + } + } else { + return false; + } + } + + return true; + } + + /** + * initWMI function + * + * @return string, object or false + */ + public static function initWMI($namespace, $booErrorRep = false) + { + $wmi = false; + if (self::$_wmi !== false) { // WMI not disabled + try { + if (PSI_OS == 'Linux') { + if (defined('PSI_EMU_HOSTNAME')) + $wmi = '--namespace="'.$namespace.'" -U '.PSI_EMU_USER.'%'.PSI_EMU_PASSWORD.' //'.PSI_EMU_HOSTNAME.' "select * from'; + } elseif (PSI_OS == 'WINNT') { + $objLocator = new COM('WbemScripting.SWbemLocator'); + if (defined('PSI_EMU_HOSTNAME')) + $wmi = $objLocator->ConnectServer(PSI_EMU_HOSTNAME, $namespace, PSI_EMU_USER, PSI_EMU_PASSWORD); + else + $wmi = $objLocator->ConnectServer('', $namespace); + } + } catch (Exception $e) { + if ($booErrorRep) { + $error = PSI_Error::singleton(); + $error->addError("WMI connect ".$namespace." error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed or credentials."); + } + } + } + + return $wmi; + } + + /** + * convertCP function + * + * @return void + */ + public static function convertCP(&$strBuf, $encoding) + { + if (defined('PSI_SYSTEM_CODEPAGE') && (PSI_SYSTEM_CODEPAGE != null) && ($encoding != null) && ($encoding != PSI_SYSTEM_CODEPAGE)) { + $systemcp = PSI_SYSTEM_CODEPAGE; + if (preg_match("/^windows-\d+ \((.+)\)$/", $systemcp, $buf)) { + $systemcp = $buf[1]; + } + if (preg_match("/^windows-\d+ \((.+)\)$/", $encoding, $buf)) { + $encoding = $buf[1]; + } + $enclist = mb_list_encodings(); + if (in_array($encoding, $enclist) && in_array($systemcp, $enclist)) { + $strBuf = mb_convert_encoding($strBuf, $encoding, $systemcp); + } elseif (function_exists("iconv")) { + if (($iconvout=iconv($systemcp, $encoding.'//IGNORE', $strBuf))!==false) { + $strBuf = $iconvout; + } + } elseif (function_exists("libiconv") && (($iconvout=libiconv($systemcp, $encoding, $strBuf))!==false)) { + $strBuf = $iconvout; + } + } + } + /** * build the global Error object and create the WMI connection */ - public function __construct() + public function __construct($blockname = false) { - parent::__construct(); - // don't set this params for local connection, it will not work - $strHostname = ''; - $strUser = ''; - $strPassword = ''; - try { - // initialize the wmi object - $objLocator = new COM('WbemScripting.SWbemLocator'); - if ($strHostname == "") { - $this->_wmi = $objLocator->ConnectServer(); - - } else { - $this->_wmi = $objLocator->ConnectServer($strHostname, 'root\CIMv2', $strHostname.'\\'.$strUser, $strPassword); - } - } catch (Exception $e) { - $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed."); + parent::__construct($blockname); + if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('cmd', '/c ver 2>nul', $ver_value, false) && (($ver_value = trim($ver_value)) !== "")) { + $this->_ver = $ver_value; } + if (($this->_ver !== "") && preg_match("/ReactOS\r?\n\S+\s+.+/", $this->_ver)) { + self::$_wmi = false; // No WMI info on ReactOS yet + $this->_reg = false; // No EnumKey and ReadReg on ReactOS yet + } else { + if ((PSI_OS == 'WINNT') && !defined('PSI_SYSTEM_CODEPAGE')) { + if (defined('PSI_EMU_HOSTNAME')) { + try { + $objLocator = new COM('WbemScripting.SWbemLocator'); + $wmi = $objLocator->ConnectServer('', 'root\CIMv2'); + $buffer = self::getWMI($wmi, 'Win32_OperatingSystem', array('CodeSet')); + if (!$buffer) { + $reg = $objLocator->ConnectServer('', 'root\default'); + if (self::readReg($reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) { + $buffer[0]['CodeSet'] = $strBuf; + } + } + if ($buffer && isset($buffer[0]) && isset($buffer[0]['CodeSet'])) { + $codeset = $buffer[0]['CodeSet']; + if ($codeset == 932) { + $codename = ' (SJIS)'; + } elseif ($codeset == 949) { + $codename = ' (EUC-KR)'; + } elseif ($codeset == 950) { + $codename = ' (BIG-5)'; + } else { + $codename = ''; + } + define('PSI_SYSTEM_CODEPAGE', 'windows-'.$codeset.$codename); + } else { + define('PSI_SYSTEM_CODEPAGE', null); + if (PSI_DEBUG) { + $this->error->addError("__construct()", "PhpSysInfo can not detect PSI_SYSTEM_CODEPAGE"); + } + } + } catch (Exception $e) { + define('PSI_SYSTEM_CODEPAGE', null); + if (PSI_DEBUG) { + $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed"); + } + } + } else { + define('PSI_SYSTEM_CODEPAGE', null); + } + } + self::$_wmi = self::initWMI('root\CIMv2', true); + if (PSI_OS == 'WINNT') { + $this->_reg = self::initWMI('root\default', PSI_DEBUG); + if (gettype($this->_reg) === "object") { + $this->_reg->Security_->ImpersonationLevel = 3; + } + } else { + $this->_reg = false; // No EnumKey and ReadReg on Linux + } + } + $this->_getCodeSet(); } @@ -87,19 +636,42 @@ class WINNT extends OS */ private function _getCodeSet() { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('CodeSet', 'OSLanguage')); - if ($buffer) { - $this->_codepage = 'windows-'.$buffer[0]['CodeSet']; - $lang = ""; - if (is_readable(APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(APP_ROOT.'/data/languages.ini', true))) { - if (isset($langdata['WINNT'][$buffer[0]['OSLanguage']])) { - $lang = $langdata['WINNT'][$buffer[0]['OSLanguage']]; + $buffer = $this->_get_Win32_OperatingSystem(); + if (!$buffer) { + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) { + $buffer[0]['CodeSet'] = $strBuf; + } + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Language\\Default", $strBuf, false)) { + $buffer[0]['Locale'] = $strBuf; + } + } + if ($buffer && isset($buffer[0])) { + if (isset($buffer[0]['CodeSet'])) { + $codeset = $buffer[0]['CodeSet']; + if ($codeset == 932) { + $codename = ' (SJIS)'; + } elseif ($codeset == 949) { + $codename = ' (EUC-KR)'; + } elseif ($codeset == 950) { + $codename = ' (BIG-5)'; + } else { + $codename = ''; } + self::$_cp = $codeset; + $this->_codepage = 'windows-'.$codeset.$codename; } - if ($lang == "") { - $lang = 'Unknown'; + if (isset($buffer[0]['Locale']) && (($locale = hexdec($buffer[0]['Locale']))>0)) { + $lang = ""; + if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) { + if (isset($langdata['WINNT'][$locale])) { + $lang = $langdata['WINNT'][$locale]; + } + } + if ($lang == "") { + $lang = 'Unknown'; + } + $this->_syslang = $lang.' ('.$locale.')'; } - $this->_syslang = $lang.' ('.$buffer[0]['OSLanguage'].')'; } } @@ -112,13 +684,132 @@ class WINNT extends OS */ private function _devicelist($strType) { - if (empty($this->_wmidevices)) { - $this->_wmidevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID')); + if ($this->_wmidevices === null) { + $this->_wmidevices = array(); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID', 'Manufacturer', 'PNPClass')); + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size', 'SerialNumber')); + } else { + $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size')); + } + } else { + $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID')); + } + + if (empty($this->_wmidevices)) { + $lstdevs = array(); + $services = array(); + foreach (array('PCI', 'USB') as $type) { + $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$type; + if (self::enumKey($this->_reg, $hkey, $vendevs, false)) { + foreach ($vendevs as $vendev) if (self::enumKey($this->_reg, $hkey."\\".$vendev, $ids, false)) { + foreach ($ids as $id) { + if ($type === 'PCI') { // enumerate all PCI devices + $lstdevs[$type."\\".$vendev."\\".$id] = true; + } elseif (self::readReg($this->_reg, $hkey."\\".$vendev."\\".$id."\\Service", $service, false)) { + $services[$service] = true; // ever used USB services + break; + } + } + } + } + } + + $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services"; + foreach ($services as $service=>$tmp) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\Count", $count, false, true) && ($count > 0)) { + for ($i = 0; $i < $count; $i++) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\".$i, $id, false) && preg_match("/^USB/", $id)) { + $lstdevs[$id] = true; // used USB devices + } + } + + $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\"; + foreach ($lstdevs as $lstdev=>$tmp) { + if (self::readReg($this->_reg, $hkey.$lstdev."\\DeviceDesc", $nameBuf, false)) { + $namesplit = preg_split('/;/', $nameBuf, -1, PREG_SPLIT_NO_EMPTY); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && self::readReg($this->_reg, $hkey.$lstdev."\\Mfg", $mfgBuf, false)) { + $mfgsplit = preg_split('/;/', $mfgBuf, -1, PREG_SPLIT_NO_EMPTY); + $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev, 'Manufacturer'=>$mfgsplit[count($mfgsplit)-1]); + } else { + $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev); + } + } + } + + $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi"; + $id = 0; + if (self::enumKey($this->_reg, $hkey, $portBuf, false)) { + foreach ($portBuf as $scsiport) { + if (self::enumKey($this->_reg, $hkey."\\".$scsiport, $busBuf, false)) { + foreach ($busBuf as $scsibus) { + if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus, $tarBuf, false)) { + foreach ($tarBuf as $scsitar) if (!strncasecmp($scsitar, "Target Id ", strlen("Target Id "))) { + if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar, $logBuf, false)) { + foreach ($logBuf as $scsilog) if (!strncasecmp($scsilog, "Logical Unit Id ", strlen("Logical Unit Id "))) { + $hkey2 = $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar."\\".$scsilog."\\"; + if ((self::readReg($this->_reg, $hkey2."DeviceType", $typeBuf, false) || self::readReg($this->_reg, $hkey2."Type", $typeBuf, false)) + && (($typeBuf=strtolower(trim($typeBuf))) !== "")) { + if ((($typeBuf == 'diskperipheral') || ($typeBuf == 'cdromperipheral')) + && self::readReg($this->_reg, $hkey2."Identifier", $ideBuf, false)) { + $this->_wmidevices[] = array('Name'=>$ideBuf, 'PNPDeviceID'=>'SCSI\\'.$id); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL + && self::readReg($this->_reg, $hkey2."SerialNumber", $serBuf, false) + && (($serBuf=trim($serBuf)) !== "")) { + $this->_wmidisks[] = array('PNPDeviceID'=>'SCSI\\'.$id, 'SerialNumber'=>$serBuf); + } + $id++; + } + } + } + } + } + } + } + } + } + } + } } + $list = array(); foreach ($this->_wmidevices as $device) { if (substr($device['PNPDeviceID'], 0, strpos($device['PNPDeviceID'], "\\") + 1) == ($strType."\\")) { - $list[] = $device['Name']; + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (!isset($device['PNPClass']) || ($device['PNPClass']===$strType) || ($device['PNPClass']==='System')) { + $device['PNPClass'] = null; + } + if (!isset($device['Manufacturer']) || preg_match('/^\(.*\)$/', $device['Manufacturer']) || (($device['PNPClass']==='USB') && preg_match('/\sUSB\s/', $device['Manufacturer']))) { + $device['Manufacturer'] = null; + } + $device['Capacity'] = null; + if (($strType==='IDE')||($strType==='SCSI')) { + foreach ($this->_wmidisks as $disk) { + if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['Size'])) { + $device['Capacity'] = $disk['Size']; + break; + } + } + } + $device['Serial'] = null; + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + if ($strType==='USB') { +// if (preg_match('/\\\\([^\\\\][^&\\\\][^\\\\]+)$/', $device['PNPDeviceID'], $buf)) { // second character !== & + if (preg_match('/\\\\(\w+)$/', $device['PNPDeviceID'], $buf)) { + $device['Serial'] = $buf[1]; + } + } elseif (($strType==='IDE')||($strType==='SCSI')) { + foreach ($this->_wmidisks as $disk) { + if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['SerialNumber'])) { + $device['Serial'] = $disk['SerialNumber']; + break; + } + } + } + } + $list[] = array('Name'=>$device['Name'], 'Manufacturer'=>$device['Manufacturer'], 'Product'=>$device['PNPClass'], 'Capacity'=>$device['Capacity'], 'Serial'=>$device['Serial']); + } else { + $list[] = array('Name'=>$device['Name']); + } } } @@ -132,48 +823,76 @@ class WINNT extends OS */ private function _hostname() { - if (PSI_USE_VHOST === true) { - if ($hnm = getenv('SERVER_NAME')) $this->sys->setHostname($hnm); + if (PSI_USE_VHOST && !defined('PSI_EMU_HOSTNAME')) { + if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm); } else { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name')); + $buffer = $this->_get_Win32_ComputerSystem(); + if (!$buffer && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName\\ComputerName", $strBuf, false) && (strlen($strBuf) > 0)) { + $buffer[0]['Name'] = $strBuf; + } if ($buffer) { $result = $buffer[0]['Name']; $ip = gethostbyname($result); if ($ip != $result) { - $long = ip2long($ip); - if (($long >= 167772160 && $long <= 184549375) || - ($long >= -1408237568 && $long <= -1407188993) || - ($long >= -1062731776 && $long <= -1062666241) || - ($long >= 2130706432 && $long <= 2147483647) || $long == -1) { - $this->sys->setHostname($result); //internal ip + if ((version_compare("10.0.0.0", $ip, "<=") && version_compare($ip, "10.255.255.255", "<=")) || + (version_compare("172.16.0.0", $ip, "<=") && version_compare($ip, "172.31.255.255", "<=")) || + (version_compare("192.168.0.0", $ip, "<=") && version_compare($ip, "192.168.255.255", "<=")) || + (version_compare("127.0.0.0", $ip, "<=") && version_compare($ip, "127.255.255.255", "<=")) || + (version_compare("169.254.1.0", $ip, "<=") && version_compare($ip, "169.254.254.255", "<=")) || + (version_compare("255.255.255.255", $ip, "=="))) { + $this->sys->setHostname($result); // internal ip } else { - $this->sys->setHostname(gethostbyaddr($ip)); + $hostname = gethostbyaddr($ip); + if ($hostname !== false) + $this->sys->setHostname($hostname); + else + $this->sys->setHostname($result); } + } else { + $this->sys->setHostname($result); } - } else { - if ($hnm = getenv('COMPUTERNAME')) $this->sys->setHostname($hnm); + } elseif (defined('PSI_EMU_HOSTNAME')) { + $this->sys->setHostname(PSI_EMU_HOSTNAME); + } elseif (CommonFunctions::readenv('COMPUTERNAME', $hnm)) { + $this->sys->setHostname($hnm); } } } /** - * IP of the Canonical Host Name + * Virtualizer info * * @return void */ - private function _ip() + protected function _virtualizer() { - if (PSI_USE_VHOST === true) { - if ((($hnm=$this->sys->getHostname()) != 'localhost') && - (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip); - } else { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name')); - if ($buffer) { - $result = $buffer[0]['Name']; - $this->sys->setIp(gethostbyname($result)); - } else { - if ((($hnm=$this->sys->getHostname()) != 'localhost') && - (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip); + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo() + + $vendor_array = array(); + if ($this->_Model != "") { + $vendor_array[] = $this->_Model; + } + if ($this->_Manufacturer != "") { + if ($this->_Model != "") { + $vendor_array[] = $this->_Manufacturer." ".$this->_Model; + } else { + $vendor_array[] = $this->_Manufacturer; + } + } + $novm = true; + if (count($vendor_array)>0) { + $virt = CommonFunctions::decodevirtualizer($vendor_array); + if ($virt !== null) { + $this->sys->setVirtualizer($virt); + $novm = false; + } + } + if ($novm) { + // Detect QEMU cpu + if (isset($cpuvirt["cpuid:QEMU"])) { + $this->sys->setVirtualizer('qemu'); // QEMU + } } } } @@ -188,24 +907,43 @@ class WINNT extends OS { $result = 0; date_default_timezone_set('UTC'); - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('LastBootUpTime', 'LocalDateTime')); - if ($buffer) { - $byear = intval(substr($buffer[0]['LastBootUpTime'], 0, 4)); - $bmonth = intval(substr($buffer[0]['LastBootUpTime'], 4, 2)); - $bday = intval(substr($buffer[0]['LastBootUpTime'], 6, 2)); - $bhour = intval(substr($buffer[0]['LastBootUpTime'], 8, 2)); - $bminute = intval(substr($buffer[0]['LastBootUpTime'], 10, 2)); - $bseconds = intval(substr($buffer[0]['LastBootUpTime'], 12, 2)); - $lyear = intval(substr($buffer[0]['LocalDateTime'], 0, 4)); - $lmonth = intval(substr($buffer[0]['LocalDateTime'], 4, 2)); - $lday = intval(substr($buffer[0]['LocalDateTime'], 6, 2)); - $lhour = intval(substr($buffer[0]['LocalDateTime'], 8, 2)); - $lminute = intval(substr($buffer[0]['LocalDateTime'], 10, 2)); - $lseconds = intval(substr($buffer[0]['LocalDateTime'], 12, 2)); - $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear); - $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear); + $buffer = $this->_get_Win32_OperatingSystem(); + if ($buffer && ($buffer[0]['LastBootUpTime'] !== null)) { + $local = $buffer[0]['LocalDateTime']; + $boot = $buffer[0]['LastBootUpTime']; + + $lyear = intval(substr($local, 0, 4)); + $lmonth = intval(substr($local, 4, 2)); + $lday = intval(substr($local, 6, 2)); + $lhour = intval(substr($local, 8, 2)); + $lminute = intval(substr($local, 10, 2)); + $lseconds = intval(substr($local, 12, 2)); + $loffset = intval(substr($boot, 21, 4)); + + $byear = intval(substr($boot, 0, 4)); + $bmonth = intval(substr($boot, 4, 2)); + $bday = intval(substr($boot, 6, 2)); + $bhour = intval(substr($boot, 8, 2)); + $bminute = intval(substr($boot, 10, 2)); + $bseconds = intval(substr($boot, 12, 2)); + $boffset = intval(substr($boot, 21, 4)); + + if (version_compare($buffer[0]['Version'], "5.1", "<")) { // fix LastBootUpTime on Windows 2000 and older + $boffset += $boffset; + } + + $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear) - $loffset*60; + $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear) - $boffset*60; + $result = $localtime - $boottime; + $this->sys->setUptime($result); + } elseif (!defined('PSI_EMU_HOSTNAME') && (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('uptime', '', $strBuf, false) && (strlen($strBuf) > 0) && preg_match("/^System Up Time:\s+(\d+) days, (\d+) Hours, (\d+) Minutes, (\d+) Seconds/", $strBuf, $ar_buf)) { + $sec = $ar_buf[4]; + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60 + $sec); } } @@ -214,14 +952,14 @@ class WINNT extends OS * * @return void */ - private function _users() + protected function _users() { - if (CommonFunctions::executeProgram("quser", "", $strBuf, false) && (strlen(trim($strBuf)) > 0)) { + if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('quser', '', $strBuf, false) && (strlen($strBuf) > 0)) { $lines = preg_split('/\n/', $strBuf); $users = count($lines)-1; } else { $users = 0; - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption')); + $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption')); foreach ($buffer as $process) { if (strtoupper($process['Caption']) == strtoupper('explorer.exe')) { $users++; @@ -238,46 +976,124 @@ class WINNT extends OS */ private function _distro() { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('Version', 'ServicePackMajorVersion', 'Caption', 'OSArchitecture')); + $buffer = $this->_get_Win32_OperatingSystem(); if ($buffer) { - $kernel = $buffer[0]['Version']; + $ver = $buffer[0]['Version']; + if (($this->_ver !== "") && preg_match("/^Microsoft [^\[]*\s*\[\D*\s*(".$ver."\.\d+).*\]/", $this->_ver, $ar_temp)) { + $kernel = $ar_temp[1]; + } else { + $kernel = $ver; + } if ($buffer[0]['ServicePackMajorVersion'] > 0) { $kernel .= ' SP'.$buffer[0]['ServicePackMajorVersion']; } - if (isset($buffer[0]['OSArchitecture']) && preg_match("/^(\d+)/", $buffer[0]['OSArchitecture'], $bits)) { - $this->sys->setKernel($kernel.' ('.$bits[1].'-bit)'); - } elseif (($allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('AddressWidth'))) && isset($allCpus[0]['AddressWidth'])) { - $this->sys->setKernel($kernel.' ('.$allCpus[0]['AddressWidth'].'-bit)'); - } else { - $this->sys->setKernel($kernel); + if ($allCpus = $this->_get_Win32_Processor()) { + $addresswidth = 0; + if (isset($allCpus[0]['AddressWidth']) && (($addresswidth = $allCpus[0]['AddressWidth']) > 0)) { + $kernel .= ' ('.$addresswidth.'-bit)'; + } + if (isset($allCpus[0]['Architecture'])) { + switch ($allCpus[0]['Architecture']) { + case 0: $kernel .= ' x86'; break; + case 1: $kernel .= ' MIPS'; break; + case 2: $kernel .= ' Alpha'; break; + case 3: $kernel .= ' PowerPC'; break; + case 5: $kernel .= ' ARM'; break; + case 6: $kernel .= ' ia64'; break; + case 9: if ($addresswidth == 32) { + $kernel .= ' x86'; + } else { + $kernel .= ' x64'; + } + break; + case 12: if ($addresswidth == 32) { + $kernel .= ' ARM'; + } else { + $kernel .= ' ARM64'; + } + } + } } - $this->sys->setDistribution($buffer[0]['Caption']); - - if ((($kernel[1] == ".") && ($kernel[0] <5)) || (substr($kernel, 0, 4) == "5.0.")) + $this->sys->setKernel($kernel); + $distribution = $buffer[0]['Caption']; + if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $buffer[0]['Caption']) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) { + $karray = preg_split('/\./', $ver); + if (isset($karray[2]) && isset($list['win10'][$karray[2]])) { + $distribution .= ' ('.$list['win10'][$karray[2]].')'; + } + } + $this->sys->setDistribution($distribution); + if (version_compare($ver, "5.1", "<")) $icon = 'Win2000.png'; - elseif ((substr($kernel, 0, 4) == "6.0.") || (substr($kernel, 0, 4) == "6.1.")) + elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<")) + $icon = 'WinXP.png'; + elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<")) $icon = 'WinVista.png'; - elseif ((substr($kernel, 0, 4) == "6.2.") || (substr($kernel, 0, 4) == "6.3.") || (substr($kernel, 0, 4) == "6.4.") || (substr($kernel, 0, 5) == "10.0.")) + elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<")) $icon = 'Win8.png'; else - $icon = 'WinXP.png'; + $icon = 'Win11.png'; $this->sys->setDistributionIcon($icon); - } elseif (CommonFunctions::executeProgram("cmd", "/c ver 2>nul", $ver_value, false)) { - if (preg_match("/ReactOS\r?\nVersion\s+(.+)/", $ver_value, $ar_temp)) { - $this->sys->setDistribution("ReactOS"); - $this->sys->setKernel($ar_temp[1]); + } elseif ($this->_ver !== "") { + if (preg_match("/ReactOS\r?\n\S+\s+(.+)/", $this->_ver, $ar_temp)) { + if (preg_match("/^(\d+\.\d+\.\d+[\S]*)(.+)$/", trim($ar_temp[1]), $ver_temp)) { + $this->sys->setDistribution("ReactOS ".trim($ver_temp[1])); + $this->sys->setKernel(trim($ver_temp[2])); + } else { + $this->sys->setDistribution("ReactOS"); + $this->sys->setKernel($ar_temp[1]); + } $this->sys->setDistributionIcon('ReactOS.png'); - } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*(.+)\]/", $ver_value, $ar_temp)) { - $this->sys->setDistribution($ar_temp[1]); - $this->sys->setKernel($ar_temp[2]); - $this->sys->setDistributionIcon('Win2000.png'); + } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*([\.\d]+)\]/", $this->_ver, $ar_temp)) { + $ver = $ar_temp[2]; + $kernel = $ver; + if (($this->_reg === false) && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false, false, true) && (strlen($strBuf) > 0)) { // only if reg query via cmd + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $tmpBuf, false)) { + $kernel .= ' (64-bit)'; + } + if (preg_match("/^Microsoft /", $strBuf)) { + $distribution = $strBuf; + } else { + $distribution = "Microsoft ".$strBuf; + } + } elseif (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false) && (strlen($strBuf) > 0)) { + if (preg_match("/^Microsoft /", $strBuf)) { + $distribution = $strBuf; + } else { + $distribution = "Microsoft ".$strBuf; + } + } else { + $distribution = $ar_temp[1]; + } + $this->sys->setKernel($kernel); + if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $this->sys->getDistribution()) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) { + if (version_compare($ver, "10.0.21996", ">=") && version_compare($ver, "11.0", "<")) { + $distribution = preg_replace("/Windows 10/", "Windows 11", $distribution); // fix Windows 11 detection + } + $karray = preg_split('/\./', $ver); + if (isset($karray[2]) && isset($list['win10'][$karray[2]])) { + $distribution .= ' ('.$list['win10'][$karray[2]].')'; + } + } + $this->sys->setDistribution($distribution); + if (version_compare($ver, "5.1", "<")) + $icon = 'Win2000.png'; + elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<")) + $icon = 'WinXP.png'; + elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<")) + $icon = 'WinVista.png'; + elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<")) + $icon = 'Win8.png'; + else + $icon = 'Win11.png'; + $this->sys->setDistributionIcon($icon); } else { - $this->sys->setDistribution("WinNT"); - $this->sys->setDistributionIcon('Win2000.png'); + $this->sys->setDistribution("WINNT"); + $this->sys->setDistributionIcon('WINNT.png'); } } else { - $this->sys->setDistribution("WinNT"); - $this->sys->setDistributionIcon('Win2000.png'); + $this->sys->setDistribution("WINNT"); + $this->sys->setDistributionIcon('WINNT.png'); } } @@ -289,18 +1105,29 @@ class WINNT extends OS */ private function _loadavg() { - $loadavg = ""; - $sum = 0; - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('LoadPercentage')); - if ($buffer) { + if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && isset($cpubuffer['cpu_Total'])) { + $this->sys->setLoad($cpubuffer['cpu_Total']); + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($cpubuffer['cpu_Total']); + } + } elseif ($buffer = $this->_get_Win32_Processor()) { + $loadok = true; + $sum = 0; foreach ($buffer as $load) { $value = $load['LoadPercentage']; - $loadavg .= $value.' '; - $sum += $value; + if ($value !== null) { + $sum += $value; + } else { + $loadok = false; + break; + } } - $this->sys->setLoad(trim($loadavg)); - if (PSI_LOAD_BAR) { - $this->sys->setLoadPercent($sum / count($buffer)); + if ($loadok) { + $percent = $sum / count($buffer); + $this->sys->setLoad($percent); + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($percent); + } } } } @@ -312,19 +1139,116 @@ class WINNT extends OS */ private function _cpuinfo() { - $allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('Name', 'L2CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'MaxClockSpeed')); - foreach ($allCpus as $oneCpu) { - $coreCount = 1; - if (isset($oneCpu['NumberOfCores'])) { - $coreCount = $oneCpu['NumberOfCores']; + $allCpus = $this->_get_Win32_Processor(); + if (empty($allCpus)) { + $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"; + if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) { + foreach ($arrBuf as $coreCount) { + if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\ProcessorNameString", $strBuf, false)) { + $allCpus[$coreCount]['Name'] = $strBuf; + } + if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\~MHz", $strBuf, false)) { + if (preg_match("/^0x([0-9a-f]+)$/i", $strBuf, $hexvalue)) { + $allCpus[$coreCount]['CurrentClockSpeed'] = hexdec($hexvalue[1]); + } + } + if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\VendorIdentifier", $strBuf, false)) { + $allCpus[$coreCount]['Manufacturer'] = $strBuf; + } + if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\Identifier", $strBuf, false)) { + $allCpus[$coreCount]['Caption'] = $strBuf; + } + } } - for ($i = 0; $i < $coreCount; $i++) { + } + + $globalcpus = 0; + foreach ($allCpus as $oneCpu) { + $cpuCount = 1; + if (isset($oneCpu['NumberOfLogicalProcessors'])) { + $cpuCount = $oneCpu['NumberOfLogicalProcessors']; + } elseif (isset($oneCpu['NumberOfCores'])) { + $cpuCount = $oneCpu['NumberOfCores']; + } + $globalcpus+=$cpuCount; + } + + $cpulist = null; + foreach ($allCpus as $oneCpu) { + $cpuCount = 1; + if (isset($oneCpu['NumberOfLogicalProcessors'])) { + $cpuCount = $oneCpu['NumberOfLogicalProcessors']; + } elseif (isset($oneCpu['NumberOfCores'])) { + $cpuCount = $oneCpu['NumberOfCores']; + } + for ($i = 0; $i < $cpuCount; $i++) { $cpu = new CpuDevice(); - $cpu->setModel($oneCpu['Name']); - $cpu->setCache($oneCpu['L2CacheSize'] * 1024); - $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']); - $cpu->setBusSpeed($oneCpu['ExtClock']); - if ($oneCpu['CurrentClockSpeed'] < $oneCpu['MaxClockSpeed']) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']); + if (isset($oneCpu['Name'])) $cpu->setModel($oneCpu['Name']); + if (isset($oneCpu['L3CacheSize']) && ($oneCpu['L3CacheSize'] > 0)) { + $cpu->setCache($oneCpu['L3CacheSize'] * 1024); + } elseif (isset($oneCpu['L2CacheSize']) && ($oneCpu['L2CacheSize'] > 0)) { + $cpu->setCache($oneCpu['L2CacheSize'] * 1024); + } + if (isset($oneCpu['CurrentVoltage']) && ($oneCpu['CurrentVoltage'] > 0)) { + $cpu->setVoltage($oneCpu['CurrentVoltage']/10); + } + if (isset($oneCpu['CurrentClockSpeed']) && ($oneCpu['CurrentClockSpeed'] > 0)) { + $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']); + if (isset($oneCpu['MaxClockSpeed']) && ($oneCpu['CurrentClockSpeed'] <= $oneCpu['MaxClockSpeed'])) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']); + } + if (isset($oneCpu['ExtClock']) && ($oneCpu['ExtClock'] > 0)) { + $cpu->setBusSpeed($oneCpu['ExtClock']); + } + if (isset($oneCpu['Manufacturer'])) { + $cpumanufacturer = $oneCpu['Manufacturer']; + $cpu->setVendorId($cpumanufacturer); + if ($cpumanufacturer === "QEMU") { + if (isset($oneCpu['Caption'])) { + $impl = ''; + if (preg_match('/^ARMv8 \(64-bit\) Family 8 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) { + switch (strtolower($partvar[1])) { + case '51': + $impl = '0x0'; break; // Qemu + case 'd03': + case 'd07': + case 'd08': + $impl = '0x41'; break; // ARM Limited + case '1': + $impl = '0x46'; // Fujitsu Ltd. + } + } elseif (preg_match('/^ARM Family 7 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) { + switch (strtolower($partvar[1])) { + case 'c07': + case 'c0f': + $impl = '0x41'; // ARM Limited + } + } + if ($impl !== '') { + if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true); + if ($cpulist) { + if ((isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1].',0x'.$partvar[2])])) + || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1])])) { + if (($cpumodel = $cpu->getModel()) !== '') { + $cpu->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]); + } else { + $cpu->setModel($cpulist['cpu'][$cpufromlist]); + } + } + } + } + } + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $this->sys->setVirtualizer("cpuid:QEMU", false); + } + } + } + if (PSI_LOAD_BAR) { + if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && (count($cpubuffer) == ($globalcpus+1)) && isset($cpubuffer['cpu'.$i])) { + $cpu->setLoad($cpubuffer['cpu'.$i]); + } elseif ((count($allCpus) == $globalcpus) && isset($oneCpu['LoadPercentage'])) { + $cpu->setLoad($oneCpu['LoadPercentage']); + } + } $this->sys->setCpus($cpu); } } @@ -337,18 +1261,85 @@ class WINNT extends OS */ private function _machine() { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Manufacturer', 'Model')); - if ($buffer) { - $buf = ""; + $buffer = $this->_get_Win32_ComputerSystem(); + $bufferp = self::getWMI(self::$_wmi, 'Win32_BaseBoard', array('Product')); + $bufferb = self::getWMI(self::$_wmi, 'Win32_BIOS', array('SMBIOSBIOSVersion', 'ReleaseDate')); + + if (!$buffer) { + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\systemManufacturer", $strBuf, false)) { + $buffer[0]['Manufacturer'] = $strBuf; + } + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemProductName", $strBuf, false)) { + $buffer[0]['Model'] = $strBuf; + } + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemFamily", $strBuf, false)) { + $buffer[0]['SystemFamily'] = $strBuf; + } + } + if (!$bufferp) { + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BaseBoardProduct", $strBuf, false)) { + $bufferp[0]['Product'] = $strBuf; + } + } + if (!$bufferb) { + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSVersion", $strBuf, false)) { + $bufferb[0]['SMBIOSBIOSVersion'] = $strBuf; + } + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSReleaseDate", $strBuf, false)) { + $bufferb[0]['ReleaseDate'] = $strBuf; + } + } + + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { if (isset($buffer[0]['Manufacturer'])) { - $buf .= ' '.$buffer[0]['Manufacturer']; + $this->_Manufacturer = $buffer[0]['Manufacturer']; } if (isset($buffer[0]['Model'])) { - $buf .= ' '.$buffer[0]['Model']; + $this->_Model = $buffer[0]['Model']; } - if (trim($buf) != "") { - $this->sys->setMachine(trim($buf)); + } + + $buf = ""; + $model = ""; + if ($buffer && isset($buffer[0])) { + if (isset($buffer[0]['Manufacturer']) && !preg_match("/^To be filled by O\.E\.M\.$|^System manufacturer$|^Not Specified$/i", $buf2=trim($buffer[0]['Manufacturer'])) && ($buf2 !== "")) { + $buf .= ' '.$buf2; } + + if (isset($buffer[0]['Model']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Product Name$|^Not Specified$/i", $buf2=trim($buffer[0]['Model'])) && ($buf2 !== "")) { + $model = $buf2; + $buf .= ' '.$buf2; + } + } + if ($bufferp && isset($bufferp[0])) { + if (isset($bufferp[0]['Product']) && !preg_match("/^To be filled by O\.E\.M\.$|^BaseBoard Product Name$|^Not Specified$|^Default string$/i", $buf2=trim($bufferp[0]['Product'])) && ($buf2 !== "")) { + if ($buf2 !== $model) { + $buf .= '/'.$buf2; + } elseif (isset($buffer[0]['SystemFamily']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Family$|^Not Specified$/i", $buf2=trim($buffer[0]['SystemFamily'])) && ($buf2 !== "")) { + $buf .= '/'.$buf2; + } + } + } + if ($bufferb && isset($bufferb[0])) { + $bver = ""; + $brel = ""; + if (isset($bufferb[0]['SMBIOSBIOSVersion']) && (($buf2=trim($bufferb[0]['SMBIOSBIOSVersion'])) !== "")) { + $bver .= ' '.$buf2; + } + if (isset($bufferb[0]['ReleaseDate'])) { + if (preg_match("/^(\d{4})(\d{2})(\d{2})\d{6}\.\d{6}\+\d{3}$/", $bufferb[0]['ReleaseDate'], $dateout)) { + $brel .= ' '.$dateout[2].'/'.$dateout[3].'/'.$dateout[1]; + } elseif (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $bufferb[0]['ReleaseDate'])) { + $brel .= ' '.$bufferb[0]['ReleaseDate']; + } + } + if ((trim($bver) !== "") || (trim($brel) !== "")) { + $buf .= ', BIOS'.$bver.$brel; + } + } + + if (trim($buf) != "") { + $this->sys->setMachine(trim($buf)); } } @@ -361,25 +1352,52 @@ class WINNT extends OS { foreach ($this->_devicelist('PCI') as $pciDev) { $dev = new HWDevice(); - $dev->setName($pciDev); + $dev->setName($pciDev['Name']); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (($pciDev['Manufacturer'] !== null) && preg_match("/^@[^\.]+\.inf,%([^%]+)%$/i", trim($pciDev['Manufacturer']), $mbuff)) { + $dev->setManufacturer($mbuff[1]); + } else { + $dev->setManufacturer($pciDev['Manufacturer']); + } + $dev->setProduct($pciDev['Product']); + } $this->sys->setPciDevices($dev); } foreach ($this->_devicelist('IDE') as $ideDev) { $dev = new HWDevice(); - $dev->setName($ideDev); + $dev->setName($ideDev['Name']); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setCapacity($ideDev['Capacity']); + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $dev->setSerial($ideDev['Serial']); + } + } $this->sys->setIdeDevices($dev); } foreach ($this->_devicelist('SCSI') as $scsiDev) { $dev = new HWDevice(); - $dev->setName($scsiDev); + $dev->setName($scsiDev['Name']); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setCapacity($scsiDev['Capacity']); + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $dev->setSerial($scsiDev['Serial']); + } + } $this->sys->setScsiDevices($dev); } foreach ($this->_devicelist('USB') as $usbDev) { $dev = new HWDevice(); - $dev->setName($usbDev); + $dev->setName($usbDev['Name']); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $dev->setManufacturer($usbDev['Manufacturer']); + $dev->setProduct($usbDev['Product']); + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) { + $dev->setSerial($usbDev['Serial']); + } + } $this->sys->setUsbDevices($dev); } } @@ -391,75 +1409,167 @@ class WINNT extends OS */ private function _network() { - $allDevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded')); - $allNetworkAdapterConfigurations = CommonFunctions::getWMI($this->_wmi, 'Win32_NetworkAdapterConfiguration', array('Description', 'MACAddress', 'IPAddress', 'SettingID')); - - foreach ($allDevices as $device) { - $dev = new NetDevice(); - $name=$device['Name']; - - if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name, $ar_name)) { //isatap device - foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) { - if ($ar_name[1]==$NetworkAdapterConfiguration['SettingID']) { - $dev->setName($NetworkAdapterConfiguration['Description']); - if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) { - $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress'])); - if (isset($NetworkAdapterConfiguration['IPAddress'])) - foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres) - if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres); - } - - break; - } - } + if (self::$_wmi) { + $buffer = $this->_get_Win32_OperatingSystem(); + if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "6.2", ">=")) { // minimal windows 2012 or windows 8 + $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkAdapter', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth')); + } else { + $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth')); } - if ($dev->getName() == "") { //no isatap or no isatap description - $cname=preg_replace('/[^A-Za-z0-9]/', '_', $name); //convert to canonical - if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name)) - $name=substr($name, 0, strlen($name)-strlen($ar_name[0])); - $dev->setName($name); - - if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) { - if (preg_replace('/[^A-Za-z0-9]/', '_', $NetworkAdapterConfiguration['Description']) == $cname) { - if (!is_null($dev->getInfo())) { - $dev->setInfo(''); //multiple with the same name - } else { - $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress'])); - if (isset($NetworkAdapterConfiguration['IPAddress'])) - foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres) - if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres)) - $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres); + if ($allDevices) { + $aliases = array(); + $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; + if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) { + foreach ($arrBuf as $netID) { + if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\PnPInstanceId", $strInstanceID, false)) { + if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$strInstanceID."\\FriendlyName", $strName, false)) { + $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical + if (!isset($aliases[$cname])) { // duplicate checking + $aliases[$cname]['id'] = $netID; + $aliases[$cname]['name'] = $strName; + if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\Name", $strCName, false) + && (str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strCName) !== $cname)) { + $aliases[$cname]['netname'] = $strCName; + } + } else { + $aliases[$cname]['id'] = ''; + } + } } } } - } - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp - // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that - // magative numbers would occour, try to calculate the nagative value from total - positive number - $txbytes = $device['BytesSentPersec']; - $rxbytes = $device['BytesReceivedPersec']; - if (($txbytes < 0) && ($rxbytes < 0)) { - $txbytes += 4294967296; - $rxbytes += 4294967296; - } elseif ($txbytes < 0) { - if ($device['BytesTotalPersec'] > $rxbytes) - $txbytes = $device['BytesTotalPersec'] - $rxbytes; - else - $txbytes += 4294967296; - } elseif ($rxbytes < 0) { - if ($device['BytesTotalPersec'] > $txbytes) - $rxbytes = $device['BytesTotalPersec'] - $txbytes; - else - $rxbytes += 4294967296; - } - $dev->setTxBytes($txbytes); - $dev->setRxBytes($rxbytes); - $dev->setErrors($device['PacketsReceivedErrors']); - $dev->setDrops($device['PacketsReceivedDiscarded']); + $aliases2 = array(); + $hkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) { + foreach ($arrBuf as $netCount) { + if (self::readReg($this->_reg, $hkey."\\".$netCount."\\Description", $strName, false) + && self::readReg($this->_reg, $hkey."\\".$netCount."\\ServiceName", $strGUID, false)) { + $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical + if (!isset($aliases2[$cname])) { // duplicate checking + $aliases2[$cname]['id'] = $strGUID; + $aliases2[$cname]['name'] = $strName; + } else { + $aliases2[$cname]['id'] = ''; + } + } + } + } - $this->sys->setNetDevices($dev); + $allNetworkAdapterConfigurations = self::getWMI(self::$_wmi, 'Win32_NetworkAdapterConfiguration', array('SettingID', /*'Description',*/ 'MACAddress', 'IPAddress')); + foreach ($allDevices as $device) if (!preg_match('/^WAN Miniport \[/', $device['Name'])) { + $dev = new NetDevice(); + $name = $device['Name']; + + if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name)) { + $dev->setName("Microsoft ISATAP Adapter"); + } else { + if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name)) { + $name=substr($name, 0, strlen($name)-strlen($ar_name[0])); + } + $dev->setName($name); + } + + $macexist = false; + if (((($ali=$aliases) && isset($ali[$name])) || (($ali=$aliases2) && isset($ali[$name]))) && isset($ali[$name]['id']) && ($ali[$name]['id'] !== "")) { + foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) { + if ($ali[$name]['id']==$NetworkAdapterConfiguration['SettingID']) { + $mininame = $ali[$name]['name']; + if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $mininame)) + $mininame="Microsoft ISATAP Adapter"; + elseif (preg_match('/\s-\s([^-]*)$/', $mininame, $ar_name)) + $name=substr($mininame, 0, strlen($mininame)-strlen($ar_name[0])); + $dev->setName($mininame); + if (isset($NetworkAdapterConfiguration['MACAddress']) && trim($NetworkAdapterConfiguration['MACAddress']) !== "") $macexist = true; + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) { + if (isset($ali[$name]['netname'])) $dev->setInfo(str_replace(';', ':', $ali[$name]['netname'])); + if ((!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) + && $macexist) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').str_replace(':', '-', strtoupper(trim($NetworkAdapterConfiguration['MACAddress'])))); + if (isset($NetworkAdapterConfiguration['IPAddress'])) + foreach ($NetworkAdapterConfiguration['IPAddress'] as $ipaddres) + if (($ipaddres != "0.0.0.0") && ($ipaddres != "::") && !preg_match('/^fe80::/i', $ipaddres)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres)); + } + + break; + } + } + } + + if ($macexist +// || ($device['CurrentBandwidth'] >= 1000000) + || ($device['BytesTotalPersec'] != 0) + || ($device['BytesSentPersec'] != 0) + || ($device['BytesReceivedPersec'] != 0) + || ($device['PacketsReceivedErrors'] != 0) + || ($device['PacketsReceivedDiscarded'] != 0)) { // hide unused + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) { + if (($speedinfo = $device['CurrentBandwidth']) >= 1000000) { + if ($speedinfo > 1000000000) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000000, 2)."Gb/s"); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000, 2)."Mb/s"); + } + } + } + + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp + // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that + // magative numbers would occour, try to calculate the nagative value from total - positive number + $txbytes = $device['BytesSentPersec']; + $rxbytes = $device['BytesReceivedPersec']; + if (($txbytes < 0) && ($rxbytes < 0)) { + $txbytes += 4294967296; + $rxbytes += 4294967296; + } elseif ($txbytes < 0) { + if ($device['BytesTotalPersec'] > $rxbytes) + $txbytes = $device['BytesTotalPersec'] - $rxbytes; + else + $txbytes += 4294967296; + } elseif ($rxbytes < 0) { + if ($device['BytesTotalPersec'] > $txbytes) + $rxbytes = $device['BytesTotalPersec'] - $txbytes; + else + $rxbytes += 4294967296; + } + $dev->setTxBytes($txbytes); + $dev->setRxBytes($rxbytes); + $dev->setErrors($device['PacketsReceivedErrors']); + $dev->setDrops($device['PacketsReceivedDiscarded']); + + $this->sys->setNetDevices($dev); + } + } + } + } elseif (($buffer = $this->_get_systeminfo()) && preg_match('/^(\s+)\[\d+\]:[^\r\n]+\r\n\s+[^\s\[]/m', $buffer, $matches, PREG_OFFSET_CAPTURE)) { + $netbuf = substr($buffer, $matches[0][1]); + if (preg_match('/^[^\s]/m', $netbuf, $matches2, PREG_OFFSET_CAPTURE)) { + $netbuf = substr($netbuf, 0, $matches2[0][1]); + } + $netstrs = preg_split('/^'.$matches[1][0].'\[\d+\]:/m', $netbuf, -1, PREG_SPLIT_NO_EMPTY); + $devnr = 0; + foreach ($netstrs as $netstr) { + $netstrls = preg_split('/\r\n/', $netstr, -1, PREG_SPLIT_NO_EMPTY); + if (sizeof($netstrls)>1) { + $dev = new NetDevice(); + foreach ($netstrls as $nr=>$netstrl) { + if ($nr === 0) { + $name = trim($netstrl); + if ($name !== "") { + $dev->setName($name); + } else { + $dev->setName('dev'.$devnr); + $devnr++; + } + } elseif (preg_match('/\[\d+\]:\s+(.+)/', $netstrl, $netinfo)) { + $ipaddres = trim($netinfo[1]); + if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres)); + } + } + $this->sys->setNetDevices($dev); + } + } } } @@ -472,23 +1582,30 @@ class WINNT extends OS */ private function _memory() { - $buffer = CommonFunctions::getWMI($this->_wmi, "Win32_OperatingSystem", array('TotalVisibleMemorySize', 'FreePhysicalMemory')); - if ($buffer) { - $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024); - $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024); + if (self::$_wmi) { + $buffer = $this->_get_Win32_OperatingSystem(); + if ($buffer) { + $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024); + $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024); + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); + } + $buffer = self::getWMI(self::$_wmi, 'Win32_PageFileUsage'); + foreach ($buffer as $swapdevice) { + $dev = new DiskDevice(); + $dev->setName("SWAP"); + $dev->setMountPoint($swapdevice['Name']); + $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024); + $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024); + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $dev->setFsType('swap'); + $this->sys->setSwapDevices($dev); + } + } elseif (($buffer = $this->_get_systeminfo()) && preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n/m", $buffer, $buffer2)) { +// && (preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n.*:\s+(\S+)\r\n/m", $buffer, $buffer2)) { + $this->sys->setMemTotal(preg_replace('/(\s)|(\xFF)/', '', $buffer2[1]) * 1024 * 1024); + $this->sys->setMemFree(preg_replace('/(\s)|(\xFF)/', '', $buffer2[2]) * 1024 * 1024); $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); } - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_PageFileUsage'); - foreach ($buffer as $swapdevice) { - $dev = new DiskDevice(); - $dev->setName("SWAP"); - $dev->setMountPoint($swapdevice['Name']); - $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024); - $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024); - $dev->setFree($dev->getTotal() - $dev->getUsed()); - $dev->setFsType('swap'); - $this->sys->setSwapDevices($dev); - } } /** @@ -500,11 +1617,13 @@ class WINNT extends OS { $typearray = array('Unknown', 'No Root Directory', 'Removable Disk', 'Local Disk', 'Network Drive', 'Compact Disc', 'RAM Disk'); $floppyarray = array('Unknown', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', 'Other', 'HD', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '8 in.'); - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType')); + $buffer = self::getWMI(self::$_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType')); foreach ($buffer as $filesystem) { $dev = new DiskDevice(); $dev->setMountPoint($filesystem['Name']); - $dev->setFsType($filesystem['FileSystem']); + if (isset($filesystem['FileSystem'])) { + $dev->setFsType($filesystem['FileSystem']); + } if ($filesystem['Size'] > 0) { $dev->setTotal($filesystem['Size']); $dev->setFree($filesystem['FreeSpace']); @@ -517,25 +1636,64 @@ class WINNT extends OS } $this->sys->setDiskDevices($dev); } - if (!$buffer && ($this->sys->getDistribution()=="ReactOS")) { - // test for command 'free' on current disk - if (CommonFunctions::executeProgram("cmd", "/c free 2>nul", $out_value, true)) { - for ($letter='A'; $letter!='AA'; $letter++) if (CommonFunctions::executeProgram("cmd", "/c free ".$letter.": 2>nul", $out_value, false)) { - if (preg_match('/\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*$/', $out_value, $out_dig)) { - $size = preg_replace('/(\.)|(\,)/', '', $out_dig[1]); - $used = preg_replace('/(\.)|(\,)/', '', $out_dig[2]); - $free = preg_replace('/(\.)|(\,)/', '', $out_dig[3]); + if (!$buffer && !defined('PSI_EMU_HOSTNAME')) { + $letters = array(); + if (CommonFunctions::executeProgram('fsutil', 'fsinfo drives 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/^Drives:\s*(.+)$/i', $out_value, $disks)) { + $diskarr = preg_split('/ /', $disks[1], -1, PREG_SPLIT_NO_EMPTY); + foreach ($diskarr as $disk) if (preg_match('/^(\w):\\\\$/', $disk, $diskletter)) { + $letters[] = $diskletter[1]; + } + } + if (count($letters) == 0) for ($letter='A'; $letter!='AA'; $letter++) { + $letters[] = $letter; + } + if ((substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('cmd', '/c free 2>nul', $out_value, false)) { + foreach ($letters as $letter) if (CommonFunctions::executeProgram('cmd', '/c free '.$letter.': 2>nul', $out_value, false)) { + $values = preg_replace('/[^\d\n]/', '', $out_value); + if (preg_match('/\n(\d+)\n(\d+)\n(\d+)$/', $values, $out_dig)) { + $size = $out_dig[1]; + $used = $out_dig[2]; + $free = $out_dig[3]; if ($used + $free == $size) { $dev = new DiskDevice(); $dev->setMountPoint($letter.":"); - $dev->setFsType('Unknown'); + if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.':\ 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) { + $dev->setFsType($fsname[1]); + } else { + $dev->setFsType('Unknown'); + } + $dev->setName('Unknown'); $dev->setTotal($size); - $dev->setFree($free); $dev->setUsed($used); + $dev->setFree($free); $this->sys->setDiskDevices($dev); } } } + } else { + if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") { + $disksep = ':\\'; + } else { + $disksep = ':'; + } + foreach ($letters as $letter) { + $size = disk_total_space($letter.':\\'); + $free = disk_free_space($letter.':\\'); + if (($size !== false) && ($free !== false) && ($size >= 0) && ($free >= 0) && ($size >= $free)) { + $dev = new DiskDevice(); + $dev->setMountPoint($letter.":"); + if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.$disksep.' 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) { + $dev->setFsType($fsname[1]); + } else { + $dev->setFsType('Unknown'); + } + $dev->setName('Unknown'); + $dev->setTotal($size); + $dev->setUsed($size - $free); + $dev->setFree($free); + $this->sys->setDiskDevices($dev); + } + } } } } @@ -567,43 +1725,231 @@ class WINNT extends OS public function _processes() { $processes['*'] = 0; - if (CommonFunctions::executeProgram("qprocess", "*", $strBuf, false) && (strlen(trim($strBuf)) > 0)) { + if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('qprocess', '*', $strBuf, false) && (strlen($strBuf) > 0)) { $lines = preg_split('/\n/', $strBuf); - $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *" + $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *" } if ($processes['*'] <= 0) { - $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption')); + $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption')); $processes['*'] = count($buffer); } $processes[' '] = $processes['*']; $this->sys->setProcesses($processes); } + /** + * MEM information + * + * @return void + */ + private function _meminfo() + { + $allMems = self::_get_Win32_PhysicalMemory(); + if ($allMems) { + $reg = false; + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + $arrMems = self::getWMI(self::$_wmi, 'Win32_PhysicalMemoryArray', array('MemoryErrorCorrection')); + $reg = (count($arrMems) == 1) && isset($arrMems[0]['MemoryErrorCorrection']) && ($arrMems[0]['MemoryErrorCorrection'] == 6); + } + foreach ($allMems as $mem) { + $dev = new HWDevice(); + $name = ''; + if (isset($mem['PartNumber']) && !preg_match("/^PartNum\d+$/", $part = $mem['PartNumber']) && ($part != '') && ($part != 'None') && ($part != 'N/A') && ($part != 'NOT AVAILABLE')) { + $name = $part; + } + if (isset($mem['DeviceLocator']) && (($dloc = $mem['DeviceLocator']) != '') && ($dloc != 'None') && ($dloc != 'N/A')) { + if ($name != '') { + $name .= ' - '.$dloc; + } else { + $name = $dloc; + } + } + if (isset($mem['BankLabel']) && (($bank = $mem['BankLabel']) != '') && ($bank != 'None') && ($bank != 'N/A')) { + if ($name != '') { + $name .= ' in '.$bank; + } else { + $name = 'Physical Memory in '.$bank; + } + } + if ($name != '') { + $dev->setName(trim($name)); + } else { + $dev->setName('Physical Memory'); + } + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if (isset($mem['Manufacturer']) && !preg_match("/^([A-F\d]{4}|[A-F\d]{12}|[A-F\d]{16})$/", $manufacturer = $mem['Manufacturer']) && !preg_match("/^Manufacturer\d+$/", $manufacturer) && !preg_match("/^Mfg \d+$/", $manufacturer) && ($manufacturer != '') && ($manufacturer != 'None') && ($manufacturer != 'N/A') && ($manufacturer != 'UNKNOWN')) { + $dev->setManufacturer($manufacturer); + } + if (isset($mem['Capacity'])) { + $dev->setCapacity($mem['Capacity']); + } + $memtype = ''; + if (isset($mem['MemoryType']) && (($memval = $mem['MemoryType']) != 0)) { + switch ($memval) { +// case 0: $memtype = 'Unknown'; break; +// case 1: $memtype = 'Other'; break; + case 2: $memtype = 'DRAM'; break; + case 3: $memtype = 'Synchronous DRAM'; break; + case 4: $memtype = 'Cache DRAM'; break; + case 5: $memtype = 'EDO'; break; + case 6: $memtype = 'EDRAM'; break; + case 7: $memtype = 'VRAM'; break; + case 8: $memtype = 'SRAM'; break; + case 9: $memtype = 'RAM'; break; + case 10: $memtype = 'ROM'; break; + case 11: $memtype = 'Flash'; break; + case 12: $memtype = 'EEPROM'; break; + case 13: $memtype = 'FEPROM'; break; + case 14: $memtype = 'EPROM'; break; + case 15: $memtype = 'CDRAM'; break; + case 16: $memtype = '3DRAM'; break; + case 17: $memtype = 'SDRAM'; break; + case 18: $memtype = 'SGRAM'; break; + case 19: $memtype = 'RDRAM'; break; + case 20: $memtype = 'DDR'; break; + case 21: $memtype = 'DDR2'; break; + case 22: $memtype = 'DDR2 FB-DIMM'; break; + case 24: $memtype = 'DDR3'; break; + case 25: $memtype = 'FBD2'; break; + case 26: $memtype = 'DDR4'; + } + } elseif (isset($mem['SMBIOSMemoryType'])) { + switch ($mem['SMBIOSMemoryType']) { +// case 0: $memtype = 'Invalid'; break; +// case 1: $memtype = 'Other'; break; +// case 2: $memtype = 'Unknown'; break; + case 3: $memtype = 'DRAM'; break; + case 4: $memtype = 'EDRAM'; break; + case 5: $memtype = 'VRAM'; break; + case 6: $memtype = 'SRAM'; break; + case 7: $memtype = 'RAM'; break; + case 8: $memtype = 'ROM'; break; + case 9: $memtype = 'FLASH'; break; + case 10: $memtype = 'EEPROM'; break; + case 11: $memtype = 'FEPROM'; break; + case 12: $memtype = 'EPROM'; break; + case 13: $memtype = 'CDRAM'; break; + case 14: $memtype = '3DRAM'; break; + case 15: $memtype = 'SDRAM'; break; + case 16: $memtype = 'SGRAM'; break; + case 17: $memtype = 'RDRAM'; break; + case 18: $memtype = 'DDR'; break; + case 19: $memtype = 'DDR2'; break; + case 20: $memtype = 'DDR2 FB-DIMM'; break; + case 24: $memtype = 'DDR3'; break; + case 25: $memtype = 'FBD2'; break; + case 26: $memtype = 'DDR4'; break; + case 27: $memtype = 'LPDDR'; break; + case 28: $memtype = 'LPDDR2'; break; + case 29: $memtype = 'LPDDR3'; break; + case 30: $memtype = 'DDR3'; break; + case 31: $memtype = 'FBD2'; break; + case 32: $memtype = 'Logical non-volatile device'; break; + case 33: $memtype = 'HBM2'; break; + case 34: $memtype = 'DDR5'; break; + case 35: $memtype = 'LPDDR5'; + } + } + if (isset($mem['Speed']) && (($speed = $mem['Speed']) > 0) && (preg_match('/^(DDR\d*)(.*)/', $memtype, $dr) || preg_match('/^(SDR)AM(.*)/', $memtype, $dr))) { + if (isset($mem['MinVoltage']) && isset($mem['MaxVoltage']) && (($minv = $mem['MinVoltage']) > 0) && (($maxv = $mem['MaxVoltage']) > 0) && ($minv < $maxv)) { + $lv = 'L'; + } else { + $lv = ''; + } + if (isset($dr[2])) { + $memtype = $dr[1].$lv.'-'.$speed.' '.$dr[2]; + } else { + $memtype = $dr[1].$lv.'-'.$speed; + } + } + if (isset($mem['FormFactor'])) { + switch ($mem['FormFactor']) { +// case 0: $memtype .= ' Unknown'; break; +// case 1: $memtype .= ' Other'; break; + case 2: $memtype .= ' SIP'; break; + case 3: $memtype .= ' DIP'; break; + case 4: $memtype .= ' ZIP'; break; + case 5: $memtype .= ' SOJ'; break; + case 6: $memtype .= ' Proprietary'; break; + case 7: $memtype .= ' SIMM'; break; + case 8: $memtype .= ' DIMM'; break; + case 9: $memtype .= ' TSOPO'; break; + case 10: $memtype .= ' PGA'; break; + case 11: $memtype .= ' RIM'; break; + case 12: $memtype .= ' SODIMM'; break; + case 13: $memtype .= ' SRIMM'; break; + case 14: $memtype .= ' SMD'; break; + case 15: $memtype .= ' SSMP'; break; + case 16: $memtype .= ' QFP'; break; + case 17: $memtype .= ' TQFP'; break; + case 18: $memtype .= ' SOIC'; break; + case 19: $memtype .= ' LCC'; break; + case 20: $memtype .= ' PLCC'; break; + case 21: $memtype .= ' BGA'; break; + case 22: $memtype .= ' FPBGA'; break; + case 23: $memtype .= ' LGA'; + } + } + if (isset($mem['DataWidth']) && isset($mem['TotalWidth']) && (($dataw = $mem['DataWidth']) > 0) && (($totalw = $mem['TotalWidth']) > 0) && ($dataw < $totalw)) { + $memtype .= ' ECC'; + } + if ($reg) { + $memtype .= ' REG'; + } + if (($memtype = trim($memtype)) != '') { + $dev->setProduct($memtype); + } + if (isset($mem['ConfiguredClockSpeed']) && (($clock = $mem['ConfiguredClockSpeed']) > 0)) { + $dev->setSpeed($clock); + } + if (isset($mem['ConfiguredVoltage']) && (($voltage = $mem['ConfiguredVoltage']) > 0)) { + $dev->setVoltage($voltage/1000); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && + isset($mem['SerialNumber']) && !preg_match("/^SerNum\d+$/", $serial = $mem['SerialNumber']) && ($serial != '') && ($serial != 'None')) { + $dev->setSerial($serial); + } + } + $this->sys->setMemDevices($dev); + } + } + } /** * get the information * * @see PSI_Interface_OS::build() * - * @return Void + * @return void */ public function build() { - $this->_distro(); - if ($this->sys->getDistribution()=="ReactOS") { - $this->error->addError("WARN", "The ReactOS version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); // share getDistribution() + if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") { + $this->error->addWarning("The ReactOS version of phpSysInfo is a work in progress, some things currently don't work"); + } + if (!$this->blockname || $this->blockname==='vitals') { + $this->_hostname(); + $this->_users(); + $this->_uptime(); + $this->_loadavg(); + $this->_processes(); + } + if (!$this->blockname || $this->blockname==='hardware') { + $this->_machine(); + $this->_cpuinfo(); + $this->_virtualizer(); + $this->_meminfo(); + $this->_hardware(); + } + if (!$this->blockname || $this->blockname==='memory') { + $this->_memory(); + } + if (!$this->blockname || $this->blockname==='filesystem') { + $this->_filesystems(); + } + if (!$this->blockname || $this->blockname==='network') { + $this->_network(); } - $this->_hostname(); - $this->_ip(); - $this->_users(); - $this->_machine(); - $this->_uptime(); - $this->_cpuinfo(); - $this->_network(); - $this->_hardware(); - $this->_filesystems(); - $this->_memory(); - $this->_loadavg(); - $this->_processes(); } } diff --git a/root/opt/phpsysinfo/includes/output/class.Output.inc.php b/root/opt/phpsysinfo/includes/output/class.Output.inc.php index 4d561e3..7872b53 100644 --- a/root/opt/phpsysinfo/includes/output/class.Output.inc.php +++ b/root/opt/phpsysinfo/includes/output/class.Output.inc.php @@ -8,7 +8,7 @@ * @package PSI_Output * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Output.inc.php 569 2012-04-16 06:08:18Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_Output * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,7 +28,7 @@ abstract class Output /** * error object for logging errors * - * @var Error + * @var PSI_Error */ protected $error; @@ -37,11 +37,9 @@ abstract class Output */ public function __construct() { - $this->error = Error::singleton(); + $this->error = PSI_Error::singleton(); $this->_checkConfig(); CommonFunctions::checkForExtensions(); -// $this->error = Error::singleton(); -// $this->_checkConfig(); } /** @@ -51,7 +49,7 @@ abstract class Output */ private function _checkConfig() { - include_once APP_ROOT.'/read_config.php'; + include_once PSI_APP_ROOT.'/read_config.php'; if ($this->error->errorsExist()) { $this->error->errorsAsXML(); diff --git a/root/opt/phpsysinfo/includes/output/class.Template.inc.php b/root/opt/phpsysinfo/includes/output/class.Template.inc.php index 3fa71ce..830448a 100644 --- a/root/opt/phpsysinfo/includes/output/class.Template.inc.php +++ b/root/opt/phpsysinfo/includes/output/class.Template.inc.php @@ -8,7 +8,7 @@ * @package PSI_Output * @author Damien Roth * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Output.inc.php 315 2009-09-02 15:48:31Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_Output * @author Damien Roth * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,14 +28,14 @@ class Template /** * Vars used in the template * - * @Array + * @var array */ private $_vars; /** * Template file * - * @String + * @var string */ private $_file; @@ -53,8 +53,8 @@ class Template /** * Set a template variable. * - * @param string variable name - * @param string variable value + * @param string $name variable name + * @param string|array|Template $value variable value */ public function set($name, $value) { @@ -80,7 +80,7 @@ class Template // Start output buffering ob_start(); - include(APP_ROOT.$file); + include(PSI_APP_ROOT.$file); // Get the contents of the buffer $contents = ob_get_contents(); diff --git a/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php index 2d27fea..6a2b6c7 100644 --- a/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php +++ b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php @@ -8,7 +8,7 @@ * @package PSI_Web * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.Webpage.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,45 +19,82 @@ * @package PSI_Web * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ class Webpage extends Output implements PSI_Interface_Output { + /** + * configured indexname + * + * @var string + */ + private $_indexname; + /** * configured language * - * @var String + * @var string */ private $_language; /** * configured template * - * @var String + * @var string */ private $_template; /** * all available templates * - * @var Array + * @var array */ private $_templates = array(); + /** + * configured bootstrap template + * + * @var string + */ + private $_bootstrap_template; + + /** + * all available bootstrap templates + * + * @var array + */ + private $_bootstrap_templates = array(); + /** * all available languages * - * @var Array + * @var array */ private $_languages = array(); /** - * check for all extensions that are needed, initialize needed vars and read phpsysinfo.ini + * configured show picklist language + * + * @var boolean */ - public function __construct() + private $_pick_language; + + /** + * configured show picklist template + * + * @var boolean + */ + private $_pick_template; + + /** + * check for all extensions that are needed, initialize needed vars and read phpsysinfo.ini + * @param string $indexname + */ + public function __construct($indexname="dynamic") { + $this->_indexname = $indexname; parent::__construct(); $this->_getTemplateList(); $this->_getLanguageList(); @@ -71,15 +108,18 @@ class Webpage extends Output implements PSI_Interface_Output */ private function _checkTemplateLanguage() { - $this->_template = trim(strtolower(PSI_DEFAULT_TEMPLATE)); - if (!file_exists(APP_ROOT.'/templates/'.$this->_template.".css")) { + if (!defined("PSI_DEFAULT_TEMPLATE") || (($this->_template = strtolower(trim(PSI_DEFAULT_TEMPLATE))) == "") || !file_exists(PSI_APP_ROOT.'/templates/'.$this->_template.".css")) { $this->_template = 'phpsysinfo'; } + if (!defined("PSI_DEFAULT_BOOTSTRAP_TEMPLATE") || (($this->_bootstrap_template = strtolower(trim(PSI_DEFAULT_BOOTSTRAP_TEMPLATE))) == "") || !file_exists(PSI_APP_ROOT.'/templates/'.$this->_bootstrap_template."_bootstrap.css")) { + $this->_bootstrap_template = 'phpsysinfo'; + } + $this->_pick_template = !defined("PSI_SHOW_PICKLIST_TEMPLATE") || (PSI_SHOW_PICKLIST_TEMPLATE !== false); - $this->_language = trim(strtolower(PSI_DEFAULT_LANG)); - if (!file_exists(APP_ROOT.'/language/'.$this->_language.".xml")) { + if (!defined("PSI_DEFAULT_LANG") || (($this->_language = strtolower(trim(PSI_DEFAULT_LANG))) == "") || !file_exists(PSI_APP_ROOT.'/language/'.$this->_language.".xml")) { $this->_language = 'en'; } + $this->_pick_language = !defined("PSI_SHOW_PICKLIST_LANG") || (PSI_SHOW_PICKLIST_LANG !== false); } /** @@ -89,13 +129,17 @@ class Webpage extends Output implements PSI_Interface_Output */ private function _getTemplateList() { - $dirlist = CommonFunctions::gdc(APP_ROOT.'/templates/'); + $dirlist = CommonFunctions::gdc(PSI_APP_ROOT.'/templates/'); sort($dirlist); foreach ($dirlist as $file) { $tpl_ext = substr($file, strlen($file) - 4); $tpl_name = substr($file, 0, strlen($file) - 4); - if (($tpl_ext === ".css") && ($tpl_name !== "phpsysinfo_bootstrap")) { - array_push($this->_templates, $tpl_name); + if ($tpl_ext === ".css") { + if (preg_match("/(\S+)_bootstrap$/", $tpl_name, $ar_buf)) { + array_push($this->_bootstrap_templates, $ar_buf[1]); + } else { + array_push($this->_templates, $tpl_name); + } } } } @@ -107,11 +151,11 @@ class Webpage extends Output implements PSI_Interface_Output */ private function _getLanguageList() { - $dirlist = CommonFunctions::gdc(APP_ROOT.'/language/'); + $dirlist = CommonFunctions::gdc(PSI_APP_ROOT.'/language/'); sort($dirlist); foreach ($dirlist as $file) { - $lang_ext = substr($file, strlen($file) - 4); - $lang_name = substr($file, 0, strlen($file) - 4); + $lang_ext = strtolower(substr($file, strlen($file) - 4)); + $lang_name = strtolower(substr($file, 0, strlen($file) - 4)); if ($lang_ext == ".xml") { array_push($this->_languages, $lang_name); } @@ -127,12 +171,52 @@ class Webpage extends Output implements PSI_Interface_Output { $this->_checkTemplateLanguage(); - $tpl = new Template("/templates/html/index_dynamic.html"); + $tpl = new Template("/templates/html/index_".$this->_indexname.".html"); $tpl->set("template", $this->_template); $tpl->set("templates", $this->_templates); + $tpl->set("bootstraptemplate", $this->_bootstrap_template); + $tpl->set("bootstraptemplates", $this->_bootstrap_templates); + $tpl->set("picktemplate", $this->_pick_template); $tpl->set("language", $this->_language); $tpl->set("languages", $this->_languages); + $tpl->set("picklanguage", $this->_pick_language); + $tpl->set("showCPUListExpanded", defined('PSI_SHOW_CPULIST_EXPANDED') ? (PSI_SHOW_CPULIST_EXPANDED ? 'true' : 'false') : 'true'); + $tpl->set("showCPUInfoExpanded", defined('PSI_SHOW_CPUINFO_EXPANDED') ? (PSI_SHOW_CPUINFO_EXPANDED ? 'true' : 'false') : 'false'); + $tpl->set("showNetworkInfosExpanded", defined('PSI_SHOW_NETWORK_INFOS_EXPANDED') ? (PSI_SHOW_NETWORK_INFOS_EXPANDED ? 'true' : 'false') : 'false'); + $tpl->set("showMemoryInfosExpanded", defined('PSI_SHOW_MEMORY_INFOS_EXPANDED') ? (PSI_SHOW_MEMORY_INFOS_EXPANDED ? 'true' : 'false') : 'false'); + $tpl->set("showNetworkActiveSpeed", defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') ? (PSI_SHOW_NETWORK_ACTIVE_SPEED ? ((strtolower(PSI_SHOW_NETWORK_ACTIVE_SPEED) === 'bps') ? 'bps' :'true') : 'false') : 'false'); + $tpl->set("showCPULoadCompact", defined('PSI_LOAD_BAR') ? ((strtolower(PSI_LOAD_BAR) === 'compact') ? 'true' :'false') : 'false'); + $tpl->set("hideBootstrapLoader", defined('PSI_HIDE_BOOTSTRAP_LOADER') ? (PSI_HIDE_BOOTSTRAP_LOADER ? 'true' : 'false') : 'false'); + $tpl->set("increaseWidth", defined('PSI_INCREASE_WIDTH') ? ((intval(PSI_INCREASE_WIDTH)>0) ? intval(PSI_INCREASE_WIDTH) : 0) : 0); + $tpl->set("hideTotals", defined('PSI_HIDE_TOTALS') ? (PSI_HIDE_TOTALS ? 'true' : 'false') : 'false'); + if (defined('PSI_BLOCKS')) { + if (is_string(PSI_BLOCKS)) { + if (preg_match(ARRAY_EXP, PSI_BLOCKS)) { + $blocks = eval(strtolower(PSI_BLOCKS)); + } else { + $blocks = array(strtolower(PSI_BLOCKS)); + } + $blocklist = ''; + $validblocks = array('vitals','hardware','memory','filesystem','network','voltage','current','temperature','fans','power','other','ups'); + foreach ($blocks as $block) { + if (in_array($block, $validblocks)) { + if (empty($blocklist)) { + $blocklist = $block; + } else { + $blocklist .= ','.$block; + } + } + } + if (!empty($blocklist)) { + $tpl->set("blocks", $blocklist); + } + } elseif (PSI_BLOCKS) { + $tpl->set("blocks", 'true'); + } + } else { + $tpl->set("blocks", 'true'); + } echo $tpl->fetch(); } diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php index 43c226d..0c59a67 100644 --- a/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php +++ b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php @@ -8,7 +8,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.WebpageXML.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -32,13 +32,6 @@ class WebpageXML extends Output implements PSI_Interface_Output */ private $_xml; - /** - * only plugin xml - * - * @var boolean - */ - private $_pluginRequest = false; - /** * complete xml * @@ -53,6 +46,13 @@ class WebpageXML extends Output implements PSI_Interface_Output */ private $_pluginName = null; + /** + * name of the block + * + * @var string + */ + private $_blockName = null; + /** * generate the output * @@ -60,82 +60,161 @@ class WebpageXML extends Output implements PSI_Interface_Output */ private function _prepare() { - if (!$this->_pluginRequest) { - // Figure out which OS we are running on, and detect support - if (!file_exists(APP_ROOT.'/includes/os/class.'.PSI_OS.'.inc.php')) { - $this->error->addError("file_exists(class.".PSI_OS.".inc.php)", PSI_OS." is not currently supported"); + if ($this->_pluginName === null) { + if ((PSI_OS == 'Linux') && defined('PSI_SSH_HOSTNAME') && defined('PSI_SSH_USER') && defined('PSI_SSH_PASSWORD')) { + $fgthost = preg_split("/:/", PSI_SSH_HOSTNAME, -1, PREG_SPLIT_NO_EMPTY); + define('PSI_EMU_HOSTNAME', trim($fgthost[0])); + if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) { + define('PSI_EMU_PORT', trim($fgthost[1])); + } else { + define('PSI_EMU_PORT', 22); + } + define('PSI_EMU_USER', PSI_SSH_USER); + define('PSI_EMU_PASSWORD', PSI_SSH_PASSWORD); + if (defined('PSI_SSH_ADD_PATHS')) { + define('PSI_EMU_ADD_PATHS', PSI_SSH_ADD_PATHS); + } + if (defined('PSI_SSH_ADD_OPTIONS')) { + define('PSI_EMU_ADD_OPTIONS', PSI_SSH_ADD_OPTIONS); + } + if (!file_exists(PSI_APP_ROOT.'/includes/os/class.Linux.inc.php')) { + $this->error->addError("file_exists(class.Linux.inc.php)", "Linux is not currently supported"); + } + } elseif (((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) && defined('PSI_WMI_HOSTNAME')) { + define('PSI_EMU_HOSTNAME', PSI_WMI_HOSTNAME); + if (defined('PSI_WMI_USER') && defined('PSI_WMI_PASSWORD')) { + define('PSI_EMU_USER', PSI_WMI_USER); + define('PSI_EMU_PASSWORD', PSI_WMI_PASSWORD); + } else { + define('PSI_EMU_USER', null); + define('PSI_EMU_PASSWORD', null); + } + if (!file_exists(PSI_APP_ROOT.'/includes/os/class.WINNT.inc.php')) { + $this->error->addError("file_exists(class.WINNT.inc.php)", "WINNT is not currently supported"); + } + } else { + // Figure out which OS we are running on, and detect support + if (!file_exists(PSI_APP_ROOT.'/includes/os/class.'.PSI_OS.'.inc.php')) { + $this->error->addError("file_exists(class.".PSI_OS.".inc.php)", PSI_OS." is not currently supported"); + } } - // check if there is a valid sensor configuration in phpsysinfo.ini - $foundsp = array(); - if (defined('PSI_SENSOR_PROGRAM') && is_string(PSI_SENSOR_PROGRAM)) { - if (preg_match(ARRAY_EXP, PSI_SENSOR_PROGRAM)) { - $sensorprograms = eval(strtolower(PSI_SENSOR_PROGRAM)); - } else { - $sensorprograms = array(strtolower(PSI_SENSOR_PROGRAM)); - } - foreach ($sensorprograms as $sensorprogram) { - if (!file_exists(APP_ROOT.'/includes/mb/class.'.$sensorprogram.'.inc.php')) { - $this->error->addError("file_exists(class.".htmlspecialchars($sensorprogram).".inc.php)", "specified sensor program is not supported"); + if (!defined('PSI_MBINFO') && (!$this->_blockName || in_array($this->_blockName, array('mbinfo','voltage','current','temperature','fans','power','other')))) { + // check if there is a valid sensor configuration in phpsysinfo.ini + $foundsp = array(); + if (defined('PSI_SENSOR_PROGRAM') && is_string(PSI_SENSOR_PROGRAM)) { + if (preg_match(ARRAY_EXP, PSI_SENSOR_PROGRAM)) { + $sensorprograms = eval(strtolower(PSI_SENSOR_PROGRAM)); } else { - $foundsp[] = $sensorprogram; + $sensorprograms = array(strtolower(PSI_SENSOR_PROGRAM)); + } + foreach ($sensorprograms as $sensorprogram) { + if (!file_exists(PSI_APP_ROOT.'/includes/mb/class.'.$sensorprogram.'.inc.php')) { + $this->error->addError("file_exists(class.".htmlspecialchars($sensorprogram).".inc.php)", "specified sensor program is not supported"); + } else { + $foundsp[] = $sensorprogram; + } } } + + /** + * motherboard information + * + * @var string serialized array + */ + define('PSI_MBINFO', serialize($foundsp)); } - /** - * motherboard information - * - * @var serialized array - */ - define('PSI_MBINFO', serialize($foundsp)); - - // check if there is a valid hddtemp configuration in phpsysinfo.ini - $found = false; - if (PSI_HDD_TEMP !== false) { - $found = true; - } - /** - * hddtemp information available or not - * - * @var boolean - */ - define('PSI_HDDTEMP', $found); - - // check if there is a valid ups configuration in phpsysinfo.ini - $foundup = array(); - if (defined('PSI_UPS_PROGRAM') && is_string(PSI_UPS_PROGRAM)) { - if (preg_match(ARRAY_EXP, PSI_UPS_PROGRAM)) { - $upsprograms = eval(strtolower(PSI_UPS_PROGRAM)); - } else { - $upsprograms = array(strtolower(PSI_UPS_PROGRAM)); - } - foreach ($upsprograms as $upsprogram) { - if (!file_exists(APP_ROOT.'/includes/ups/class.'.$upsprogram.'.inc.php')) { - $this->error->addError("file_exists(class.".htmlspecialchars($upsprogram).".inc.php)", "specified UPS program is not supported"); + if (!defined('PSI_UPSINFO') && (!$this->_blockName || ($this->_blockName==='ups'))) { + // check if there is a valid ups configuration in phpsysinfo.ini + $foundup = array(); + if (defined('PSI_UPS_PROGRAM') && is_string(PSI_UPS_PROGRAM)) { + if (preg_match(ARRAY_EXP, PSI_UPS_PROGRAM)) { + $upsprograms = eval(strtolower(PSI_UPS_PROGRAM)); } else { - $foundup[] = $upsprogram; + $upsprograms = array(strtolower(PSI_UPS_PROGRAM)); + } + foreach ($upsprograms as $upsprogram) { + if (!file_exists(PSI_APP_ROOT.'/includes/ups/class.'.$upsprogram.'.inc.php')) { + $this->error->addError("file_exists(class.".htmlspecialchars($upsprogram).".inc.php)", "specified UPS program is not supported"); + } else { + $foundup[] = $upsprogram; + } } } + /** + * ups information + * + * @var string serialized array + */ + define('PSI_UPSINFO', serialize($foundup)); } - /** - * ups information - * - * @var serialized array - */ - define('PSI_UPSINFO', serialize($foundup)); // if there are errors stop executing the script until they are fixed if ($this->error->errorsExist()) { $this->error->errorsAsXML(); } - } - // Create the XML - if ($this->_pluginRequest) { - $this->_xml = new XML(false, $this->_pluginName); + // Create the XML + $this->_xml = new XML($this->_completeXML, '', $this->_blockName); } else { - $this->_xml = new XML($this->_completeXML); + if ((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) { + $plugname = strtoupper(trim($this->_pluginName)); + if ((PSI_OS == 'Linux') && defined('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME') && defined('PSI_PLUGIN_'.$plugname.'_SSH_USER') && defined('PSI_PLUGIN_'.$plugname.'_SSH_PASSWORD')) { + $fgthost = preg_split("/:/", constant('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME'), -1, PREG_SPLIT_NO_EMPTY); + define('PSI_EMU_HOSTNAME', trim($fgthost[0])); + if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) { + define('PSI_EMU_PORT', trim($fgthost[1])); + } else { + define('PSI_EMU_PORT', 22); + } + define('PSI_EMU_USER', constant('PSI_PLUGIN_'.$plugname.'_SSH_USER')); + define('PSI_EMU_PASSWORD', constant('PSI_PLUGIN_'.$plugname.'_SSH_PASSWORD')); + if (defined('PSI_PLUGIN_'.$plugname.'_SSH_ADD_PATHS')) { + define('PSI_EMU_ADD_PATHS', constant('PSI_PLUGIN_'.$plugname.'_SSH_ADD_PATHS')); + } + if (defined('PSI_PLUGIN_'.$plugname.'_SSH_ADD_OPTIONS')) { + define('PSI_EMU_ADD_OPTIONS', constant('PSI_PLUGIN_'.$plugname.'_SSH_ADD_OPTIONS')); + } + } elseif (defined('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME')) { + define('PSI_EMU_HOSTNAME', constant('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME')); + if (defined('PSI_PLUGIN_'.$plugname.'_WMI_USER') && defined('PSI_PLUGIN_'.$plugname.'_WMI_PASSWORD')) { + define('PSI_EMU_USER', constant('PSI_PLUGIN_'.$plugname.'_WMI_USER')); + define('PSI_EMU_PASSWORD', constant('PSI_PLUGIN_'.$plugname.'_WMI_PASSWORD')); + } else { + define('PSI_EMU_USER', null); + define('PSI_EMU_PASSWORD', null); + } + } elseif ((PSI_OS == 'Linux') && defined('PSI_SSH_HOSTNAME') && defined('PSI_SSH_USER') && defined('PSI_SSH_PASSWORD')) { + $fgthost = preg_split("/:/", PSI_SSH_HOSTNAME, -1, PREG_SPLIT_NO_EMPTY); + define('PSI_EMU_HOSTNAME', trim($fgthost[0])); + if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) { + define('PSI_EMU_PORT', trim($fgthost[1])); + } else { + define('PSI_EMU_PORT', 22); + } + define('PSI_EMU_USER', PSI_SSH_USER); + define('PSI_EMU_PASSWORD', PSI_SSH_PASSWORD); + if (defined('PSI_SSH_ADD_PATHS')) { + define('PSI_EMU_ADD_PATHS', PSI_SSH_ADD_PATHS); + } + if (defined('PSI_SSH_ADD_OPTIONS')) { + define('PSI_EMU_ADD_OPTIONS', PSI_SSH_ADD_OPTIONS); + } + } elseif (defined('PSI_WMI_HOSTNAME')) { + define('PSI_EMU_HOSTNAME', PSI_WMI_HOSTNAME); + if (defined('PSI_WMI_USER') && defined('PSI_WMI_PASSWORD')) { + define('PSI_EMU_USER', PSI_WMI_USER); + define('PSI_EMU_PASSWORD', PSI_WMI_PASSWORD); + } else { + define('PSI_EMU_USER', null); + define('PSI_EMU_PASSWORD', null); + } + } + } + + // Create the XML + $this->_xml = new XML(false, $this->_pluginName); } } @@ -146,8 +225,8 @@ class WebpageXML extends Output implements PSI_Interface_Output */ public function run() { - header("Cache-Control: no-cache, must-revalidate\n"); - header("Content-Type: text/xml\n\n"); + header('Cache-Control: no-cache, must-revalidate'); + header('Content-Type: text/xml'); $xml = $this->_xml->getXml(); echo $xml->asXML(); } @@ -164,24 +243,52 @@ class WebpageXML extends Output implements PSI_Interface_Output return $xml->asXML(); } + /** + * get json string + * + * @return string + */ + public function getJsonString() + { + if (defined('PSI_JSON_ISSUE') && (PSI_JSON_ISSUE)) { + return json_encode(simplexml_load_string(str_replace(">", ">\n", $this->getXMLString()))); // solving json_encode issue + } else { + return json_encode(simplexml_load_string($this->getXMLString())); + } + } + + /** + * get array + * + * @return array + */ + public function getArray() + { + return json_decode($this->getJsonString()); + } + /** * set parameters for the XML generation process * - * @param boolean $completeXML switch for complete xml with all plugins - * @param string $plugin name of the plugin + * @param string $plugin name of the plugin, block or 'complete' for all plugins * * @return void */ - public function __construct($completeXML, $plugin = null) + public function __construct($plugin = "") { parent::__construct(); - if ($completeXML) { - $this->_completeXML = true; - } - if ($plugin) { - if (in_array(strtolower($plugin), CommonFunctions::getPlugins())) { + + if (is_string($plugin) && ($plugin !== "")) { + if (preg_match('/[^A-Za-z]/', $plugin)) { + $this->_blockName = ' '; // mask wrong plugin name + } elseif (($plugin = strtolower($plugin)) === "complete") { + $this->_completeXML = true; + } elseif (in_array($plugin, array('vitals','hardware','memory','filesystem','network','mbinfo','voltage','current','temperature','fans','power','other','ups'))) { + $this->_blockName = $plugin; + } elseif (in_array($plugin, CommonFunctions::getPlugins())) { $this->_pluginName = $plugin; - $this->_pluginRequest = true; + } else { + $this->_blockName = ' '; // disable all blocks } } $this->_prepare(); diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php index 284498c..9c3597e 100644 --- a/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php +++ b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php @@ -8,7 +8,7 @@ * @package PSI_Web * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.WebpageXSLT.inc.php 569 2012-04-16 06:08:18Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_Web * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,7 +30,7 @@ class WebpageXSLT extends WebpageXML implements PSI_Interface_Output */ public function __construct() { - parent::__construct(false, null); + parent::__construct(); } /** @@ -49,6 +49,7 @@ class WebpageXSLT extends WebpageXML implements PSI_Interface_Output $domxsl->load($xslfile); $xsltproc = new XSLTProcessor; $xsltproc->importStyleSheet($domxsl); + header('Cache-Control: no-cache, must-revalidate'); echo $xsltproc->transformToXML($domxml); } } diff --git a/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php index 583ef8c..fc670fc 100644 --- a/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php +++ b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php @@ -8,7 +8,7 @@ * @package PSI_Plugin * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.PSI_Plugin.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -23,7 +23,7 @@ * @package PSI_Plugin * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -61,17 +61,16 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin * build the global Error object, read the configuration and check if all files are available * for a minimalistic function of the plugin * - * @param String $plugin_name name of the plugin - * @param String $enc target encoding - * + * @param string $plugin_name name of the plugin + * @param string $enc target encoding * @return void */ public function __construct($plugin_name, $enc) { - $this->global_error = Error::Singleton(); + $this->global_error = PSI_Error::Singleton(); if (trim($plugin_name) != "") { $this->_plugin_name = $plugin_name; - $this->_plugin_base = APP_ROOT."/plugins/".strtolower($this->_plugin_name)."/"; + $this->_plugin_base = PSI_APP_ROOT."/plugins/".strtolower($this->_plugin_name)."/"; $this->_checkfiles(); $this->_getconfig(); } else { @@ -87,9 +86,11 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin */ private function _getconfig() { - if ((!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_ACCESS')) && - (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_FILE'))) { - $this->global_error->addError("config.ini", "Config for plugin ".$this->_plugin_name." not exist!"); + if ((strtoupper($this->_plugin_name) !== 'DISKLOAD') && + (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_ACCESS')) && + (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_FILE')) && + (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SHOW_SERIAL'))) { + $this->global_error->addError("phpsysinfo.ini", "Config for plugin ".$this->_plugin_name." not exist!"); } } @@ -120,9 +121,9 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin /** * create the xml template where plugin information are added to * - * @param String $enc target encoding + * @param string $enc target encoding * - * @return Void + * @return void */ private function _createXml($enc) { @@ -130,5 +131,13 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin $root = $dom->createElement("Plugin_".$this->_plugin_name); $dom->appendChild($root); $this->xml = new SimpleXMLExtended(simplexml_import_dom($dom), $enc); + $plugname = strtoupper($this->_plugin_name); + if ((PSI_OS == 'Linux') && defined('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME') && + (!defined('PSI_SSH_HOSTNAME') || (PSI_SSH_HOSTNAME != constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SSH_HOSTNAME')))) { + $this->xml->addAttribute('Hostname', constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SSH_HOSTNAME')); + } elseif (((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) && defined('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME') && + (!defined('PSI_WMI_HOSTNAME') || (PSI_WMI_HOSTNAME != constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_WMI_HOSTNAME')))) { + $this->xml->addAttribute('Hostname', constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_WMI_HOSTNAME')); + } } } diff --git a/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php index 07c254c..aa07cab 100644 --- a/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php +++ b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.MBInfo.inc.php 253 2009-06-17 13:07:50Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,7 +30,7 @@ class MBInfo * * @see SensorDevice * - * @var Array + * @var array */ private $_mbTemp = array(); @@ -39,7 +39,7 @@ class MBInfo * * @see SensorDevice * - * @var Array + * @var array */ private $_mbFan = array(); @@ -48,7 +48,7 @@ class MBInfo * * @see SensorDevice * - * @var Array + * @var array */ private $_mbVolt = array(); @@ -57,7 +57,7 @@ class MBInfo * * @see SensorDevice * - * @var Array + * @var array */ private $_mbPower = array(); @@ -66,19 +66,32 @@ class MBInfo * * @see SensorDevice * - * @var Array + * @var array */ private $_mbCurrent = array(); + /** + * array with SensorDevices for other + * + * @see SensorDevice + * + * @var array + */ + private $_mbOther = array(); + /** * Returns $_mbFan. * * @see System::$_mbFan * - * @return Array + * @return array */ public function getMbFan() { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbFan, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_mbFan; } @@ -89,7 +102,7 @@ class MBInfo * * @see System::$_mbFan * - * @return Void + * @return void */ public function setMbFan($mbFan) { @@ -101,21 +114,25 @@ class MBInfo * * @see System::$_mbTemp * - * @return Array + * @return array */ public function getMbTemp() { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbTemp, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_mbTemp; } /** * Sets $_mbTemp. * - * @param Sensor $mbTemp temp device + * @param SensorDevice $mbTemp temp device * * @see System::$_mbTemp * - * @return Void + * @return void */ public function setMbTemp($mbTemp) { @@ -127,21 +144,25 @@ class MBInfo * * @see System::$_mbVolt * - * @return Array + * @return array */ public function getMbVolt() { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbVolt, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_mbVolt; } /** * Sets $_mbVolt. * - * @param Sensor $mbVolt voltage device + * @param SensorDevice $mbVolt voltage device * * @see System::$_mbVolt * - * @return Void + * @return void */ public function setMbVolt($mbVolt) { @@ -153,49 +174,88 @@ class MBInfo * * @see System::$_mbPower * - * @return Array + * @return array */ public function getMbPower() { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbPower, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_mbPower; } /** * Sets $_mbPower. * - * @param Sensor $mbPower power device + * @param SensorDevice $mbPower power device * * @see System::$_mbPower * - * @return Void + * @return void */ public function setMbPower($mbPower) { array_push($this->_mbPower, $mbPower); } + /** * Returns $_mbCurrent. * * @see System::$_mbCurrent * - * @return Array + * @return array */ public function getMbCurrent() { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbCurrent, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_mbCurrent; } /** * Sets $_mbCurrent. * - * @param Sensor $mbCurrent current device + * @param SensorDevice $mbCurrent current device * * @see System::$_mbCurrent * - * @return Void + * @return void */ public function setMbCurrent($mbCurrent) { array_push($this->_mbCurrent, $mbCurrent); } + + /** + * Returns $_mbOther. + * + * @see System::$_mbOther + * + * @return array + */ + public function getMbOther() + { + if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) { + usort($this->_mbOther, array('CommonFunctions', 'name_natural_compare')); + } + + return $this->_mbOther; + } + + /** + * Sets $_mbOther. + * + * @param SensorDevice $mbOther other device + * + * @see System::$_mbOther + * + * @return void + */ + public function setMbOther($mbOther) + { + array_push($this->_mbOther, $mbOther); + } } diff --git a/root/opt/phpsysinfo/includes/to/class.System.inc.php b/root/opt/phpsysinfo/includes/to/class.System.inc.php index 938139e..8ace1dd 100644 --- a/root/opt/phpsysinfo/includes/to/class.System.inc.php +++ b/root/opt/phpsysinfo/includes/to/class.System.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.System.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,70 +28,70 @@ class System /** * name of the host where phpSysInfo runs * - * @var String + * @var string */ private $_hostname = "localhost"; /** * ip of the host where phpSysInfo runs * - * @var String + * @var string */ private $_ip = "127.0.0.1"; /** - * detailed Information about the kernel + * detailed information about the kernel * - * @var String + * @var string */ private $_kernel = "Unknown"; /** * name of the distribution * - * @var String + * @var string */ private $_distribution = "Unknown"; /** * icon of the distribution (must be available in phpSysInfo) * - * @var String + * @var string */ private $_distributionIcon = "unknown.png"; /** * detailed Information about the machine name * - * @var String + * @var string */ private $_machine = ""; /** * time in sec how long the system is running * - * @var Integer + * @var int */ private $_uptime = 0; /** * count of users that are currently logged in * - * @var Integer + * @var int */ private $_users = 0; /** * load of the system * - * @var String + * @var string */ private $_load = ""; /** * load of the system in percent (all cpus, if more than one) * - * @var Integer + * @var int */ private $_loadPercent = null; @@ -100,7 +100,7 @@ class System * * @see CpuDevice * - * @var Array + * @var array */ private $_cpus = array(); @@ -109,7 +109,7 @@ class System * * @see NetDevice * - * @var Array + * @var array */ private $_netDevices = array(); @@ -118,7 +118,7 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_pciDevices = array(); @@ -127,7 +127,7 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_ideDevices = array(); @@ -136,7 +136,7 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_scsiDevices = array(); @@ -145,7 +145,7 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_usbDevices = array(); @@ -154,7 +154,7 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_tbDevices = array(); @@ -163,58 +163,76 @@ class System * * @see HWDevice * - * @var Array + * @var array */ private $_i2cDevices = array(); + /** + * array with NVMe devices + * + * @see HWDevice + * + * @var array + */ + private $_nvmeDevices = array(); + + /** + * array with Mem devices + * + * @see HWDevice + * + * @var array + */ + private $_memDevices = array(); + /** * array with disk devices * * @see DiskDevice * - * @var Array + * @var array */ private $_diskDevices = array(); /** * free memory in bytes * - * @var Integer + * @var int */ private $_memFree = 0; /** * total memory in bytes * - * @var Integer + * @var int */ private $_memTotal = 0; /** * used memory in bytes * - * @var Integer + * @var int */ private $_memUsed = 0; /** * used memory by applications in bytes * - * @var Integer + * @var int */ private $_memApplication = null; /** * used memory for buffers in bytes * - * @var Integer + * @var int */ private $_memBuffer = null; /** * used memory for cache in bytes * - * @var Integer + * @var int */ private $_memCache = null; @@ -223,25 +241,39 @@ class System * * @see DiskDevice * - * @var Array + * @var array */ private $_swapDevices = array(); /** * array of types of processes * - * @var Array + * @var array */ private $_processes = array(); + /** + * array with Virtualizer information + * + * @var array + */ + private $_virtualizer = array(); + + /** + * operating system type + * + * @var string + */ + private $_OS = ""; + /** * remove duplicate Entries and Count * - * @param Array $arrDev list of HWDevices + * @param array $arrDev list of HWDevices * * @see HWDevice * - * @return Array + * @return array */ public static function removeDupsAndCount($arrDev) { @@ -273,7 +305,7 @@ class System * @see System::_memUsed * @see System::_memTotal * - * @return Integer + * @return int */ public function getMemPercentUsed() { @@ -290,7 +322,7 @@ class System * @see System::_memApplication * @see System::_memTotal * - * @return Integer + * @return int */ public function getMemPercentApplication() { @@ -311,7 +343,7 @@ class System * @see System::_memCache * @see System::_memTotal * - * @return Integer + * @return int */ public function getMemPercentCache() { @@ -336,7 +368,7 @@ class System * @see System::_memBuffer * @see System::_memTotal * - * @return Integer + * @return int */ public function getMemPercentBuffer() { @@ -367,7 +399,7 @@ class System * @see System::_swapDevices * @see DiskDevice::getFree() * - * @return Integer + * @return int */ public function getSwapFree() { @@ -389,7 +421,7 @@ class System * @see System::_swapDevices * @see DiskDevice::getTotal() * - * @return Integer + * @return int */ public function getSwapTotal() { @@ -411,7 +443,7 @@ class System * @see System::_swapDevices * @see DiskDevice::getUsed() * - * @return Integer + * @return int */ public function getSwapUsed() { @@ -433,7 +465,7 @@ class System * @see System::getSwapUsed() * @see System::getSwapTotal() * - * @return Integer + * @return int */ public function getSwapPercentUsed() { @@ -467,7 +499,7 @@ class System * * @see System::$_distribution * - * @return Void + * @return void */ public function setDistribution($distribution) { @@ -493,7 +525,7 @@ class System * * @see System::$_distributionIcon * - * @return Void + * @return void */ public function setDistributionIcon($distributionIcon) { @@ -519,7 +551,7 @@ class System * * @see System::$_hostname * - * @return Void + * @return void */ public function setHostname($hostname) { @@ -545,7 +577,7 @@ class System * * @see System::$_ip * - * @return Void + * @return void */ public function setIp($ip) { @@ -571,7 +603,7 @@ class System * * @see System::$_kernel * - * @return Void + * @return void */ public function setKernel($kernel) { @@ -597,7 +629,7 @@ class System * * @see System::$_load * - * @return Void + * @return void */ public function setLoad($load) { @@ -609,7 +641,7 @@ class System * * @see System::$_loadPercent * - * @return Integer + * @return int */ public function getLoadPercent() { @@ -619,11 +651,11 @@ class System /** * Sets $_loadPercent. * - * @param Integer $loadPercent load percent + * @param int $loadPercent load percent * * @see System::$_loadPercent * - * @return Void + * @return void */ public function setLoadPercent($loadPercent) { @@ -645,11 +677,11 @@ class System /** * Sets $_machine. * - * @param Interger $machine machine + * @param string $machine machine * * @see System::$_machine * - * @return Void + * @return void */ public function setMachine($machine) { @@ -661,7 +693,7 @@ class System * * @see System::$_uptime * - * @return Integer + * @return int */ public function getUptime() { @@ -671,11 +703,11 @@ class System /** * Sets $_uptime. * - * @param Interger $uptime uptime + * @param integer $uptime uptime * * @see System::$_uptime * - * @return Void + * @return void */ public function setUptime($uptime) { @@ -687,7 +719,7 @@ class System * * @see System::$_users * - * @return Integer + * @return int */ public function getUsers() { @@ -697,11 +729,11 @@ class System /** * Sets $_users. * - * @param Integer $users user count + * @param int $users user count * * @see System::$_users * - * @return Void + * @return void */ public function setUsers($users) { @@ -713,7 +745,7 @@ class System * * @see System::$_cpus * - * @return Array + * @return array */ public function getCpus() { @@ -723,12 +755,12 @@ class System /** * Sets $_cpus. * - * @param Cpu $cpus cpu device + * @param CpuDevice $cpus cpu device * * @see System::$_cpus * @see CpuDevice * - * @return Void + * @return void */ public function setCpus($cpus) { @@ -740,10 +772,14 @@ class System * * @see System::$_netDevices * - * @return Array + * @return array */ public function getNetDevices() { + if (defined('PSI_SORT_NETWORK_INTERFACES_LIST') && PSI_SORT_NETWORK_INTERFACES_LIST) { + usort($this->_netDevices, array('CommonFunctions', 'name_natural_compare')); + } + return $this->_netDevices; } @@ -755,7 +791,7 @@ class System * @see System::$_netDevices * @see NetDevice * - * @return Void + * @return void */ public function setNetDevices($netDevices) { @@ -767,7 +803,7 @@ class System * * @see System::$_pciDevices * - * @return Array + * @return array */ public function getPciDevices() { @@ -782,7 +818,7 @@ class System * @see System::$_pciDevices * @see HWDevice * - * @return Void + * @return void */ public function setPciDevices($pciDevices) { @@ -794,7 +830,7 @@ class System * * @see System::$_ideDevices * - * @return Array + * @return array */ public function getIdeDevices() { @@ -809,7 +845,7 @@ class System * @see System::$_ideDevices * @see HWDevice * - * @return Void + * @return void */ public function setIdeDevices($ideDevices) { @@ -821,7 +857,7 @@ class System * * @see System::$_scsiDevices * - * @return Array + * @return array */ public function getScsiDevices() { @@ -836,7 +872,7 @@ class System * @see System::$_scsiDevices * @see HWDevice * - * @return Void + * @return void */ public function setScsiDevices($scsiDevices) { @@ -848,7 +884,7 @@ class System * * @see System::$_usbDevices * - * @return Array + * @return array */ public function getUsbDevices() { @@ -863,7 +899,7 @@ class System * @see System::$_usbDevices * @see HWDevice * - * @return Void + * @return void */ public function setUsbDevices($usbDevices) { @@ -875,7 +911,7 @@ class System * * @see System::$_tbDevices * - * @return Array + * @return array */ public function getTbDevices() { @@ -890,7 +926,7 @@ class System * @see System::$_tbDevices * @see HWDevice * - * @return Void + * @return void */ public function setTbDevices($tbDevices) { @@ -902,7 +938,7 @@ class System * * @see System::$_i2cDevices * - * @return Array + * @return array */ public function getI2cDevices() { @@ -917,19 +953,73 @@ class System * @see System::$_i2cDevices * @see HWDevice * - * @return Void + * @return void */ public function setI2cDevices($i2cDevices) { array_push($this->_i2cDevices, $i2cDevices); } + /** + * Returns $_nvmeDevices. + * + * @see System::$_nvmeDevices + * + * @return array + */ + public function getNvmeDevices() + { + return $this->_nvmeDevices; + } + + /** + * Sets $_nvmeDevices. + * + * @param HWDevice $nvmeDevices NVMe device + * + * @see System::$_nvmeDevices + * @see HWDevice + * + * @return void + */ + public function setNvmeDevices($nvmeDevices) + { + array_push($this->_nvmeDevices, $nvmeDevices); + } + + /** + * Returns $_memDevices. + * + * @see System::$_memDevices + * + * @return array + */ + public function getMemDevices() + { + return $this->_memDevices; + } + + /** + * Sets $_memDevices. + * + * @param HWDevice $memDevices mem device + * + * @see System::$_memDevices + * @see HWDevice + * + * @return void + */ + public function setMemDevices($memDevices) + { + array_push($this->_memDevices, $memDevices); + } + /** * Returns $_diskDevices. * * @see System::$_diskDevices * - * @return Array + * @return array */ public function getDiskDevices() { @@ -956,7 +1046,7 @@ class System * * @see System::$_memApplication * - * @return Integer + * @return int */ public function getMemApplication() { @@ -966,11 +1056,11 @@ class System /** * Sets $_memApplication. * - * @param Integer $memApplication application memory + * @param int $memApplication application memory * * @see System::$_memApplication * - * @return Void + * @return void */ public function setMemApplication($memApplication) { @@ -982,7 +1072,7 @@ class System * * @see System::$_memBuffer * - * @return Integer + * @return int */ public function getMemBuffer() { @@ -992,11 +1082,11 @@ class System /** * Sets $_memBuffer. * - * @param Integer $memBuffer buffer memory + * @param int $memBuffer buffer memory * * @see System::$_memBuffer * - * @return Void + * @return void */ public function setMemBuffer($memBuffer) { @@ -1008,7 +1098,7 @@ class System * * @see System::$_memCache * - * @return Integer + * @return int */ public function getMemCache() { @@ -1018,11 +1108,11 @@ class System /** * Sets $_memCache. * - * @param Integer $memCache cache memory + * @param int $memCache cache memory * * @see System::$_memCache * - * @return Void + * @return void */ public function setMemCache($memCache) { @@ -1034,7 +1124,7 @@ class System * * @see System::$_memFree * - * @return Integer + * @return int */ public function getMemFree() { @@ -1044,11 +1134,11 @@ class System /** * Sets $_memFree. * - * @param Integer $memFree free memory + * @param int $memFree free memory * * @see System::$_memFree * - * @return Void + * @return void */ public function setMemFree($memFree) { @@ -1060,7 +1150,7 @@ class System * * @see System::$_memTotal * - * @return Integer + * @return int */ public function getMemTotal() { @@ -1070,11 +1160,11 @@ class System /** * Sets $_memTotal. * - * @param Integer $memTotal total memory + * @param int $memTotal total memory * * @see System::$_memTotal * - * @return Void + * @return void */ public function setMemTotal($memTotal) { @@ -1086,7 +1176,7 @@ class System * * @see System::$_memUsed * - * @return Integer + * @return int */ public function getMemUsed() { @@ -1096,11 +1186,11 @@ class System /** * Sets $_memUsed. * - * @param Integer $memUsed used memory + * @param int $memUsed used memory * * @see System::$_memUsed * - * @return Void + * @return void */ public function setMemUsed($memUsed) { @@ -1112,7 +1202,7 @@ class System * * @see System::$_swapDevices * - * @return Array + * @return array */ public function getSwapDevices() { @@ -1127,7 +1217,7 @@ class System * @see System::$_swapDevices * @see DiskDevice * - * @return Void + * @return void */ public function setSwapDevices($swapDevices) { @@ -1139,7 +1229,7 @@ class System * * @see System::$_processes * - * @return Array + * @return array */ public function getProcesses() { @@ -1153,7 +1243,7 @@ class System * * @see System::$_processes * - * @return Void + * @return void */ public function setProcesses($processes) { @@ -1164,4 +1254,64 @@ class System } */ } + + /** + * Returns $_virtualizer. + * + * @see System::$_virtualizer + * + * @return array + */ + public function getVirtualizer() + { + return $this->_virtualizer; + } + + /** + * Sets $_virtualizer. + * + * @param String $virtualizer virtualizername + * @param Bool|String $value true, false or virtualizername to replace + * + * @see System::$_virtualizer + * + * @return void + */ + public function setVirtualizer($virtualizer, $value = true) + { + if (!isset($this->_virtualizer[$virtualizer])) { + if (is_bool($value)) { + $this->_virtualizer[$virtualizer] = $value; + } else { // replace the virtualizer with another + $this->_virtualizer[$virtualizer] = true; + $this->_virtualizer[$value] = false; + } + } + } + + /** + * Returns $_OS. + * + * @see System::$_OS + * + * @return string + */ + public function getOS() + { + return $this->_OS; + } + + /** + * Sets $_OS. + * + * @param $os operating system type + * + * @see System::$_OS + * + * @return void + */ + public function setOS($OS) + { + $this->_OS = $OS; + } } diff --git a/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php index 26b81cf..3b120f4 100644 --- a/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php +++ b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.UPSInfo.inc.php 329 2009-09-07 11:21:44Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -30,7 +30,7 @@ class UPSInfo * * @see UPSDevice * - * @var Array + * @var array */ private $_upsDevices = array(); @@ -39,7 +39,7 @@ class UPSInfo * * @see UPSInfo::$_upsDevices * - * @return Array + * @return array */ public function getUpsDevices() { @@ -53,7 +53,7 @@ class UPSInfo * * @see UPSInfo::$_upsDevices * - * @return Void + * @return void */ public function setUpsDevices($upsDevices) { diff --git a/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php index e690ef2..a229801 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.CpuDevice.inc.php 411 2010-12-28 22:32:52Z Jacky672 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,123 +28,215 @@ class CpuDevice /** * model of the cpu * - * @var String + * @var string */ private $_model = ""; + /** + * cpu voltage + * + * @var Float + */ + private $_voltage = 0; + /** * speed of the cpu in hertz * - * @var Integer + * @var int */ private $_cpuSpeed = 0; /** * max speed of the cpu in hertz * - * @var Integer + * @var int */ private $_cpuSpeedMax = 0; /** * min speed of the cpu in hertz * - * @var Integer + * @var int */ private $_cpuSpeedMin = 0; /** * cache size in bytes, if available * - * @var Integer + * @var int */ private $_cache = null; /** * virtualization, if available * - * @var String + * @var string */ private $_virt = null; /** * busspeed in hertz, if available * - * @var Integer + * @var int */ private $_busSpeed = null; - /** - * temperature of the cpu, if available - * - * @var Integer - */ - private $_temp = null; - /** * bogomips of the cpu, if available * - * @var Integer + * @var int */ private $_bogomips = null; + /** + * temperature of the cpu, if available + * + * @var int + */ + private $_temp = null; + + /** + * vendorid, if available + * + * @var string + */ + private $_vendorid = null; + /** * current load in percent of the cpu, if available * - * @var Integer + * @var int */ private $_load = null; /** - * Returns $_bogomips. + * Returns $_model. * - * @see Cpu::$_bogomips + * @see Cpu::$_model * - * @return Integer + * @return String */ - public function getBogomips() + public function getModel() { - return $this->_bogomips; + return $this->_model; } /** - * Sets $_bogomips. + * Sets $_model. * - * @param Integer $bogomips bogompis + * @param String $model cpumodel * - * @see Cpu::$_bogomips + * @see Cpu::$_model * - * @return Void + * @return void */ - public function setBogomips($bogomips) + public function setModel($model) { - $this->_bogomips = $bogomips; + $this->_model = $model; } /** - * Returns $_busSpeed. + * Returns $_voltage. * - * @see Cpu::$_busSpeed + * @see Cpu::$_voltage * - * @return Integer + * @return Float */ - public function getBusSpeed() + public function getVoltage() { - return $this->_busSpeed; + return $this->_voltage; } /** - * Sets $_busSpeed. + * Sets $_voltage. * - * @param Integer $busSpeed busspeed + * @param int $voltage voltage * - * @see Cpu::$_busSpeed + * @see Cpu::$_voltage * - * @return Void + * @return void */ - public function setBusSpeed($busSpeed) + public function setVoltage($voltage) { - $this->_busSpeed = $busSpeed; + $this->_voltage = $voltage; + } + + /** + * Returns $_cpuSpeed. + * + * @see Cpu::$_cpuSpeed + * + * @return int + */ + public function getCpuSpeed() + { + return $this->_cpuSpeed; + } + + /** + * Sets $_cpuSpeed. + * + * @param int $cpuSpeed cpuspeed + * + * @see Cpu::$_cpuSpeed + * + * @return void + */ + public function setCpuSpeed($cpuSpeed) + { + $this->_cpuSpeed = $cpuSpeed; + } + + /** + * Returns $_cpuSpeedMax. + * + * @see Cpu::$_cpuSpeedMAx + * + * @return int + */ + public function getCpuSpeedMax() + { + return $this->_cpuSpeedMax; + } + + /** + * Sets $_cpuSpeedMax. + * + * @param int $cpuSpeedMax cpuspeedmax + * + * @see Cpu::$_cpuSpeedMax + * + * @return void + */ + public function setCpuSpeedMax($cpuSpeedMax) + { + $this->_cpuSpeedMax = $cpuSpeedMax; + } + + /** + * Returns $_cpuSpeedMin. + * + * @see Cpu::$_cpuSpeedMin + * + * @return int + */ + public function getCpuSpeedMin() + { + return $this->_cpuSpeedMin; + } + + /** + * Sets $_cpuSpeedMin. + * + * @param int $cpuSpeedMin cpuspeedmin + * + * @see Cpu::$_cpuSpeedMin + * + * @return void + */ + public function setCpuSpeedMin($cpuSpeedMin) + { + $this->_cpuSpeedMin = $cpuSpeedMin; } /** @@ -152,7 +244,7 @@ class CpuDevice * * @see Cpu::$_cache * - * @return Integer + * @return int */ public function getCache() { @@ -162,11 +254,11 @@ class CpuDevice /** * Sets $_cache. * - * @param Integer $cache cache size + * @param int $cache cache size * * @see Cpu::$_cache * - * @return Void + * @return void */ public function setCache($cache) { @@ -188,11 +280,11 @@ class CpuDevice /** * Sets $_virt. * - * @param String $_virt + * @param string $virt * * @see Cpu::$_virt * - * @return Void + * @return void */ public function setVirt($virt) { @@ -200,107 +292,55 @@ class CpuDevice } /** - * Returns $_cpuSpeed. + * Returns $_busSpeed. * - * @see Cpu::$_cpuSpeed + * @see Cpu::$_busSpeed * - * @return Integer + * @return int */ - public function getCpuSpeed() + public function getBusSpeed() { - return $this->_cpuSpeed; + return $this->_busSpeed; } /** - * Returns $_cpuSpeedMax. + * Sets $_busSpeed. * - * @see Cpu::$_cpuSpeedMAx + * @param int $busSpeed busspeed * - * @return Integer + * @see Cpu::$_busSpeed + * + * @return void */ - public function getCpuSpeedMax() + public function setBusSpeed($busSpeed) { - return $this->_cpuSpeedMax; + $this->_busSpeed = $busSpeed; } /** - * Returns $_cpuSpeedMin. + * Returns $_bogomips. * - * @see Cpu::$_cpuSpeedMin + * @see Cpu::$_bogomips * - * @return Integer + * @return int */ - public function getCpuSpeedMin() + public function getBogomips() { - return $this->_cpuSpeedMin; + return $this->_bogomips; } /** - * Sets $_cpuSpeed. + * Sets $_bogomips. * - * @param Integer $cpuSpeed cpuspeed + * @param int $bogomips bogompis * - * @see Cpu::$_cpuSpeed + * @see Cpu::$_bogomips * - * @return Void + * @return void */ - public function setCpuSpeed($cpuSpeed) + public function setBogomips($bogomips) { - $this->_cpuSpeed = $cpuSpeed; - } - - /** - * Sets $_cpuSpeedMax. - * - * @param Integer $cpuSpeedMax cpuspeedmax - * - * @see Cpu::$_cpuSpeedMax - * - * @return Void - */ - public function setCpuSpeedMax($cpuSpeedMax) - { - $this->_cpuSpeedMax = $cpuSpeedMax; - } - - /** - * Sets $_cpuSpeedMin. - * - * @param Integer $cpuSpeedMin cpuspeedmin - * - * @see Cpu::$_cpuSpeedMin - * - * @return Void - */ - public function setCpuSpeedMin($cpuSpeedMin) - { - $this->_cpuSpeedMin = $cpuSpeedMin; - } - - /** - * Returns $_model. - * - * @see Cpu::$_model - * - * @return String - */ - public function getModel() - { - return $this->_model; - } - - /** - * Sets $_model. - * - * @param String $model cpumodel - * - * @see Cpu::$_model - * - * @return Void - */ - public function setModel($model) - { - $this->_model = $model; + $this->_bogomips = $bogomips; } /** @@ -308,33 +348,63 @@ class CpuDevice * * @see Cpu::$_temp * - * @return Integer + * @return int */ +/* public function getTemp() { return $this->_temp; } +*/ /** * Sets $_temp. * - * @param Integer $temp temperature + * @param int $temp temperature * * @see Cpu::$_temp * - * @return Void + * @return void */ +/* public function setTemp($temp) { $this->_temp = $temp; } +*/ + + /** + * Returns $_vendorid. + * + * @see Cpu::$_vendorid + * + * @return String + */ + public function getVendorId() + { + return $this->_vendorid; + } + + /** + * Sets $_vendorid. + * + * @param string $vendorid + * + * @see Cpu::$_vendorid + * + * @return void + */ + public function setVendorId($vendorid) + { + $this->_vendorid = trim(preg_replace('/[\s!]/', '', $vendorid)); + } /** * Returns $_load. * * @see CpuDevice::$_load * - * @return Integer + * @return int */ public function getLoad() { @@ -344,11 +414,11 @@ class CpuDevice /** * Sets $_load. * - * @param Integer $load load percent + * @param int $load load percent * * @see CpuDevice::$_load * - * @return Void + * @return void */ public function setLoad($load) { diff --git a/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php index 32e5b73..aa7a9c5 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.DiskDevice.inc.php 252 2009-06-17 13:06:44Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,71 +28,78 @@ class DiskDevice /** * name of the disk device * - * @var String + * @var string */ private $_name = ""; /** * type of the filesystem on the disk device * - * @var String + * @var string */ private $_fsType = ""; /** * diskspace that is free in bytes * - * @var Integer + * @var int */ private $_free = 0; /** * diskspace that is used in bytes * - * @var Integer + * @var int */ private $_used = 0; /** * total diskspace * - * @var Integer + * @var int */ private $_total = 0; /** * mount point of the disk device if available * - * @var String + * @var string */ private $_mountPoint = null; /** * additional options of the device, like mount options * - * @var String + * @var string */ private $_options = null; /** * inodes usage in percent if available * - * @var + * @var int */ private $_percentInodesUsed = null; + /** + * ignore mode + * + * @var int + */ + private $_ignore = 0; + /** * Returns PercentUsed calculated when function is called from internal values * * @see DiskDevice::$_total * @see DiskDevice::$_used * - * @return Integer + * @return int */ public function getPercentUsed() { if ($this->_total > 0) { - return round($this->_used / $this->_total * 100); + return 100 - min(floor($this->_free / $this->_total * 100), 100); } else { return 0; } @@ -103,7 +110,7 @@ class DiskDevice * * @see DiskDevice::$_PercentInodesUsed * - * @return Integer + * @return int */ public function getPercentInodesUsed() { @@ -113,11 +120,11 @@ class DiskDevice /** * Sets $_PercentInodesUsed. * - * @param Integer $percentInodesUsed inodes percent + * @param int $percentInodesUsed inodes percent * * @see DiskDevice::$_PercentInodesUsed * - * @return Void + * @return void */ public function setPercentInodesUsed($percentInodesUsed) { @@ -129,7 +136,7 @@ class DiskDevice * * @see DiskDevice::$_free * - * @return Integer + * @return int */ public function getFree() { @@ -139,11 +146,11 @@ class DiskDevice /** * Sets $_free. * - * @param Integer $free free bytes + * @param int $free free bytes * * @see DiskDevice::$_free * - * @return Void + * @return void */ public function setFree($free) { @@ -155,7 +162,7 @@ class DiskDevice * * @see DiskDevice::$_fsType * - * @return String + * @return string */ public function getFsType() { @@ -169,7 +176,7 @@ class DiskDevice * * @see DiskDevice::$_fsType * - * @return Void + * @return void */ public function setFsType($fsType) { @@ -181,7 +188,7 @@ class DiskDevice * * @see DiskDevice::$_mountPoint * - * @return String + * @return string */ public function getMountPoint() { @@ -191,11 +198,11 @@ class DiskDevice /** * Sets $_mountPoint. * - * @param String $mountPoint mountpoint + * @param string $mountPoint mountpoint * * @see DiskDevice::$_mountPoint * - * @return Void + * @return void */ public function setMountPoint($mountPoint) { @@ -207,7 +214,7 @@ class DiskDevice * * @see DiskDevice::$_name * - * @return String + * @return string */ public function getName() { @@ -217,11 +224,11 @@ class DiskDevice /** * Sets $_name. * - * @param String $name device name + * @param string $name device name * * @see DiskDevice::$_name * - * @return Void + * @return void */ public function setName($name) { @@ -233,7 +240,7 @@ class DiskDevice * * @see DiskDevice::$_options * - * @return String + * @return string */ public function getOptions() { @@ -243,11 +250,11 @@ class DiskDevice /** * Sets $_options. * - * @param String $options additional options + * @param string $options additional options * * @see DiskDevice::$_options * - * @return Void + * @return void */ public function setOptions($options) { @@ -259,7 +266,7 @@ class DiskDevice * * @see DiskDevice::$_total * - * @return Integer + * @return int */ public function getTotal() { @@ -269,11 +276,11 @@ class DiskDevice /** * Sets $_total. * - * @param Integer $total total bytes + * @param int $total total bytes * * @see DiskDevice::$_total * - * @return Void + * @return void */ public function setTotal($total) { @@ -285,7 +292,7 @@ class DiskDevice * * @see DiskDevice::$_used * - * @return Integer + * @return int */ public function getUsed() { @@ -295,14 +302,38 @@ class DiskDevice /** * Sets $_used. * - * @param Integer $used used bytes + * @param int $used used bytes * * @see DiskDevice::$_used * - * @return Void + * @return void */ public function setUsed($used) { $this->_used = $used; } + + /** + * Returns $_ignore. + * + * @see DiskDevice::$_ignore + * + * @return int + */ + public function getIgnore() + { + return $this->_ignore; + } + + /** + * Sets $_ignore. + * + * @see DiskDevice::$_ignore + * + * @return void + */ + public function setIgnore($ignore) + { + $this->_ignore = $ignore; + } } diff --git a/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php index 3a2b0f1..c4db009 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.HWDevice.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,21 +28,56 @@ class HWDevice /** * name of the device * - * @var String + * @var string */ private $_name = ""; /** * capacity of the device, if not available it will be null * - * @var Integer + * @var int */ private $_capacity = null; + /** + * manufacturer of the device, if not available it will be null + * + * @var int + */ + private $_manufacturer = null; + + /** + * product of the device, if not available it will be null + * + * @var int + */ + private $_product = null; + + /** + * serial number of the device, if not available it will be null + * + * @var string + */ + private $_serial = null; + + /** + * speed of the device, if not available it will be null + * + * @var Float + */ + private $_speed = null; + + /** + * voltage of the device, if not available it will be null + * + * @var Float + */ + private $_voltage = null; + /** * count of the device * - * @var Integer + * @var int */ private $_count = 1; @@ -55,39 +90,18 @@ class HWDevice */ public function equals(HWDevice $dev) { - if ($dev->getName() === $this->_name && $dev->getCapacity() === $this->_capacity) { + if ($dev->getName() === $this->_name + && $dev->getCapacity() === $this->_capacity + && $dev->getManufacturer() === $this->_manufacturer + && $dev->getProduct() === $this->_product + && $dev->getSerial() === $this->_serial + && $dev->getSpeed() === $this->_speed) { return true; } else { return false; } } - /** - * Returns $_capacity. - * - * @see HWDevice::$_capacity - * - * @return Integer - */ - public function getCapacity() - { - return $this->_capacity; - } - - /** - * Sets $_capacity. - * - * @param Integer $capacity device capacity - * - * @see HWDevice::$_capacity - * - * @return Void - */ - public function setCapacity($capacity) - { - $this->_capacity = $capacity; - } - /** * Returns $_name. * @@ -107,19 +121,175 @@ class HWDevice * * @see HWDevice::$_name * - * @return Void + * @return void */ public function setName($name) { $this->_name = $name; } + /** + * Returns $_manufacturer. + * + * @see HWDevice::$_manufacturer + * + * @return String + */ + public function getManufacturer() + { + return $this->_manufacturer; + } + + /** + * Sets $_manufacturer. + * + * @param String $manufacturer manufacturer name + * + * @see HWDevice::$_manufacturer + * + * @return void + */ + public function setManufacturer($manufacturer) + { + $this->_manufacturer = $manufacturer; + } + + /** + * Returns $_product. + * + * @see HWDevice::$_product + * + * @return String + */ + public function getProduct() + { + return $this->_product; + } + + /** + * Sets $_product. + * + * @param String $product product name + * + * @see HWDevice::$_product + * + * @return void + */ + public function setProduct($product) + { + $this->_product = $product; + } + + /** + * Returns $_serial. + * + * @see HWDevice::$_serial + * + * @return String + */ + public function getSerial() + { + return $this->_serial; + } + + /** + * Sets $_serial. + * + * @param String $serial serial number + * + * @see HWDevice::$_serial + * + * @return void + */ + public function setSerial($serial) + { + $this->_serial = $serial; + } + + /** + * Returns $_speed. + * + * @see HWDevice::$_speed + * + * @return Float + */ + public function getSpeed() + { + return $this->_speed; + } + + /** + * Sets $_speed. + * + * @param Float $speed speed + * + * @see HWDevice::$_speed + * + * @return void + */ + public function setSpeed($speed) + { + $this->_speed = $speed; + } + + /** + * Returns $_voltage. + * + * @see HWDevice::$_voltage + * + * @return Float + */ + public function getVoltage() + { + return $this->_voltage; + } + + /** + * Sets $_voltage. + * + * @param Float $voltage voltage + * + * @see HWDevice::$_voltage + * + * @return void + */ + public function setVoltage($voltage) + { + $this->_voltage = $voltage; + } + + /** + * Returns $_capacity. + * + * @see HWDevice::$_capacity + * + * @return int + */ + public function getCapacity() + { + return $this->_capacity; + } + + /** + * Sets $_capacity. + * + * @param int $capacity device capacity + * + * @see HWDevice::$_capacity + * + * @return void + */ + public function setCapacity($capacity) + { + $this->_capacity = $capacity; + } + /** * Returns $_count. * * @see HWDevice::$_count * - * @return Integer + * @return int */ public function getCount() { @@ -129,11 +299,11 @@ class HWDevice /** * Sets $_count. * - * @param Integer $count device count + * @param int $count device count * * @see HWDevice::$_count * - * @return Void + * @return void */ public function setCount($count) { diff --git a/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php index 6f8d3b9..20e7dc5 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.NetDevice.inc.php 547 2012-03-22 09:44:38Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,51 +28,72 @@ class NetDevice /** * name of the device * - * @var String + * @var string */ private $_name = ""; /** * transmitted bytes * - * @var Integer + * @var int */ private $_txBytes = 0; /** * received bytes * - * @var Integer + * @var int */ private $_rxBytes = 0; /** * counted error packages * - * @var Integer + * @var int */ private $_errors = 0; /** * counted droped packages * - * @var Integer + * @var int */ private $_drops = 0; /** * string with info * - * @var String + * @var string */ private $_info = null; + /** + * string with bridge + * + * @var string + */ + private $_bridge = null; + + /** + * transmitted bytes rate + * + * @var int + */ + private $_txRate = null; + + /** + * received bytes rate + * + * @var int + */ + private $_rxRate = null; + /** * Returns $_drops. * * @see NetDevice::$_drops * - * @return Integer + * @return int */ public function getDrops() { @@ -82,11 +103,11 @@ class NetDevice /** * Sets $_drops. * - * @param Integer $drops dropped packages + * @param int $drops dropped packages * * @see NetDevice::$_drops * - * @return Void + * @return void */ public function setDrops($drops) { @@ -98,7 +119,7 @@ class NetDevice * * @see NetDevice::$_errors * - * @return Integer + * @return int */ public function getErrors() { @@ -108,11 +129,11 @@ class NetDevice /** * Sets $_errors. * - * @param Integer $errors error packages + * @param int $errors error packages * * @see NetDevice::$_errors * - * @return Void + * @return void */ public function setErrors($errors) { @@ -138,7 +159,7 @@ class NetDevice * * @see NetDevice::$_name * - * @return Void + * @return void */ public function setName($name) { @@ -150,7 +171,7 @@ class NetDevice * * @see NetDevice::$_rxBytes * - * @return Integer + * @return int */ public function getRxBytes() { @@ -160,11 +181,11 @@ class NetDevice /** * Sets $_rxBytes. * - * @param Integer $rxBytes received bytes + * @param int $rxBytes received bytes * * @see NetDevice::$_rxBytes * - * @return Void + * @return void */ public function setRxBytes($rxBytes) { @@ -176,7 +197,7 @@ class NetDevice * * @see NetDevice::$_txBytes * - * @return Integer + * @return int */ public function getTxBytes() { @@ -186,11 +207,11 @@ class NetDevice /** * Sets $_txBytes. * - * @param Integer $txBytes transmitted bytes + * @param int $txBytes transmitted bytes * * @see NetDevice::$_txBytes * - * @return Void + * @return void */ public function setTxBytes($txBytes) { @@ -216,10 +237,88 @@ class NetDevice * * @see NetDevice::$_info * - * @return Void + * @return void */ public function setInfo($info) { $this->_info = $info; } + + /** + * Returns $_bridge. + * + * @see NetDevice::$_bridge + * + * @return String + */ + public function getBridge() + { + return $this->_bridge; + } + + /** + * Sets $_bridge. + * + * @param String $bridge bridge string + * + * @see NetDevice::$_bridge + * + * @return void + */ + public function setBridge($bridge) + { + $this->_bridge = $bridge; + } + + /** + * Returns $_rxRate. + * + * @see NetDevice::$_rxRate + * + * @return int + */ + public function getRxRate() + { + return $this->_rxRate; + } + + /** + * Sets $_rxRate. + * + * @param int $rxRate received bytes rate + * + * @see NetDevice::$_rxRate + * + * @return void + */ + public function setRxRate($rxRate) + { + $this->_rxRate = $rxRate; + } + + /** + * Returns $_txRate. + * + * @see NetDevice::$_txRate + * + * @return int + */ + public function getTxRate() + { + return $this->_txRate; + } + + /** + * Sets $_txRate. + * + * @param int $txRate transmitted bytes rate + * + * @see NetDevice::$_txRate + * + * @return void + */ + public function setTxRate($txRate) + { + $this->_txRate = $txRate; + } } diff --git a/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php index 65c2f6c..80ccf37 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.SensorDevice.inc.php 592 2012-07-03 10:55:51Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,44 +28,51 @@ class SensorDevice /** * name of the sensor * - * @var String + * @var string */ private $_name = ""; /** * current value of the sensor * - * @var Integer + * @var int */ private $_value = 0; /** * maximum value of the sensor * - * @var Integer + * @var int */ private $_max = null; /** * minimum value of the sensor * - * @var Integer + * @var int */ private $_min = null; /** * event of the sensor * - * @var String + * @var string */ private $_event = ""; + /** + * unit of values of the sensor + * + * @var string + */ + private $_unit = ""; + /** * Returns $_max. * * @see Sensor::$_max * - * @return Integer + * @return int */ public function getMax() { @@ -75,11 +82,11 @@ class SensorDevice /** * Sets $_max. * - * @param Integer $max maximum value + * @param int $max maximum value * * @see Sensor::$_max * - * @return Void + * @return void */ public function setMax($max) { @@ -91,7 +98,7 @@ class SensorDevice * * @see Sensor::$_min * - * @return Integer + * @return int */ public function getMin() { @@ -101,11 +108,11 @@ class SensorDevice /** * Sets $_min. * - * @param Integer $min minimum value + * @param int $min minimum value * * @see Sensor::$_min * - * @return Void + * @return void */ public function setMin($min) { @@ -131,7 +138,7 @@ class SensorDevice * * @see Sensor::$_name * - * @return Void + * @return void */ public function setName($name) { @@ -143,7 +150,7 @@ class SensorDevice * * @see Sensor::$_value * - * @return Integer + * @return int */ public function getValue() { @@ -153,11 +160,11 @@ class SensorDevice /** * Sets $_value. * - * @param Integer $value current value + * @param int $value current value * * @see Sensor::$_value * - * @return Void + * @return void */ public function setValue($value) { @@ -183,10 +190,36 @@ class SensorDevice * * @see Sensor::$_event * - * @return Void + * @return void */ public function setEvent($event) { $this->_event = $event; } + + /** + * Returns $_unit. + * + * @see Sensor::$_unit + * + * @return String + */ + public function getUnit() + { + return $this->_unit; + } + + /** + * Sets $_unit. + * + * @param String $unit sensor unit + * + * @see Sensor::$_unit + * + * @return void + */ + public function setUnit($unit) + { + $this->_unit = $unit; + } } diff --git a/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php index f72e30a..052785d 100644 --- a/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php +++ b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php @@ -8,7 +8,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.UPSDevice.inc.php 262 2009-06-22 10:48:33Z bigmichi1 $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_TO * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,121 +28,128 @@ class UPSDevice /** * name of the ups * - * @var String + * @var string */ private $_name = ""; /** * model of the ups * - * @var String + * @var string */ private $_model = ""; /** * mode of the ups * - * @var String + * @var string */ private $_mode = ""; /** * last start time * - * @var String + * @var string */ private $_startTime = ""; /** * status of the ups * - * @var String + * @var string */ private $_status = ""; /** * temperature of the ups * - * @var Integer + * @var string */ private $_temperatur = null; /** * outages count * - * @var Integer + * @var int */ private $_outages = null; /** * date of last outtage * - * @var String + * @var string */ private $_lastOutage = null; /** * date of last outage finish * - * @var String + * @var string */ private $_lastOutageFinish = null; /** * line volt * - * @var Integer + * @var float */ private $_lineVoltage = null; /** * line freq * - * @var Integer + * @var int */ private $_lineFrequency = null; /** * current load of the ups in percent * - * @var Integer + * @var float */ private $_load = null; /** * battery installation date * - * @var String + * @var string */ private $_batteryDate = null; /** * current battery volt * - * @var Integer + * @var float */ private $_batteryVoltage = null; /** * current charge in percent of the battery * - * @var Integer + * @var float */ private $_batterCharge = null; /** * time left * - * @var String + * @var string */ private $_timeLeft = null; + /** + * beeper enabled or disabled + * + * @var string + */ + private $_beeperStatus = null; + /** * Returns $_batterCharge. * * @see UPSDevice::$_batterCharge * - * @return integer + * @return float */ public function getBatterCharge() { @@ -152,7 +159,7 @@ class UPSDevice /** * Sets $_batterCharge. * - * @param Integer $batterCharge battery charge + * @param float $batterCharge battery charge * * @see UPSDevice::$_batterCharge * @@ -182,7 +189,7 @@ class UPSDevice * * @see UPSDevice::$_batteryDate * - * @return Void + * @return void */ public function setBatteryDate($batteryDate) { @@ -194,7 +201,7 @@ class UPSDevice * * @see UPSDevice::$_batteryVoltage * - * @return Integer + * @return float */ public function getBatteryVoltage() { @@ -204,11 +211,11 @@ class UPSDevice /** * Sets $_batteryVoltage. * - * @param object $batteryVoltage battery volt + * @param float $batteryVoltage battery volt * * @see UPSDevice::$_batteryVoltage * - * @return Void + * @return void */ public function setBatteryVoltage($batteryVoltage) { @@ -234,7 +241,7 @@ class UPSDevice * * @see UPSDevice::$lastOutage * - * @return Void + * @return void */ public function setLastOutage($lastOutage) { @@ -260,7 +267,7 @@ class UPSDevice * * @see UPSDevice::$_lastOutageFinish * - * @return Void + * @return void */ public function setLastOutageFinish($lastOutageFinish) { @@ -272,7 +279,7 @@ class UPSDevice * * @see UPSDevice::$_lineVoltage * - * @return Integer + * @return float */ public function getLineVoltage() { @@ -282,11 +289,11 @@ class UPSDevice /** * Sets $_lineVoltage. * - * @param Integer $lineVoltage line voltage + * @param float $lineVoltage line voltage * * @see UPSDevice::$_lineVoltage * - * @return Void + * @return void */ public function setLineVoltage($lineVoltage) { @@ -298,7 +305,7 @@ class UPSDevice * * @see UPSDevice::$_lineFrequency * - * @return Integer + * @return int */ public function getLineFrequency() { @@ -308,11 +315,11 @@ class UPSDevice /** * Sets $_lineFrequency. * - * @param Integer $lineFrequency line frequency + * @param int $lineFrequency line frequency * * @see UPSDevice::$_lineFrequency * - * @return Void + * @return void */ public function setLineFrequency($lineFrequency) { @@ -324,7 +331,7 @@ class UPSDevice * * @see UPSDevice::$_load * - * @return Integer + * @return float */ public function getLoad() { @@ -334,11 +341,11 @@ class UPSDevice /** * Sets $_load. * - * @param Integer $load current load + * @param float $load current load * * @see UPSDevice::$_load * - * @return Void + * @return void */ public function setLoad($load) { @@ -364,7 +371,7 @@ class UPSDevice * * @see UPSDevice::$_mode * - * @return Void + * @return void */ public function setMode($mode) { @@ -390,7 +397,7 @@ class UPSDevice * * @see UPSDevice::$_model * - * @return Void + * @return void */ public function setModel($model) { @@ -416,7 +423,7 @@ class UPSDevice * * @see UPSDevice::$_name * - * @return Void + * @return void */ public function setName($name) { @@ -428,7 +435,7 @@ class UPSDevice * * @see UPSDevice::$_outages * - * @return Integer + * @return int */ public function getOutages() { @@ -438,11 +445,11 @@ class UPSDevice /** * Sets $_outages. * - * @param Integer $outages outages count + * @param int $outages outages count * * @see UPSDevice::$_outages * - * @return Void + * @return void */ public function setOutages($outages) { @@ -468,7 +475,7 @@ class UPSDevice * * @see UPSDevice::$_startTime * - * @return Void + * @return void */ public function setStartTime($startTime) { @@ -494,7 +501,7 @@ class UPSDevice * * @see UPSDevice::$_status * - * @return Void + * @return void */ public function setStatus($status) { @@ -506,7 +513,7 @@ class UPSDevice * * @see UPSDevice::$_temperatur * - * @return Integer + * @return string */ public function getTemperatur() { @@ -516,11 +523,11 @@ class UPSDevice /** * Sets $_temperatur. * - * @param Integer $temperatur temperature + * @param string $temperatur temperature * * @see UPSDevice::$_temperatur * - * @return Void + * @return void */ public function setTemperatur($temperatur) { @@ -546,10 +553,36 @@ class UPSDevice * * @see UPSDevice::$_timeLeft * - * @return Void + * @return void */ public function setTimeLeft($timeLeft) { $this->_timeLeft = $timeLeft; } + + /** + * Returns $_beeperStatus. + * + * @see UPSDevice::$_beeperStatus + * + * @return String + */ + public function getBeeperStatus() + { + return $this->_beeperStatus; + } + + /** + * Sets $_beeperStatus. + * + * @param String $beeperStatus beeper status + * + * @see UPSDevice::$_beeperStatus + * + * @return void + */ + public function setBeeperStatus($beeperStatus) + { + $this->_beeperStatus = $beeperStatus; + } } diff --git a/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php index 0a0744a..9152191 100644 --- a/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php +++ b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php @@ -8,7 +8,7 @@ * @package PSI_UPS * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.apcupsd.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -20,7 +20,7 @@ * @author Michael Cramer * @author Artem Volk * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -29,7 +29,7 @@ class Apcupsd extends UPS /** * internal storage for all gathered data * - * @var Array + * @var array */ private $_output = array(); @@ -39,22 +39,53 @@ class Apcupsd extends UPS public function __construct() { parent::__construct(); - if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) { - if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) { - $upses = eval(PSI_UPS_APCUPSD_LIST); + if (!defined('PSI_UPS_APCUPSD_ACCESS')) { + define('PSI_UPS_APCUPSD_ACCESS', false); + } + switch (strtolower(PSI_UPS_APCUPSD_ACCESS)) { + case 'data': + if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) { + $upss = eval(PSI_UPS_APCUPSD_LIST); + } else { + $upss = array(PSI_UPS_APCUPSD_LIST); + } } else { - $upses = array(PSI_UPS_APCUPSD_LIST); + $upss = array('UPS'); } - foreach ($upses as $ups) { - CommonFunctions::executeProgram('apcaccess', 'status '.trim($ups), $temp); + $un = 0; + foreach ($upss as $ups) { + $temp = ""; + CommonFunctions::rftsdata("upsapcupsd{$un}.tmp", $temp); if (! empty($temp)) { $this->_output[] = $temp; } + $un++; } - } else { //use default if address and port not defined - CommonFunctions::executeProgram('apcaccess', 'status', $temp); - if (! empty($temp)) { - $this->_output[] = $temp; + break; + default: + if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) { + $upses = eval(PSI_UPS_APCUPSD_LIST); + } else { + $upses = array(PSI_UPS_APCUPSD_LIST); + } + foreach ($upses as $ups) { + $temp = ""; + CommonFunctions::executeProgram('apcaccess', 'status '.trim($ups), $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } + } else { //use default if address and port not defined + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) { + CommonFunctions::executeProgram('apcaccess', 'status', $temp); + } else { + CommonFunctions::executeProgram('apcaccess', 'status '.PSI_EMU_HOSTNAME, $temp); + } + if (! empty($temp)) { + $this->_output[] = $temp; + } } } } @@ -62,7 +93,7 @@ class Apcupsd extends UPS /** * parse the input and store data in resultset for xml generation * - * @return Void + * @return void */ private function _info() { @@ -75,7 +106,7 @@ class Apcupsd extends UPS $dev->setName(trim($data[1])); } if (preg_match('/^MODEL\s*:\s*(.*)$/m', $ups, $data)) { - $model=trim($data[1]); + $model = trim($data[1]); if (preg_match('/^APCMODEL\s*:\s*(.*)$/m', $ups, $data)) { $dev->setModel($model.' ('.trim($data[1]).')'); } else { @@ -92,7 +123,10 @@ class Apcupsd extends UPS $dev->setStatus(trim($data[1])); } if (preg_match('/^ITEMP\s*:\s*(.*)$/m', $ups, $data)) { - $dev->setTemperatur(trim($data[1])); + $temperatur = trim($data[1]); + if (($temperatur !== "-273.1 C") && ($temperatur !== "-273.1 C Internal")) { + $dev->setTemperatur($temperatur); + } } // Outages if (preg_match('/^NUMXFERS\s*:\s*(.*)$/m', $ups, $data)) { @@ -136,7 +170,7 @@ class Apcupsd extends UPS * * @see PSI_Interface_UPS::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/ups/class.nut.inc.php b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php index b9b86a9..4f4b5b4 100644 --- a/root/opt/phpsysinfo/includes/ups/class.nut.inc.php +++ b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php @@ -9,7 +9,7 @@ * @author Artem Volk * @author Anders Häggström * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -21,7 +21,7 @@ * @author Artem Volk * @author Anders Häggström * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -40,29 +40,62 @@ class Nut extends UPS public function __construct() { parent::__construct(); - if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) { - if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) { - $upses = eval(PSI_UPS_NUT_LIST); + if (!defined('PSI_UPS_NUT_ACCESS')) { + define('PSI_UPS_NUT_ACCESS', false); + } + switch (strtolower(PSI_UPS_NUT_ACCESS)) { + case 'data': + if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) { + $upss = eval(PSI_UPS_NUT_LIST); + } else { + $upss = array(PSI_UPS_NUT_LIST); + } } else { - $upses = array(PSI_UPS_NUT_LIST); + $upss = array('UPS'); } - foreach ($upses as $ups) { - CommonFunctions::executeProgram('upsc', '-l '.trim($ups), $output); - $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); - foreach ($ups_names as $ups_name) { - CommonFunctions::executeProgram('upsc', trim($ups_name).'@'.trim($ups), $temp); - if (! empty($temp)) { - $this->_output[trim($ups_name).'@'.trim($ups)] = $temp; + $un = 0; + foreach ($upss as $ups) { + $temp = ""; + CommonFunctions::rftsdata("upsnut{$un}.tmp", $temp); + if (! empty($temp)) { + $this->_output[$ups] = $temp; + } + $un++; + } + break; + default: + if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) { + $upses = eval(PSI_UPS_NUT_LIST); + } else { + $upses = array(PSI_UPS_NUT_LIST); + } + foreach ($upses as $ups) { + CommonFunctions::executeProgram('upsc', '-l '.trim($ups), $output, PSI_DEBUG); + $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); + foreach ($ups_names as $ups_name) { + $upsname = trim($ups_name).'@'.trim($ups); + $temp = ""; + CommonFunctions::executeProgram('upsc', $upsname, $temp, PSI_DEBUG); + if (! empty($temp)) { + $this->_output[$upsname] = $temp; + } } } - } - } else { //use default if address and port not defined - CommonFunctions::executeProgram('upsc', '-l', $output); - $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); - foreach ($ups_names as $ups_name) { - CommonFunctions::executeProgram('upsc', trim($ups_name), $temp); - if (! empty($temp)) { - $this->_output[trim($ups_name)] = $temp; + } else { //use default if address and port not defined + if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) { + CommonFunctions::executeProgram('upsc', '-l', $output, PSI_DEBUG); + } else { + CommonFunctions::executeProgram('upsc', '-l '.PSI_EMU_HOSTNAME, $output, PSI_DEBUG); + } + $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); + foreach ($ups_names as $ups_name) { + $temp = ""; + CommonFunctions::executeProgram('upsc', trim($ups_name), $temp, PSI_DEBUG); + if (! empty($temp)) { + $this->_output[trim($ups_name)] = $temp; + } } } } @@ -71,16 +104,16 @@ class Nut extends UPS /** * parse the input and store data in resultset for xml generation * - * @return array + * @return void */ private function _info() { if (! empty($this->_output)) { - foreach ($this->_output as $name=>$value) { + foreach ($this->_output as $name => $value) { $temp = preg_split("/\n/", $value, -1, PREG_SPLIT_NO_EMPTY); $ups_data = array(); - foreach ($temp as $value) { - $line = preg_split('/: /', $value, 2); + foreach ($temp as $valueTemp) { + $line = preg_split('/: /', $valueTemp, 2); $ups_data[$line[0]] = isset($line[1]) ? trim($line[1]) : ''; } $dev = new UPSDevice(); @@ -95,6 +128,9 @@ class Nut extends UPS if (isset($ups_data['ups.status'])) { $dev->setStatus($ups_data['ups.status']); } + if (isset($ups_data['ups.beeper.status'])) { + $dev->setBeeperStatus($ups_data['ups.beeper.status']); + } //Line if (isset($ups_data['input.voltage'])) { @@ -133,7 +169,7 @@ class Nut extends UPS * * @see PSI_Interface_UPS::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php index b334eb9..438b9f7 100644 --- a/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php +++ b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php @@ -8,7 +8,7 @@ * @package PSI_UPS * @author Robert Pelletier * @copyright 2014 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_UPS * @author Robert Pelletier * @copyright 2014 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -38,41 +38,60 @@ class Pmset extends UPS public function __construct() { parent::__construct(); - CommonFunctions::executeProgram('pmset', '-g batt', $temp); - if (! empty($temp)) { - $this->_output[] = $temp; + if (defined('PSI_UPS_PMSET_ACCESS') && (strtolower(trim(PSI_UPS_PMSET_ACCESS))==='data')) { + if (CommonFunctions::rftsdata('upspmset.tmp', $temp)) { + $this->_output[] = $temp; + } + } elseif (PSI_OS == 'Darwin') { + if (CommonFunctions::executeProgram('pmset', '-g batt', $temp) && !empty($temp)) { + $this->_output[] = $temp; + } } } /** * parse the input and store data in resultset for xml generation * - * @return array + * @return void */ private function _info() { + if (empty($this->_output)) { + return; + } $model = array(); $percCharge = array(); $lines = explode(PHP_EOL, implode($this->_output)); - $dev = new UPSDevice(); - $model = explode('FW:', $lines[1]); - if (strpos($model[0], 'InternalBattery') === false) { - $percCharge = explode(';', $lines[1]); - $dev->setName('UPS'); - if ($model !== false) { - $dev->setModel(substr(trim($model[0]), 1)); - } - if ($percCharge !== false) { - $dev->setBatterCharge(trim(substr($percCharge[0], -4, 3))); - $dev->setStatus(trim($percCharge[1])); - if (isset($percCharge[2])) { - $time = explode(':', $percCharge[2]); - $hours = $time[0]; - $minutes = $hours*60+substr($time[1], 0, 2); - $dev->setTimeLeft($minutes); + if (count($lines)>1) { + if (strpos($lines[1], 'InternalBattery') === false) { + $dev = new UPSDevice(); + $dev->setName('UPS'); + $percCharge = explode(';', $lines[1]); + $model = explode('FW:', $lines[1]); + if ($model !== false) { + $dev->setModel(substr(trim($model[0]), 1)); } + if ($percCharge !== false) { + if (preg_match("/\s(\d+)\%$/", trim($percCharge[0]), $tmpbuf)) { + if ($tmpbuf[1]>100) { + $dev->setBatterCharge(100); + } else { + $dev->setBatterCharge($tmpbuf[1]); + } + } + $percCharge[1]=trim($percCharge[1]); + if (preg_match("/^(.+) present:/", $percCharge[1], $tmpbuf)) { + $dev->setStatus(trim($tmpbuf[1])); + } else { + $dev->setStatus($percCharge[1]); + } + if (isset($percCharge[2]) && preg_match("/\s(\d+):(\d+)\s/", $percCharge[2], $tmpbuf)) { + $dev->setTimeLeft($tmpbuf[1]*60+$tmpbuf[2]); + } + } + $dev->setMode("pmset"); + $this->upsinfo->setUpsDevices($dev); } - $this->upsinfo->setUpsDevices($dev); } } @@ -81,7 +100,7 @@ class Pmset extends UPS * * @see PSI_Interface_UPS::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php index b43ac34..9023b3d 100644 --- a/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php +++ b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php @@ -8,7 +8,7 @@ * @package PSI_UPS * @author Mieczyslaw Nalewaj * @copyright 2014 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.powersoftplus.inc.php 661 2014-06-13 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_UPS * @author Mieczyslaw Nalewaj * @copyright 2014 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,7 +28,7 @@ class PowerSoftPlus extends UPS /** * internal storage for all gathered data * - * @var Array + * @var array */ private $_output = array(); @@ -38,16 +38,23 @@ class PowerSoftPlus extends UPS public function __construct() { parent::__construct(); - CommonFunctions::executeProgram('powersoftplus', '-p', $temp); - if (! empty($temp)) { - $this->_output[] = $temp; + if (defined('PSI_UPS_POWERSOFTPLUS_ACCESS') && (strtolower(trim(PSI_UPS_POWERSOFTPLUS_ACCESS))==='data')) { + CommonFunctions::rftsdata('upspowersoftplus.tmp', $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } elseif (PSI_OS == 'Linux') { + CommonFunctions::executeProgram('powersoftplus', '-p', $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } } } /** * parse the input and store data in resultset for xml generation * - * @return Void + * @return void */ private function _info() { @@ -69,18 +76,18 @@ class PowerSoftPlus extends UPS if (preg_match('/^Current UPS state\s*:\s*(.*)$/m', $ups, $data)) { $dev->setStatus(trim($data[1])); } - if (preg_match('/^Output load\s*:\s*(.*)\s\[\%\]$/m', $ups, $data)) { + if (preg_match('/^Output load\s*:\s*(.*)\s\[\%\]\r?$/m', $ups, $data)) { $load = trim($data[1]); } //wrong Output load issue - if (($load == 0) && ($maxpwr != 0) && preg_match('/^Effective power\s*:\s*(.*)\s\[W\]$/m', $ups, $data)) { + if (($load == 0) && ($maxpwr != 0) && preg_match('/^Effective power\s*:\s*(.*)\s\[W\]\r?$/m', $ups, $data)) { $load = 100.0*trim($data[1])/$maxpwr; } if ($load != null) { $dev->setLoad($load); } // Battery - if (preg_match('/^Battery voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) { + if (preg_match('/^Battery voltage\s*:\s*(.*)\s\[Volt\]\r?$/m', $ups, $data)) { $dev->setBatteryVoltage(trim($data[1])); } if (preg_match('/^Battery state\s*:\s*(.*)$/m', $ups, $data)) { @@ -91,10 +98,10 @@ class PowerSoftPlus extends UPS } } // Line - if (preg_match('/^Input voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) { + if (preg_match('/^Input voltage\s*:\s*(.*)\s\[Volt\]\r?$/m', $ups, $data)) { $dev->setLineVoltage(trim($data[1])); } - if (preg_match('/^Input frequency\s*:\s*(.*)\s\[Hz\]$/m', $ups, $data)) { + if (preg_match('/^Input frequency\s*:\s*(.*)\s\[Hz\]\r?$/m', $ups, $data)) { $dev->setLineFrequency(trim($data[1])); } $this->upsinfo->setUpsDevices($dev); @@ -106,7 +113,7 @@ class PowerSoftPlus extends UPS * * @see PSI_Interface_UPS::build() * - * @return Void + * @return void */ public function build() { diff --git a/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php b/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php new file mode 100644 index 0000000..1ffe0df --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php @@ -0,0 +1,292 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version SVN: $Id: class.apcupsd.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting ups information from SNMPups program + * + * @category PHP + * @package PSI_UPS + * @author Michael Cramer + * @author Artem Volk + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SNMPups extends UPS +{ + /** + * internal storage for all gathered data + * + * @var array + */ + private $_output = array(); + + /** + * get all information from all configured ups in phpsysinfo.ini and store output in internal array + */ + public function __construct() + { + parent::__construct(); + if (!defined('PSI_UPS_SNMPUPS_ACCESS')) { + define('PSI_UPS_SNMPUPS_ACCESS', 'php-snmp'); + } + switch (strtolower(PSI_UPS_SNMPUPS_ACCESS)) { + case 'data': + if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) { + $upss = eval(PSI_UPS_SNMPUPS_LIST); + } else { + $upss = array(PSI_UPS_SNMPUPS_LIST); + } + } else { + $upss = array('UPS'); + } + $un = 0; + foreach ($upss as $ups) { + $temp = ""; + CommonFunctions::rftsdata("upssnmpups{$un}.tmp", $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + $un++; + } + break; + case 'command': + if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) { + $upss = eval(PSI_UPS_SNMPUPS_LIST); + } else { + $upss = array(PSI_UPS_SNMPUPS_LIST); + } + foreach ($upss as $ups) { + $buffer = ""; + CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.1", $buffer, PSI_DEBUG); + if (strlen($buffer) > 0) { + $this->_output[$ups] = $buffer; + $buffer = ""; + CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.2", $buffer, PSI_DEBUG); + if (strlen($buffer) > 0) { + $this->_output[$ups] .= "\n".$buffer; + } + $buffer = ""; + CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.3", $buffer, PSI_DEBUG); + if (strlen($buffer) > 0) { + $this->_output[$ups] .= "\n".$buffer; + } + $buffer = ""; + CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.4", $buffer, PSI_DEBUG); + if (strlen($buffer) > 0) { + $this->_output[$ups] .= "\n".$buffer; + } + } + } + } + break; + case 'php-snmp': + if (!extension_loaded("snmp")) { + $this->error->addError("Requirements error", "SNMPups plugin requires the snmp extension to php in order to work properly"); + break; + } + snmp_set_valueretrieval(SNMP_VALUE_LIBRARY); + snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC); + if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) { + $upss = eval(PSI_UPS_SNMPUPS_LIST); + } else { + $upss = array(PSI_UPS_SNMPUPS_LIST); + } + foreach ($upss as $ups) { + if (! PSI_DEBUG) { + restore_error_handler(); /* default error handler */ + $old_err_rep = error_reporting(); + error_reporting(E_ERROR); /* fatal errors only */ + } + $bufferarr=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.1", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT); + if (! PSI_DEBUG) { + error_reporting($old_err_rep); /* restore error level */ + set_error_handler('errorHandlerPsi'); /* restore error handler */ + } + if (! empty($bufferarr)) { + $buffer=""; + foreach ($bufferarr as $id=>$string) { + $buffer .= $id." = ".$string."\n"; + } + + if (! PSI_DEBUG) { + restore_error_handler(); /* default error handler */ + $old_err_rep = error_reporting(); + error_reporting(E_ERROR); /* fatal errors only */ + } + $bufferarr2=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.2", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT); + $bufferarr3=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.3", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT); + $bufferarr4=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.4", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT); + if (! PSI_DEBUG) { + error_reporting($old_err_rep); /* restore error level */ + set_error_handler('errorHandlerPsi'); /* restore error handler */ + } + if (! empty($bufferarr2)) { + foreach ($bufferarr2 as $id=>$string) { + $buffer .= $id." = ".$string."\n"; + } + } + if (! empty($bufferarr3)) { + foreach ($bufferarr3 as $id=>$string) { + $buffer .= $id." = ".$string."\n"; + } + } + if (! empty($bufferarr4)) { + foreach ($bufferarr4 as $id=>$string) { + $buffer .= $id." = ".$string."\n"; + } + } + if (strlen(trim($buffer)) > 0) { + $this->_output[$ups] = $buffer; + } + } + } + } + break; + default: + $this->error->addError("switch(PSI_UPS_SNMPUPS_ACCESS)", "Bad SNMPups configuration in phpsysinfo.ini"); + } + } + + /** + * parse the input and store data in resultset for xml generation + * + * @return void + */ + private function _info() + { + if (empty($this->_output)) { + return; + } + foreach ($this->_output as $result) { + $dev = new UPSDevice(); + $status = ""; + $status2 = ""; + $status3 = ""; + $dev->setMode("SNMP"); + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.1\.1\.2\.0 = STRING:\s(.*)/m', $result, $data)) { + $dev->setName(trim($data[1], "\" \r\t")); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.1\.1\.1\.0 = STRING:\s(.*)/m', $result, $data)) { + $dev->setModel(trim($data[1], "\" \r\t")); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.1\.1\.0 = INTEGER:\s(.*)/m', $result, $data)) { + switch (trim($data[1])) { + case 1: $status = "Unknown"; break; + case 2: $status = "On Line"; break; + case 3: $status = "On Battery"; break; + case 4: $status = "On Smart Boost"; break; + case 5: $status = "Timed Sleeping"; break; + case 6: $status = "Software Bypass"; break; + case 7: $status = "Off"; break; + case 8: $status = "Rebooting"; break; + case 9: $status = "Switched Bypass"; break; + case 10:$status = "Hardware Failure Bypass"; break; + case 11:$status = "Sleeping Until Power Returns"; break; + case 12:$status = "On Smart Trim"; break; + default: $status = "Unknown state (".trim($data[1]).")"; + } + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.1\.1\.0 = INTEGER:\s(.*)/m', $result, $data)) { + $batstat = ""; + switch (trim($data[1])) { + case 1: $batstat = "Battery Unknown"; break; + case 2: break; + case 3: $batstat = "Battery Low"; break; + default: $batstat = "Battery Unknown (".trim($data[1]).")"; + } + if ($batstat !== "") { + if ($status !== "") { + $status .= ", ".$batstat; + } else { + $status = $batstat; + } + } + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.4\.0 = INTEGER:\s(.*)/m', $result, $data)) { + $batstat = ""; + switch (trim($data[1])) { + case 1: break; + case 2: $batstat = "Replace Battery"; break; + default: $batstat = "Replace Battery (".trim($data[1]).")"; + } + if ($batstat !== "") { + if ($status !== "") { + $status .= ", ".$batstat; + } else { + $status = $batstat; + } + } + } + if ($status !== "") { + $dev->setStatus(trim($status)); + } + + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.3\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLineVoltage(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.2\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLineVoltage(trim($data[1])); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.3\.3\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLoad(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.2\.3\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLoad(trim($data[1])); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.4\.0 = INTEGER:\s(.*)/m', $result, $data)) { + $dev->setBatteryVoltage(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.8\.0 = INTEGER:\s(.*)/m', $result, $data)) { + $dev->setBatteryVoltage(trim($data[1])); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setBatterCharge(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setBatterCharge(trim($data[1])); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.3\.0 = Timeticks:\s\((\d*)\)/m', $result, $data)) { + $dev->setTimeLeft(trim($data[1])/6000); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.2\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setTemperatur(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.2\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setTemperatur(trim($data[1])); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.1\.3\.0 = STRING:\s(.*)/m', $result, $data)) { + $dev->setBatteryDate(trim($data[1], "\" \r\t")); + } + if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.3\.4\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLineFrequency(trim($data[1])/10); + } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.2\.4\.0 = Gauge32:\s(.*)/m', $result, $data)) { + $dev->setLineFrequency(trim($data[1])); + } + + $this->upsinfo->setUpsDevices($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_UPS::build() + * + * @return void + */ + public function build() + { + $this->_info(); + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.ups.inc.php b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php index c0970b4..2eae83a 100644 --- a/root/opt/phpsysinfo/includes/ups/class.ups.inc.php +++ b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php @@ -8,7 +8,7 @@ * @package PSI_UPS * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.ups.inc.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_UPS * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,9 +28,9 @@ abstract class UPS implements PSI_Interface_UPS /** * object for error handling * - * @var Error + * @var PSI_Error */ - protected $error; + public $error; /** * main object for ups information @@ -44,7 +44,7 @@ abstract class UPS implements PSI_Interface_UPS */ public function __construct() { - $this->error = Error::singleton(); + $this->error = PSI_Error::singleton(); $this->upsinfo = new UPSInfo(); } diff --git a/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php index a05ff2c..7713322 100644 --- a/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php +++ b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php @@ -8,7 +8,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.SimpleXMLExtended.inc.php 610 2012-07-11 19:12:12Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -28,7 +28,7 @@ class SimpleXMLExtended /** * store the encoding that is used for conversation to utf8 * - * @var String base encoding + * @var string base encoding */ private $_encoding = null; @@ -42,7 +42,7 @@ class SimpleXMLExtended /** * _CP437toUTF8Table for code page conversion for CP437 * - * @var _CP437toUTF8Table array + * @var array _CP437toUTF8Table array */ private static $_CP437toUTF8Table = array( "\xC3\x87","\xC3\xBC","\xC3\xA9","\xC3\xA2", @@ -108,7 +108,7 @@ class SimpleXMLExtended if ($value == null) { return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8), $this->_encoding); } else { - $valueUtf8 = htmlspecialchars($this->_toUTF8($value)); + $valueUtf8 = htmlspecialchars($this->_toUTF8($value), ENT_COMPAT, "UTF-8"); return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8, $valueUtf8), $this->_encoding); } @@ -139,13 +139,17 @@ class SimpleXMLExtended * @param String $name name of the attribute * @param String $value value of the attribute * - * @return Void + * @return void */ public function addAttribute($name, $value) { $nameUtf8 = $this->_toUTF8($name); - $valueUtf8 = htmlspecialchars($this->_toUTF8($value)); - $this->_SimpleXmlElement->addAttribute($nameUtf8, $valueUtf8); + $valueUtf8 = htmlspecialchars($this->_toUTF8($value), ENT_COMPAT, "UTF-8"); + if (($valueUtf8 === "") && (version_compare("5.2.2", PHP_VERSION, ">"))) { + $this->_SimpleXmlElement->addAttribute($nameUtf8, "\0"); // Fixing bug #41175 (addAttribute() fails to add an attribute with an empty value) + } else { + $this->_SimpleXmlElement->addAttribute($nameUtf8, $valueUtf8); + } } /** @@ -153,7 +157,7 @@ class SimpleXMLExtended * * @param SimpleXMLElement $new_child child that should be appended * - * @return Void + * @return void */ public function combinexml(SimpleXMLElement $new_child) { @@ -172,31 +176,46 @@ class SimpleXMLExtended */ private function _toUTF8($str) { + $str = trim(preg_replace('/[\x00-\x09\x0b-\x1F]/', ' ', strval($str))); //remove nonprintable characters if ($this->_encoding != null) { if (strcasecmp($this->_encoding, "UTF-8") == 0) { - return trim($str); + return $str; } elseif (strcasecmp($this->_encoding, "CP437") == 0) { - $str = trim($str); $strr = ""; if (($strl = strlen($str)) > 0) for ($i = 0; $i < $strl; $i++) { $strc = substr($str, $i, 1); if ($strc < 128) $strr.=$strc; - else $strr.=$_CP437toUTF8Table[$strc-128]; + else $strr.=self::$_CP437toUTF8Table[$strc-128]; } return $strr; } else { - $enclist = mb_list_encodings(); - if (in_array($this->_encoding, $enclist)) { - return mb_convert_encoding(trim($str), 'UTF-8', $this->_encoding); - } elseif (function_exists("iconv")) { - return iconv($this->_encoding, 'UTF-8', trim($str)); + if (preg_match("/^windows-\d+ \((.+)\)$/", $this->_encoding, $buf)) { + $encoding = $buf[1]; } else { - return mb_convert_encoding(trim($str), 'UTF-8'); + $encoding = $this->_encoding; } - } + $enclist = mb_list_encodings(); + if (in_array($encoding, $enclist)) { + return mb_convert_encoding($str, 'UTF-8', $encoding); + } elseif (function_exists("iconv")) { + if (($iconvout=iconv($encoding, 'UTF-8', $str))!==false) { + return $iconvout; + } else { + return mb_convert_encoding($str, 'UTF-8'); + } + } elseif (function_exists("libiconv") && (($iconvout=libiconv($encoding, 'UTF-8', $str))!==false)) { + return $iconvout; + } else { + return mb_convert_encoding($str, 'UTF-8'); + } + } } else { - return mb_convert_encoding(trim($str), 'UTF-8'); + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding($str, 'UTF-8'); + } else { + return $str; + } } } diff --git a/root/opt/phpsysinfo/includes/xml/class.XML.inc.php b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php index b46330a..8f2c187 100644 --- a/root/opt/phpsysinfo/includes/xml/class.XML.inc.php +++ b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php @@ -8,7 +8,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: class.XML.inc.php 699 2012-09-15 11:57:13Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -19,7 +19,7 @@ * @package PSI_XML * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version Release: 3.0 * @link http://phpsysinfo.sourceforge.net */ @@ -47,7 +47,7 @@ class XML /** * object for error handling * - * @var Error + * @var PSI_Error */ private $_errors; @@ -65,13 +65,6 @@ class XML */ private $_plugin = ''; - /** - * generate a xml for a plugin or for the main app - * - * @var boolean - */ - private $_plugin_request = false; - /** * generate the entire xml with all plugins or only a part of the xml (main or plugin) * @@ -90,23 +83,23 @@ class XML * * @return void */ - public function __construct($complete = false, $pluginname = "") + public function __construct($complete = false, $pluginname = "", $blockname = false) { - $this->_errors = Error::singleton(); - if ($pluginname == "") { - $this->_plugin_request = false; - $this->_plugin = ''; - } else { - $this->_plugin_request = true; - $this->_plugin = $pluginname; - } + $this->_errors = PSI_Error::singleton(); + $this->_plugin = $pluginname; if ($complete) { $this->_complete_request = true; } else { $this->_complete_request = false; } - $os = PSI_OS; - $this->_sysinfo = new $os(); + if (defined('PSI_EMU_PORT')) { + $os = 'SSH'; + } elseif (defined('PSI_EMU_HOSTNAME')) { + $os = 'WINNT'; + } else { + $os = PSI_OS; + } + $this->_sysinfo = new $os($blockname); $this->_plugins = CommonFunctions::getPlugins(); $this->_xmlbody(); } @@ -169,7 +162,14 @@ class XML } } } - $vitals->addAttribute('OS', PSI_OS); + + if (($os = $this->_sys->getOS()) == 'Android') { + $vitals->addAttribute('OS', 'Linux'); + } elseif ($os == 'GNU') { + $vitals->addAttribute('OS', 'Hurd'); + } else { + $vitals->addAttribute('OS', $os); + } } /** @@ -193,15 +193,50 @@ class XML } } foreach ($this->_sys->getNetDevices() as $dev) { - if (!in_array(trim($dev->getName()), $hideDevices)) { + if (defined('PSI_HIDE_NETWORK_INTERFACE_REGEX') && PSI_HIDE_NETWORK_INTERFACE_REGEX) { + $hide = false; + foreach ($hideDevices as $hidedev) { + if (preg_match('/^'.$hidedev.'$/', trim($dev->getName()))) { + $hide = true; + break; + } + } + } else { + $hide =in_array(trim($dev->getName()), $hideDevices); + } + if (!$hide) { $device = $network->addChild('NetDevice'); $device->addAttribute('Name', $dev->getName()); - $device->addAttribute('RxBytes', $dev->getRxBytes()); - $device->addAttribute('TxBytes', $dev->getTxBytes()); + $rxbytes = $dev->getRxBytes(); + $txbytes = $dev->getTxBytes(); + $device->addAttribute('RxBytes', $rxbytes); + $device->addAttribute('TxBytes', $txbytes); + if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) { + if (($rxbytes == 0) && ($txbytes == 0)) { + $rxrate = $dev->getRxRate(); + $txrate = $dev->getTxRate(); + if (($rxrate !== null) || ($txrate !== null)) { + if ($rxrate !== null) { + $device->addAttribute('RxRate', $rxrate); + } else { + $device->addAttribute('RxRate', 0); + } + if ($txrate !== null) { + $device->addAttribute('TxRate', $txrate); + } else { + $device->addAttribute('TxRate', 0); + } + } + } + } $device->addAttribute('Err', $dev->getErrors()); $device->addAttribute('Drops', $dev->getDrops()); - if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS && $dev->getInfo()) + if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE && $dev->getBridge()) { + $device->addAttribute('Bridge', $dev->getBridge()); + } + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS && $dev->getInfo()) { $device->addAttribute('Info', $dev->getInfo()); + } } } } @@ -213,77 +248,90 @@ class XML */ private function _buildHardware() { - $dev = new HWDevice(); $hardware = $this->_xml->addChild('Hardware'); - if ($this->_sys->getMachine() != "") { - $hardware->addAttribute('Name', $this->_sys->getMachine()); - } - $pci = null; - foreach (System::removeDupsAndCount($this->_sys->getPciDevices()) as $dev) { - if ($pci === null) $pci = $hardware->addChild('PCI'); - $tmp = $pci->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); - } - $usb = null; - foreach (System::removeDupsAndCount($this->_sys->getUsbDevices()) as $dev) { - if ($usb === null) $usb = $hardware->addChild('USB'); - $tmp = $usb->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); - } - $ide = null; - foreach (System::removeDupsAndCount($this->_sys->getIdeDevices()) as $dev) { - if ($ide === null) $ide = $hardware->addChild('IDE'); - $tmp = $ide->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); - if ($dev->getCapacity() !== null) { - $tmp->addAttribute('Capacity', $dev->getCapacity()); + if (($machine = $this->_sys->getMachine()) != "") { + $machine = trim(preg_replace("/\s+/", " ", preg_replace("/^\s*[\/,]*/", "", preg_replace("/\/\s+,/", "/,", $machine)))); // remove leading slash or comma and unnecessary spaces + if (preg_match('/, BIOS .*$/', $machine, $mbuf, PREG_OFFSET_CAPTURE)) { + $comapos = $mbuf[0][1]; + $endstr = $mbuf[0][0]; + $offset = 0; + while (($offset < $comapos) + && (($slashpos = strpos($machine, "/", $offset)) !== false) + && ($slashpos < $comapos)) { + $len1 = $comapos - $slashpos - 1; + $str1 = substr($machine, $slashpos + 1, $len1); + $begstr = substr($machine, 0, $slashpos); + if ($len1 > 0) { // no empty + $str2 = substr($begstr, -$len1 - 1); + } else { + $str2 = " "; + } + if ((" ".$str1 === $str2) || ($str1 === $begstr)) { // duplicates + $machine = $begstr.$endstr; + break; + } + $offset = $slashpos + 1; + } + } + + if ($machine != "") { + $hardware->addAttribute('Name', $machine); } } - $scsi = null; - foreach (System::removeDupsAndCount($this->_sys->getScsiDevices()) as $dev) { - if ($scsi === null) $scsi = $hardware->addChild('SCSI'); - $tmp = $scsi->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); - if ($dev->getCapacity() !== null) { - $tmp->addAttribute('Capacity', $dev->getCapacity()); + + if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) { + $virt = $this->_sys->getVirtualizer(); + $virtstring = ""; + foreach ($virt as $virtkey=>$virtvalue) if ($virtvalue) { + if ($virtstring !== "") { + $virtstring .= ", "; + } + if ($virtkey === 'microsoft') { + if (!isset($virt["wsl"]) || !$virt["wsl"]) { + $virtstring .= 'hyper-v'; + } + } elseif ($virtkey === 'kvm') { + $virtstring .= 'qemu-kvm'; + } elseif ($virtkey === 'oracle') { + $virtstring .= 'virtualbox'; + } elseif ($virtkey === 'zvm') { + $virtstring .= 'z/vm'; + } elseif ($virtkey === 'sre') { + $virtstring .= 'lmhs sre'; + } else { + $virtstring .= $virtkey; + } + } + if ($virtstring !== "") { + $hardware->addAttribute('Virtualizer', $virtstring); } - } - $tb = null; - foreach (System::removeDupsAndCount($this->_sys->getTbDevices()) as $dev) { - if ($tb === null) $tb = $hardware->addChild('TB'); - $tmp = $tb->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); - } - $i2c = null; - foreach (System::removeDupsAndCount($this->_sys->getI2cDevices()) as $dev) { - if ($i2c === null) $i2c = $hardware->addChild('I2C'); - $tmp = $i2c->addChild('Device'); - $tmp->addAttribute('Name', $dev->getName()); - $tmp->addAttribute('Count', $dev->getCount()); } $cpu = null; + $vendortab = null; foreach ($this->_sys->getCpus() as $oneCpu) { if ($cpu === null) $cpu = $hardware->addChild('CPU'); $tmp = $cpu->addChild('CpuCore'); $tmp->addAttribute('Model', $oneCpu->getModel()); - if ($oneCpu->getCpuSpeed() !== 0) { - $tmp->addAttribute('CpuSpeed', $oneCpu->getCpuSpeed()); + if ($oneCpu->getVoltage() > 0) { + $tmp->addAttribute('Voltage', $oneCpu->getVoltage()); } - if ($oneCpu->getCpuSpeedMax() !== 0) { + if ($oneCpu->getCpuSpeed() > 0) { + $tmp->addAttribute('CpuSpeed', $oneCpu->getCpuSpeed()); + } elseif ($oneCpu->getCpuSpeed() == -1) { + $tmp->addAttribute('CpuSpeed', 0); // core stopped + } + if ($oneCpu->getCpuSpeedMax() > 0) { $tmp->addAttribute('CpuSpeedMax', $oneCpu->getCpuSpeedMax()); } - if ($oneCpu->getCpuSpeedMin() !== 0) { + if ($oneCpu->getCpuSpeedMin() > 0) { $tmp->addAttribute('CpuSpeedMin', $oneCpu->getCpuSpeedMin()); } +/* if ($oneCpu->getTemp() !== null) { $tmp->addAttribute('CpuTemp', $oneCpu->getTemp()); } +*/ if ($oneCpu->getBusSpeed() !== null) { $tmp->addAttribute('BusSpeed', $oneCpu->getBusSpeed()); } @@ -293,6 +341,13 @@ class XML if ($oneCpu->getVirt() !== null) { $tmp->addAttribute('Virt', $oneCpu->getVirt()); } + if ($oneCpu->getVendorId() !== null) { + if ($vendortab === null) $vendortab = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true); + $shortvendorid = $oneCpu->getVendorId(); + if ($vendortab && ($shortvendorid != "") && isset($vendortab['manufacturer'][$shortvendorid])) { + $tmp->addAttribute('Manufacturer', $vendortab['manufacturer'][$shortvendorid]); + } + } if ($oneCpu->getBogomips() !== null) { $tmp->addAttribute('Bogomips', $oneCpu->getBogomips()); } @@ -300,6 +355,144 @@ class XML $tmp->addAttribute('Load', $oneCpu->getLoad()); } } + $mem = null; + foreach (System::removeDupsAndCount($this->_sys->getMemDevices()) as $dev) { + if ($mem === null) $mem = $hardware->addChild('MEM'); + $tmp = $mem->addChild('Chip'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + if ($dev->getManufacturer() !== null) { + $tmp->addAttribute('Manufacturer', $dev->getManufacturer()); + } + if ($dev->getProduct() !== null) { + $tmp->addAttribute('Product', $dev->getProduct()); + } + if ($dev->getSpeed() !== null) { + $tmp->addAttribute('Speed', $dev->getSpeed()); + } + if ($dev->getVoltage() !== null) { + $tmp->addAttribute('Voltage', $dev->getVoltage()); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) { + $tmp->addAttribute('Serial', $dev->getSerial()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $pci = null; + foreach (System::removeDupsAndCount($this->_sys->getPciDevices()) as $dev) { + if ($pci === null) $pci = $hardware->addChild('PCI'); + $tmp = $pci->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getManufacturer() !== null) { + $tmp->addAttribute('Manufacturer', $dev->getManufacturer()); + } + if ($dev->getProduct() !== null) { + $tmp->addAttribute('Product', $dev->getProduct()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $ide = null; + foreach (System::removeDupsAndCount($this->_sys->getIdeDevices()) as $dev) { + if ($ide === null) $ide = $hardware->addChild('IDE'); + $tmp = $ide->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) { + $tmp->addAttribute('Serial', $dev->getSerial()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $scsi = null; + foreach (System::removeDupsAndCount($this->_sys->getScsiDevices()) as $dev) { + if ($scsi === null) $scsi = $hardware->addChild('SCSI'); + $tmp = $scsi->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) { + $tmp->addAttribute('Serial', $dev->getSerial()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $nvme = null; + foreach (System::removeDupsAndCount($this->_sys->getNvmeDevices()) as $dev) { + if ($nvme === null) $nvme = $hardware->addChild('NVMe'); + $tmp = $nvme->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) { + $tmp->addAttribute('Serial', $dev->getSerial()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $usb = null; + foreach (System::removeDupsAndCount($this->_sys->getUsbDevices()) as $dev) { + if ($usb === null) $usb = $hardware->addChild('USB'); + $tmp = $usb->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) { + if ($dev->getManufacturer() !== null) { + $tmp->addAttribute('Manufacturer', $dev->getManufacturer()); + } + if ($dev->getProduct() !== null) { + $tmp->addAttribute('Product', $dev->getProduct()); + } + if ($dev->getSpeed() !== null) { + $tmp->addAttribute('Speed', $dev->getSpeed()); + } + if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) { + $tmp->addAttribute('Serial', $dev->getSerial()); + } + } + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $tb = null; + foreach (System::removeDupsAndCount($this->_sys->getTbDevices()) as $dev) { + if ($tb === null) $tb = $hardware->addChild('TB'); + $tmp = $tb->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } + $i2c = null; + foreach (System::removeDupsAndCount($this->_sys->getI2cDevices()) as $dev) { + if ($i2c === null) $i2c = $hardware->addChild('I2C'); + $tmp = $i2c->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + if ($dev->getCount() > 1) { + $tmp->addAttribute('Count', $dev->getCount()); + } + } } /** @@ -348,28 +541,32 @@ class XML * * @param SimpleXmlExtended $mount Xml-Element * @param DiskDevice $dev DiskDevice - * @param Integer $i counter + * @param int $i counter * - * @return Void + * @return void */ private function _fillDevice(SimpleXMLExtended $mount, DiskDevice $dev, $i) { $mount->addAttribute('MountPointID', $i); - $mount->addAttribute('FSType', $dev->getFsType()); + if ($dev->getFsType()!=="") { + $mount->addAttribute('FSType', $dev->getFsType()); + } $mount->addAttribute('Name', $dev->getName()); $mount->addAttribute('Free', sprintf("%.0f", $dev->getFree())); $mount->addAttribute('Used', sprintf("%.0f", $dev->getUsed())); $mount->addAttribute('Total', sprintf("%.0f", $dev->getTotal())); - $mount->addAttribute('Percent', $dev->getPercentUsed()); - if (PSI_SHOW_MOUNT_OPTION === true) { + $percentUsed = $dev->getPercentUsed(); + $mount->addAttribute('Percent', $percentUsed); + if ($dev->getPercentInodesUsed() !== null) { + $mount->addAttribute('Inodes', $dev->getPercentInodesUsed()); + } + if ($dev->getIgnore() > 0) $mount->addAttribute('Ignore', $dev->getIgnore()); + if (PSI_SHOW_MOUNT_OPTION) { if ($dev->getOptions() !== null) { $mount->addAttribute('MountOptions', preg_replace("/,/", ", ", $dev->getOptions())); } } - if ($dev->getPercentInodesUsed() !== null) { - $mount->addAttribute('Inodes', $dev->getPercentInodesUsed()); - } - if (PSI_SHOW_MOUNT_POINT === true) { + if (PSI_SHOW_MOUNT_POINT && ($dev->getMountPoint() !== null)) { $mount->addAttribute('MountPoint', $dev->getMountPoint()); } } @@ -381,8 +578,7 @@ class XML */ private function _buildFilesystems() { - $hideMounts = $hideFstypes = $hideDisks = array(); - $i = 1; + $hideMounts = $hideFstypes = $hideDisks = $ignoreFree = $ignoreTotal = $ignoreUsage = $ignoreThreshold = array(); if (defined('PSI_HIDE_MOUNTS') && is_string(PSI_HIDE_MOUNTS)) { if (preg_match(ARRAY_EXP, PSI_HIDE_MOUNTS)) { $hideMounts = eval(PSI_HIDE_MOUNTS); @@ -408,10 +604,48 @@ class XML return; } } + if (defined('PSI_IGNORE_FREE') && is_string(PSI_IGNORE_FREE)) { + if (preg_match(ARRAY_EXP, PSI_IGNORE_FREE)) { + $ignoreFree = eval(PSI_IGNORE_FREE); + } else { + $ignoreFree = array(PSI_IGNORE_FREE); + } + } + if (defined('PSI_IGNORE_TOTAL') && is_string(PSI_IGNORE_TOTAL)) { + if (preg_match(ARRAY_EXP, PSI_IGNORE_TOTAL)) { + $ignoreTotal = eval(PSI_IGNORE_TOTAL); + } else { + $ignoreTotal = array(PSI_IGNORE_TOTAL); + } + } + if (defined('PSI_IGNORE_USAGE') && is_string(PSI_IGNORE_USAGE)) { + if (preg_match(ARRAY_EXP, PSI_IGNORE_USAGE)) { + $ignoreUsage = eval(PSI_IGNORE_USAGE); + } else { + $ignoreUsage = array(PSI_IGNORE_USAGE); + } + } + if (defined('PSI_IGNORE_THRESHOLD_FS_TYPES') && is_string(PSI_IGNORE_THRESHOLD_FS_TYPES)) { + if (preg_match(ARRAY_EXP, PSI_IGNORE_THRESHOLD_FS_TYPES)) { + $ignoreThreshold = eval(PSI_IGNORE_THRESHOLD_FS_TYPES); + } else { + $ignoreThreshold = array(PSI_IGNORE_THRESHOLD_FS_TYPES); + } + } $fs = $this->_xml->addChild('FileSystem'); + $i = 1; foreach ($this->_sys->getDiskDevices() as $disk) { if (!in_array($disk->getMountPoint(), $hideMounts, true) && !in_array($disk->getFsType(), $hideFstypes, true) && !in_array($disk->getName(), $hideDisks, true)) { $mount = $fs->addChild('Mount'); + if (in_array($disk->getFsType(), $ignoreThreshold, true)) { + $disk->setIgnore(4); + } elseif (in_array($disk->getMountPoint(), $ignoreUsage, true)) { + $disk->setIgnore(3); + } elseif (in_array($disk->getMountPoint(), $ignoreTotal, true)) { + $disk->setIgnore(2); + } elseif (in_array($disk->getMountPoint(), $ignoreFree, true)) { + $disk->setIgnore(1); + } $this->_fillDevice($mount, $disk, $i++); } } @@ -425,105 +659,151 @@ class XML private function _buildMbinfo() { $mbinfo = $this->_xml->addChild('MBInfo'); - $temp = $fan = $volt = $power = $current = null; + $temp = $fan = $volt = $power = $current = $other = null; + $hideSensors = array(); if (sizeof(unserialize(PSI_MBINFO))>0) { + if (defined('PSI_HIDE_SENSORS') && is_string(PSI_HIDE_SENSORS)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_SENSORS)) { + $hideSensors = eval(PSI_HIDE_SENSORS); + } else { + $hideSensors = array(PSI_HIDE_SENSORS); + } + } foreach (unserialize(PSI_MBINFO) as $mbinfoclass) { $mbinfo_data = new $mbinfoclass(); $mbinfo_detail = $mbinfo_data->getMBInfo(); - - foreach ($mbinfo_detail->getMbTemp() as $dev) { - if ($temp == null) { - $temp = $mbinfo->addChild('Temperature'); - } - $item = $temp->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMax() !== null) { - $item->addAttribute('Max', $dev->getMax()); - } - if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { - $item->addAttribute('Event', $dev->getEvent()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='temperature' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbTemp() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($temp == null) { + $temp = $mbinfo->addChild('Temperature'); + } + $item = $temp->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + $alarm = false; + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + $alarm = true; + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } } } - foreach ($mbinfo_detail->getMbFan() as $dev) { - if ($fan == null) { - $fan = $mbinfo->addChild('Fans'); - } - $item = $fan->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMin() !== null) { - $item->addAttribute('Min', $dev->getMin()); - } - if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { - $item->addAttribute('Event', $dev->getEvent()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='fans' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbFan() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($fan == null) { + $fan = $mbinfo->addChild('Fans'); + } + $item = $fan->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + $alarm = false; + if ($dev->getMin() !== null) { + $item->addAttribute('Min', $dev->getMin()); + $alarm = true; + } + if ($dev->getUnit() !== "") { + $item->addAttribute('Unit', $dev->getUnit()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } } } - foreach ($mbinfo_detail->getMbVolt() as $dev) { - if ($volt == null) { - $volt = $mbinfo->addChild('Voltage'); - } - $item = $volt->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMin() !== null) { - $item->addAttribute('Min', $dev->getMin()); - } - if ($dev->getMax() !== null) { - $item->addAttribute('Max', $dev->getMax()); - } - if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { - $item->addAttribute('Event', $dev->getEvent()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='voltage' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbVolt() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($volt == null) { + $volt = $mbinfo->addChild('Voltage'); + } + $item = $volt->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + $alarm = false; + if (($dev->getMin() === null) || ($dev->getMin() != 0) || ($dev->getMax() === null) || ($dev->getMax() != 0)) { + if ($dev->getMin() !== null) { + $item->addAttribute('Min', $dev->getMin()); + $alarm = true; + } + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + $alarm = true; + } + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } } } - foreach ($mbinfo_detail->getMbPower() as $dev) { - if ($power == null) { - $power = $mbinfo->addChild('Power'); - } - $item = $power->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMax() !== null) { - $item->addAttribute('Max', $dev->getMax()); - } - if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { - $item->addAttribute('Event', $dev->getEvent()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='power' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbPower() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($power == null) { + $power = $mbinfo->addChild('Power'); + } + $item = $power->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + $alarm = false; + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + $alarm = true; + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } } } - foreach ($mbinfo_detail->getMbCurrent() as $dev) { - if ($current == null) { - $current = $mbinfo->addChild('Current'); - } - $item = $current->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMax() !== null) { - $item->addAttribute('Max', $dev->getMax()); - } - if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { - $item->addAttribute('Event', $dev->getEvent()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='current' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbCurrent() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($current == null) { + $current = $mbinfo->addChild('Current'); + } + $item = $current->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + $alarm = false; + if (($dev->getMin() === null) || ($dev->getMin() != 0) || ($dev->getMax() === null) || ($dev->getMax() != 0)) { + if ($dev->getMin() !== null) { + $item->addAttribute('Min', $dev->getMin()); + $alarm = true; + } + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + $alarm = true; + } + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } } } - } - } - if (PSI_HDDTEMP) { - $hddtemp = new HDDTemp(); - $hddtemp_data = $hddtemp->getMBInfo(); - foreach ($hddtemp_data->getMbTemp() as $dev) { - if ($temp == null) { - $temp = $mbinfo->addChild('Temperature'); - } - $item = $temp->addChild('Item'); - $item->addAttribute('Label', $dev->getName()); - $item->addAttribute('Value', $dev->getValue()); - if ($dev->getMax() !== null) { - $item->addAttribute('Max', $dev->getMax()); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='other' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbOther() as $dev) { + $mbinfo_name = $dev->getName(); + if (!in_array($mbinfo_name, $hideSensors, true)) { + if ($other == null) { + $other = $mbinfo->addChild('Other'); + } + $item = $other->addChild('Item'); + $item->addAttribute('Label', $mbinfo_name); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getUnit() !== "") { + $item->addAttribute('Unit', $dev->getUnit()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent()))); + } + } } } } @@ -537,7 +817,7 @@ class XML private function _buildUpsinfo() { $upsinfo = $this->_xml->addChild('UPSInfo'); - if (defined('PSI_UPS_APCUPSD_CGI_ENABLE') && PSI_UPS_APCUPSD_CGI_ENABLE) { + if (!defined('PSI_EMU_HOSTNAME') && defined('PSI_UPS_APCUPSD_CGI_ENABLE') && PSI_UPS_APCUPSD_CGI_ENABLE) { $upsinfo->addAttribute('ApcupsdCgiLinks', true); } if (sizeof(unserialize(PSI_UPSINFO))>0) { @@ -550,11 +830,16 @@ class XML if ($ups->getModel() !== "") { $item->addAttribute('Model', $ups->getModel()); } - $item->addAttribute('Mode', $ups->getMode()); + if ($ups->getMode() !== "") { + $item->addAttribute('Mode', $ups->getMode()); + } if ($ups->getStartTime() !== "") { $item->addAttribute('StartTime', $ups->getStartTime()); } $item->addAttribute('Status', $ups->getStatus()); + if ($ups->getBeeperStatus() !== null) { + $item->addAttribute('BeeperStatus', $ups->getBeeperStatus()); + } if ($ups->getTemperatur() !== null) { $item->addAttribute('Temperature', $ups->getTemperatur()); } @@ -600,9 +885,14 @@ class XML */ private function _buildXml() { - if (!$this->_plugin_request || $this->_complete_request) { + if (($this->_plugin == '') || $this->_complete_request) { if ($this->_sys === null) { - if (PSI_DEBUG === true) { + if (PSI_DEBUG) { + // unstable version check + if (!is_numeric(substr(PSI_VERSION, -1))) { + $this->_errors->addWarning("This is an unstable version of phpSysInfo, some things may not work correctly"); + } + // Safe mode check $safe_mode = @ini_get("safe_mode") ? true : false; if ($safe_mode) { @@ -620,28 +910,28 @@ class XML $this->_errors->addError("WARN", "PhpSysInfo requires '.' inside the 'include_path' in php.ini"); } // popen mode check - if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) { $this->_errors->addError("WARN", "Installed version of PHP does not support proc_open() function, popen() is used"); } } $this->_sys = $this->_sysinfo->getSys(); } - $this->_buildVitals(); - $this->_buildNetwork(); - $this->_buildHardware(); - $this->_buildMemory(); - $this->_buildFilesystems(); - $this->_buildMbinfo(); - $this->_buildUpsinfo(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='vitals') $this->_buildVitals(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='network') $this->_buildNetwork(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='hardware') $this->_buildHardware(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='memory') $this->_buildMemory(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='filesystem') $this->_buildFilesystems(); + if (!$this->_sysinfo->getBlockName() || in_array($this->_sysinfo->getBlockName(), array('mbinfo','voltage','current','temperature','fans','power','other'))) $this->_buildMbinfo(); + if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='ups') $this->_buildUpsinfo(); } - $this->_buildPlugins(); + if (!$this->_sysinfo->getBlockName()) $this->_buildPlugins(); $this->_xml->combinexml($this->_errors->errorsAddToXML($this->_sysinfo->getEncoding())); } /** * get the xml object * - * @return string + * @return SimpleXmlElement */ public function getXml() { @@ -658,20 +948,25 @@ class XML private function _buildPlugins() { $pluginroot = $this->_xml->addChild("Plugins"); - if (($this->_plugin_request || $this->_complete_request) && count($this->_plugins) > 0) { + if ((($this->_plugin != '') || $this->_complete_request) && count($this->_plugins) > 0) { $plugins = array(); if ($this->_complete_request) { $plugins = $this->_plugins; } - if ($this->_plugin_request) { + if (($this->_plugin != '')) { $plugins = array($this->_plugin); } foreach ($plugins as $plugin) { - $object = new $plugin($this->_sysinfo->getEncoding()); - $object->execute(); - $oxml = $object->xml(); - if (sizeof($oxml) > 0) { - $pluginroot->combinexml($oxml); + if (!$this->_complete_request || + (!defined('PSI_PLUGIN_'.strtoupper($plugin).'_SSH_HOSTNAME') && !defined('PSI_PLUGIN_'.strtoupper($plugin).'_WMI_HOSTNAME')) || + (defined('PSI_SSH_HOSTNAME') && (PSI_SSH_HOSTNAME == constant('PSI_PLUGIN_'.strtoupper($plugin).'_SSH_HOSTNAME'))) || + (defined('PSI_WMI_HOSTNAME') && (PSI_WMI_HOSTNAME == constant('PSI_PLUGIN_'.strtoupper($plugin).'_WMI_HOSTNAME')))) { + $object = new $plugin($this->_sysinfo->getEncoding()); + $object->execute(); + $oxml = $object->xml(); + if (sizeof($oxml) > 0) { + $pluginroot->combinexml($oxml); + } } } } @@ -698,32 +993,21 @@ class XML $options = $this->_xml->addChild('Options'); $options->addAttribute('tempFormat', defined('PSI_TEMP_FORMAT') ? strtolower(PSI_TEMP_FORMAT) : 'c'); $options->addAttribute('byteFormat', defined('PSI_BYTE_FORMAT') ? strtolower(PSI_BYTE_FORMAT) : 'auto_binary'); + $options->addAttribute('datetimeFormat', defined('PSI_DATETIME_FORMAT') ? strtolower(PSI_DATETIME_FORMAT) : 'utc'); if (defined('PSI_REFRESH')) { - if (PSI_REFRESH === false) { - $options->addAttribute('refresh', 0); - } elseif (PSI_REFRESH === true) { - $options->addAttribute('refresh', 1); - } else { - $options->addAttribute('refresh', PSI_REFRESH); - } + $options->addAttribute('refresh', max(intval(PSI_REFRESH), 0)); } else { $options->addAttribute('refresh', 60000); } if (defined('PSI_FS_USAGE_THRESHOLD')) { - if (PSI_FS_USAGE_THRESHOLD === true) { - $options->addAttribute('threshold', 1); - } elseif ((PSI_FS_USAGE_THRESHOLD !== false) && (PSI_FS_USAGE_THRESHOLD >= 1) && (PSI_FS_USAGE_THRESHOLD <= 99)) { - $options->addAttribute('threshold', PSI_FS_USAGE_THRESHOLD); + if ((($fsut = intval(PSI_FS_USAGE_THRESHOLD)) >= 1) && ($fsut <= 99)) { + $options->addAttribute('threshold', $fsut); } } else { $options->addAttribute('threshold', 90); } - $options->addAttribute('showPickListTemplate', defined('PSI_SHOW_PICKLIST_TEMPLATE') ? (PSI_SHOW_PICKLIST_TEMPLATE ? 'true' : 'false') : 'false'); - $options->addAttribute('showPickListLang', defined('PSI_SHOW_PICKLIST_LANG') ? (PSI_SHOW_PICKLIST_LANG ? 'true' : 'false') : 'false'); - $options->addAttribute('showCPUListExpanded', defined('PSI_SHOW_CPULIST_EXPANDED') ? (PSI_SHOW_CPULIST_EXPANDED ? 'true' : 'false') : 'true'); - $options->addAttribute('showCPUInfoExpanded', defined('PSI_SHOW_CPUINFO_EXPANDED') ? (PSI_SHOW_CPUINFO_EXPANDED ? 'true' : 'false') : 'false'); if (count($this->_plugins) > 0) { - if ($this->_plugin_request) { + if (($this->_plugin != '')) { $plug = $this->_xml->addChild('UsedPlugins'); $plug->addChild('Plugin')->addAttribute('name', $this->_plugin); } elseif ($this->_complete_request) { @@ -731,11 +1015,13 @@ class XML foreach ($this->_plugins as $plugin) { $plug->addChild('Plugin')->addAttribute('name', $plugin); } +/* } else { $plug = $this->_xml->addChild('UnusedPlugins'); foreach ($this->_plugins as $plugin) { $plug->addChild('Plugin')->addAttribute('name', $plugin); } +*/ } } } diff --git a/root/opt/phpsysinfo/index.php b/root/opt/phpsysinfo/index.php index 2314548..fbd88e7 100644 --- a/root/opt/phpsysinfo/index.php +++ b/root/opt/phpsysinfo/index.php @@ -9,7 +9,7 @@ * @package PSI * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: index.php 687 2012-09-06 20:54:49Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -17,27 +17,19 @@ * define the application root path on the webserver * @var string */ -define('APP_ROOT', dirname(__FILE__)); +define('PSI_APP_ROOT', dirname(__FILE__)); -/** - * internal xml or external - * external is needed when running in static mode - * - * @var boolean - */ -define('PSI_INTERNAL_XML', false); - -if (version_compare("5.2", PHP_VERSION, ">")) { - die("PHP 5.2 or greater is required!!!"); +if (version_compare("5.1.3", PHP_VERSION, ">")) { + die("PHP 5.1.3 or greater is required!!!"); } if (!extension_loaded("pcre")) { die("phpSysInfo requires the pcre extension to php in order to work properly."); } -require_once APP_ROOT.'/includes/autoloader.inc.php'; +require_once PSI_APP_ROOT.'/includes/autoloader.inc.php'; // Load configuration -require_once APP_ROOT.'/read_config.php'; +require_once PSI_APP_ROOT.'/read_config.php'; if (!defined('PSI_CONFIG_FILE') || !defined('PSI_DEBUG')) { $tpl = new Template("/templates/html/error_config.html"); @@ -46,7 +38,7 @@ if (!defined('PSI_CONFIG_FILE') || !defined('PSI_DEBUG')) { } // redirect to page with and without javascript -$display = isset($_GET['disp']) ? $_GET['disp'] : strtolower(PSI_DEFAULT_DISPLAY_MODE); +$display = strtolower(isset($_GET['disp']) ? $_GET['disp'] : PSI_DEFAULT_DISPLAY_MODE); switch ($display) { case "static": $webpage = new WebpageXSLT(); @@ -57,15 +49,45 @@ case "dynamic": $webpage->run(); break; case "xml": - $webpage = new WebpageXML(true, null); + $webpage = new WebpageXML("complete"); $webpage->run(); break; +case "json": + $webpage = new WebpageXML("complete"); + $json = $webpage->getJsonString(); + header('Cache-Control: no-cache, must-revalidate'); + header('Content-Type: application/json'); + echo $json; + break; case "bootstrap": +/* $tpl = new Template("/templates/html/index_bootstrap.html"); echo $tpl->fetch(); +*/ + $webpage = new Webpage("bootstrap"); + $webpage->run(); break; -default: +case "auto": $tpl = new Template("/templates/html/index_all.html"); echo $tpl->fetch(); break; +default: + $defaultdisplay = strtolower(PSI_DEFAULT_DISPLAY_MODE); + switch ($defaultdisplay) { + case "static": + $webpage = new WebpageXSLT(); + $webpage->run(); + break; + case "dynamic": + $webpage = new Webpage(); + $webpage->run(); + break; + case "bootstrap": + $webpage = new Webpage("bootstrap"); + $webpage->run(); + break; + default: + $tpl = new Template("/templates/html/index_all.html"); + echo $tpl->fetch(); + } } diff --git a/root/opt/phpsysinfo/js.php b/root/opt/phpsysinfo/js.php index 375cb99..39f30a5 100644 --- a/root/opt/phpsysinfo/js.php +++ b/root/opt/phpsysinfo/js.php @@ -8,7 +8,7 @@ * @package PSI_JS * @author Michael Cramer * @copyright 2009 phpSysInfo - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version * @version SVN: $Id: js.php 661 2012-08-27 11:26:39Z namiltd $ * @link http://phpsysinfo.sourceforge.net */ @@ -17,11 +17,11 @@ * * @var string */ -define('APP_ROOT', dirname(__FILE__)); +define('PSI_APP_ROOT', dirname(__FILE__)); -require_once APP_ROOT.'/includes/autoloader.inc.php'; +require_once PSI_APP_ROOT.'/includes/autoloader.inc.php'; -require_once APP_ROOT.'/read_config.php'; +require_once PSI_APP_ROOT.'/read_config.php'; $file = isset($_GET['name']) ? basename(htmlspecialchars($_GET['name'])) : null; $plugin = isset($_GET['plugin']) ? basename(htmlspecialchars($_GET['plugin'])) : null; @@ -29,16 +29,16 @@ $script = null; if ($file != null && $plugin == null) { if (strtolower(substr($file, 0, 6)) == 'jquery') { - $script = APP_ROOT.'/js/jQuery/'.$file; + $script = PSI_APP_ROOT.'/js/jQuery/'.$file; } elseif (strtolower(substr($file, 0, 10)) == 'phpsysinfo') { - $script = APP_ROOT.'/js/phpSysInfo/'.$file; + $script = PSI_APP_ROOT.'/js/phpSysInfo/'.$file; } else { - $script = APP_ROOT.'/js/vendor/'.$file; + $script = PSI_APP_ROOT.'/js/vendor/'.$file; } } elseif ($file == null && $plugin != null) { - $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($plugin); + $script = PSI_APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($plugin); } elseif ($file != null && $plugin != null) { - $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($file); + $script = PSI_APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($file); } if ($script != null) { @@ -46,40 +46,33 @@ if ($script != null) { $scriptmin = $script.'.min.js'; $compression = false; - header("content-type: application/x-javascript"); + header('content-type: application/x-javascript'); if ((!defined("PSI_DEBUG") || (PSI_DEBUG !== true)) && defined("PSI_JS_COMPRESSION")) { $compression = strtolower(PSI_JS_COMPRESSION); } switch ($compression) { - case "normal": - if (file_exists($scriptmin) && is_readable($scriptmin)) { - $filecontent = file_get_contents($scriptmin); - echo $filecontent; - } elseif (file_exists($scriptjs) && is_readable($scriptjs)) { - $filecontent = file_get_contents($scriptjs); - $packer = new JavaScriptPacker($filecontent); - echo $packer->pack(); - } - break; - case "none": - if (file_exists($scriptjs) && is_readable($scriptjs)) { - $filecontent = file_get_contents($scriptjs); - $packer = new JavaScriptPacker($filecontent, 0); - echo $packer->pack(); - } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { - $filecontent = file_get_contents($scriptmin); - echo $filecontent; - } - break; - default: - if (file_exists($scriptjs) && is_readable($scriptjs)) { - $filecontent = file_get_contents($scriptjs); - } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { - $filecontent = file_get_contents($scriptmin); - } else break; - - echo $filecontent; - break; + case "normal": + if (file_exists($scriptmin) && is_readable($scriptmin)) { + echo file_get_contents($scriptmin); + } elseif (file_exists($scriptjs) && is_readable($scriptjs)) { + $packer = new JavaScriptPacker(file_get_contents($scriptjs)); + echo $packer->pack(); + } + break; + case "none": + if (file_exists($scriptjs) && is_readable($scriptjs)) { + $packer = new JavaScriptPacker(file_get_contents($scriptjs), 0); + echo $packer->pack(); + } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { + echo file_get_contents($scriptmin); + } + break; + default: + if (file_exists($scriptjs) && is_readable($scriptjs)) { + echo file_get_contents($scriptjs); + } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { + echo file_get_contents($scriptmin); + } } } diff --git a/root/opt/phpsysinfo/js/jQuery/README b/root/opt/phpsysinfo/js/jQuery/README index 5e80578..8f5300c 100644 --- a/root/opt/phpsysinfo/js/jQuery/README +++ b/root/opt/phpsysinfo/js/jQuery/README @@ -1,17 +1,10 @@ versions, links and simple description of used jquery files =========================================================== + jquery.js --------- -VERSION : 2.1.4 -URL : http://jquery.com/ -DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle - events, perform animations, and add Ajax interactions to your web pages. -USED : used for the entire userinterface - -jquery-1.js ---------- -VERSION : 1.11.3 +VERSION : v1.12.4-ff3fix-ff2fix-CVE_2015_9251fix-CVE_2019_11358fix-CVE_2020_11022fix-CVE_2020_11023fix URL : http://jquery.com/ DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages. @@ -20,7 +13,7 @@ USED : used for the entire userinterface jquery.dataTables.js -------------------- -VERSION : 1.8.2 +VERSION : 1.8.2+jquery1.9fix+parseJSONfix2+bindfix+samesitefix+noeval URL : http://plugins.jquery.com/project/DataTables DESC : dataTables is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. @@ -28,31 +21,38 @@ USED : provide tablesorting for the filesystem table jquery.nyroModal.js ------------------- -VERSION : 1.6.2+jquery1.8fix +VERSION : 1.6.2+jquery1.8fix+bindfix+ff2fix URL : http://plugins.jquery.com/project/nyroModal DESC : nyroModal is a high customizable modal window plugin. USED : provide a modal dialog, that is shown when errors are found during execution of the php parsers, or lets say in this way: if there are error elements in the xml file -jquery.timers.js +jquery.timer.js ---------------- VERSION : 0.1 -URL : http://plugins.jquery.com/project/Timer +URL : http://plugins.jquery.com/project/Timer; https://github.com/sloat/timer DESC : provides a cleaner way to handle intervals USED : automatic reloading of the entire page jquery.jgrowl.js ---------------- -VERSION : 1.2.6 +VERSION : 1.2.6+jquery1.9fix+jquery3fix+bindfix URL : http://plugins.jquery.com/project/jGrowl DESC : jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works USED : show alert and error message jquery.treeTable.js ------------------- -VERSION : 2009-06-22+statefix +VERSION : 2009-06-22+statefix+spanfix+altfix+undefinedfix+ie6cachefix+multilinefix+divfix URL : http://plugins.jquery.com/project/jQTreeTable; http://www.hanpau.com/index.php?page=jqtreetable DESC : Take a plain html table, wrap the rows you want collapsing/expanding in a tbody tag with an id of treetable, map each row to it's parent row, set some options, and let jQTreeTable take it from there. USED : Hardware, Memory, UPS blocks +jquery.ifixpng.js +------------------- +VERSION : 2.1 (23/04/2008)+jquery1.9fix +URL : http://jquery.khurshid.com +DESC : Designed to fix that problem by applying appropriate filters to user specified elements, while keeping all element tags intact. +USED : used for the entire userinterface + $Id: README 702 2012-09-21 16:52:32Z namiltd $ diff --git a/root/opt/phpsysinfo/js/jQuery/README_bootstrap b/root/opt/phpsysinfo/js/jQuery/README_bootstrap index 18e9b93..2cda39e 100644 --- a/root/opt/phpsysinfo/js/jQuery/README_bootstrap +++ b/root/opt/phpsysinfo/js/jQuery/README_bootstrap @@ -3,15 +3,7 @@ versions, links and simple description of used jquery files jquery.js --------- -VERSION : 2.1.4 -URL : http://jquery.com/ -DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle - events, perform animations, and add Ajax interactions to your web pages. -USED : used for the entire userinterface - -jquery-1.js ---------- -VERSION : 1.11.3 +VERSION : v1.12.4-ff3fix-ff2fix-CVE_2015_9251fix-CVE_2019_11358fix-CVE_2020_11022fix-CVE_2020_11023fix URL : http://jquery.com/ DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages. diff --git a/root/opt/phpsysinfo/js/jQuery/jquery-1.js b/root/opt/phpsysinfo/js/jQuery/jquery-1.js deleted file mode 100644 index 6feb110..0000000 --- a/root/opt/phpsysinfo/js/jQuery/jquery-1.js +++ /dev/null @@ -1,10351 +0,0 @@ -/*! - * jQuery JavaScript Library v1.11.3 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-04-28T16:19Z - */ - -(function( global, factory ) { - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// - -var deletedIds = []; - -var slice = deletedIds.slice; - -var concat = deletedIds.concat; - -var push = deletedIds.push; - -var indexOf = deletedIds.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - version = "1.11.3", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1, IE<9 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: deletedIds.sort, - splice: deletedIds.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var src, copyIsArray, copy, name, options, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - isWindow: function( obj ) { - /* jshint eqeqeq: false */ - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - // adding 1 corrects loss of precision from parseFloat (#15100) - return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - isPlainObject: function( obj ) { - var key; - - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( support.ownLast ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && jQuery.trim( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Support: Android<4.1, IE<9 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - var len; - - if ( arr ) { - if ( indexOf ) { - return indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - while ( j < len ) { - first[ i++ ] = second[ j++ ]; - } - - // Support: IE<9 - // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) - if ( len !== len ) { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var args, proxy, tmp; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: function() { - return +( new Date() ); - }, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - - // Support: iOS 8.2 (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = "length" in obj && obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.2.0-pre - * http://sizzlejs.com/ - * - * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-12-16 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // http://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + characterEncoding + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - nodeType = context.nodeType; - - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - if ( !seed && documentIsHTML ) { - - // Try to shortcut find operations when possible (e.g., not under DocumentFragment) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType !== 1 && selector; - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, parent, - doc = node ? node.ownerDocument || node : preferredDoc; - - // If no document and documentElement is available, return - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Set our document - document = doc; - docElem = doc.documentElement; - parent = doc.defaultView; - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer - if ( parent.addEventListener ) { - parent.addEventListener( "unload", unloadHandler, false ); - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", unloadHandler ); - } - } - - /* Support tests - ---------------------------------------------------------------------- */ - documentIsHTML = !isXML( doc ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - docElem.appendChild( div ).innerHTML = "
" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowcapture^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ - if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibing-combinator selector` fails - if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully does not implement inclusive descendent - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch (e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) - } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context !== document && context; - } - - // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // Apply set filters to unmatched elements - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is no seed and only one group - if ( match.length === 1 ) { - - // Take a shortcut and set the context if the root selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; - }); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); -}; - -jQuery.fn.extend({ - find: function( selector ) { - var i, - ret = [], - self = this, - len = self.length; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -}); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -jQuery.fn.extend({ - has: function( target ) { - var i, - targets = jQuery( target, this ), - len = targets.length; - - return this.filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.unique( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - do { - cur = cur[ dir ]; - } while ( cur && cur.nodeType !== 1 ); - - return cur; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - ret = jQuery.unique( ret ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - } - - return this.pushStack( ret ); - }; -}); -var rnotwhite = (/\S+/g); - - - -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // First callback to fire (used internally by add and fireWith) - firingStart, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - - } else if ( !(--remaining) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend({ - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -}); - -/** - * Clean-up method for dom ready events - */ -function detach() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - - } else { - document.detachEvent( "onreadystatechange", completed ); - window.detachEvent( "onload", completed ); - } -} - -/** - * The ready event handler and self cleanup method - */ -function completed() { - // readyState === "complete" is good enough for us to call the dom ready in oldIE - if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { - detach(); - jQuery.ready(); - } -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - // Standards-based browsers support DOMContentLoaded - } else if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - - // If IE event model is used - } else { - // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", completed ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", completed ); - - // If IE and not a frame - // continually check to see if the document is ready - var top = false; - - try { - top = window.frameElement == null && document.documentElement; - } catch(e) {} - - if ( top && top.doScroll ) { - (function doScrollCheck() { - if ( !jQuery.isReady ) { - - try { - // Use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - top.doScroll("left"); - } catch(e) { - return setTimeout( doScrollCheck, 50 ); - } - - // detach all dom ready events - detach(); - - // and execute any waiting functions - jQuery.ready(); - } - })(); - } - } - } - return readyList.promise( obj ); -}; - - -var strundefined = typeof undefined; - - - -// Support: IE<9 -// Iteration over object's inherited properties before its own -var i; -for ( i in jQuery( support ) ) { - break; -} -support.ownLast = i !== "0"; - -// Note: most support tests are defined in their respective modules. -// false until the test is run -support.inlineBlockNeedsLayout = false; - -// Execute ASAP in case we need to set body.style.zoom -jQuery(function() { - // Minified: var a,b,c,d - var val, div, body, container; - - body = document.getElementsByTagName( "body" )[ 0 ]; - if ( !body || !body.style ) { - // Return for frameset docs that don't have a body - return; - } - - // Setup - div = document.createElement( "div" ); - container = document.createElement( "div" ); - container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; - body.appendChild( container ).appendChild( div ); - - if ( typeof div.style.zoom !== strundefined ) { - // Support: IE<8 - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; - - support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; - if ( val ) { - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - // Support: IE<8 - body.style.zoom = 1; - } - } - - body.removeChild( container ); -}); - - - - -(function() { - var div = document.createElement( "div" ); - - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - } - - // Null elements to avoid leaks in IE. - div = null; -})(); - - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( elem ) { - var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], - nodeType = +elem.nodeType || 1; - - // Do not set data on non-element DOM nodes because it will not be cleared (#8335). - return nodeType !== 1 && nodeType !== 9 ? - false : - - // Nodes accept data unless otherwise specified; rejection can be conditional - !noData || noData !== true && elem.getAttribute("classid") === noData; -}; - - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - var name; - for ( name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - -function internalData( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var ret, thisCache, - internalKey = jQuery.expando, - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - // Avoid exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( typeof name === "string" ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; -} - -function internalRemoveData( elem, name, pvt ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split(" "); - } - } - } else { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = name.concat( jQuery.map( name, jQuery.camelCase ) ); - } - - i = name.length; - while ( i-- ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject( cache[ id ] ) ) { - return; - } - } - - // Destroy the cache - if ( isNode ) { - jQuery.cleanData( [ elem ], true ); - - // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) - /* jshint eqeqeq: false */ - } else if ( support.deleteExpando || cache != cache.window ) { - /* jshint eqeqeq: true */ - delete cache[ id ]; - - // When all else fails, null - } else { - cache[ id ] = null; - } -} - -jQuery.extend({ - cache: {}, - - // The following elements (space-suffixed to avoid Object.prototype collisions) - // throw uncatchable exceptions if you attempt to set expando properties - noData: { - "applet ": true, - "embed ": true, - // ...but Flash objects (which have this classid) *can* handle expandos - "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data ) { - return internalData( elem, name, data ); - }, - - removeData: function( elem, name ) { - return internalRemoveData( elem, name ); - }, - - // For internal use only. - _data: function( elem, name, data ) { - return internalData( elem, name, data, true ); - }, - - _removeData: function( elem, name ) { - return internalRemoveData( elem, name, true ); - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var i, name, data, - elem = this[0], - attrs = elem && elem.attributes; - - // Special expections of .data basically thwart jQuery.access, - // so implement the relevant behavior ourselves - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - return arguments.length > 1 ? - - // Sets one value - this.each(function() { - jQuery.data( this, key, value ); - }) : - - // Gets one value - // Try to fetch any internally stored data first - elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - - -jQuery.extend({ - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray(data) ) { - queue = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return jQuery._data( elem, key ) || jQuery._data( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - jQuery._removeData( elem, type + "queue" ); - jQuery._removeData( elem, key ); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = jQuery._data( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHidden = function( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); - }; - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - length = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < length; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; -}; -var rcheckableType = (/^(?:checkbox|radio)$/i); - - - -(function() { - // Minified: var a,b,c - var input = document.createElement( "input" ), - div = document.createElement( "div" ), - fragment = document.createDocumentFragment(); - - // Setup - div.innerHTML = "
a"; - - // IE strips leading whitespace when .innerHTML is used - support.leadingWhitespace = div.firstChild.nodeType === 3; - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - support.tbody = !div.getElementsByTagName( "tbody" ).length; - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - support.html5Clone = - document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - input.type = "checkbox"; - input.checked = true; - fragment.appendChild( input ); - support.appendChecked = input.checked; - - // Make sure textarea (and checkbox) defaultValue is properly cloned - // Support: IE6-IE11+ - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // #11217 - WebKit loses check when the name is after the checked attribute - fragment.appendChild( div ); - div.innerHTML = ""; - - // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 - // old WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<9 - // Opera does not clone events (and typeof div.attachEvent === undefined). - // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() - support.noCloneEvent = true; - if ( div.attachEvent ) { - div.attachEvent( "onclick", function() { - support.noCloneEvent = false; - }); - - div.cloneNode( true ).click(); - } - - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - } -})(); - - -(function() { - var i, eventName, - div = document.createElement( "div" ); - - // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) - for ( i in { submit: true, change: true, focusin: true }) { - eventName = "on" + i; - - if ( !(support[ i + "Bubbles" ] = eventName in window) ) { - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) - div.setAttribute( eventName, "t" ); - support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; - } - } - - // Null elements to avoid leaks in IE. - div = null; -})(); - - -var rformElems = /^(?:input|select|textarea)$/i, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - var tmp, events, t, handleObjIn, - special, eventHandle, handleObj, - handlers, type, namespaces, origType, - elemData = jQuery._data( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - var j, handleObj, tmp, - origCount, t, events, - special, handlers, type, - namespaces, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery._removeData( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - var handle, ontype, cur, - bubbleType, special, tmp, i, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - try { - elem[ type ](); - } catch ( e ) { - // IE<9 dies on focus/blur to hidden element (#1486,#12518) - // only reproducible on winXP IE8 native, not IE9 in IE8 mode - } - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, ret, handleObj, matched, j, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var sel, handleObj, matches, i, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - /* jshint eqeqeq: false */ - for ( ; cur != this; cur = cur.parentNode || this ) { - /* jshint eqeqeq: true */ - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: IE<9 - // Fix target property (#1925) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Support: Chrome 23+, Safari? - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Support: IE<9 - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) - event.metaKey = !!event.metaKey; - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var body, eventDoc, doc, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - try { - this.focus(); - return false; - } catch ( e ) { - // Support: IE<9 - // If we error on focus to hidden element (#1486, #12518), - // let .trigger() run the handlers - } - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - var name = "on" + type; - - if ( elem.detachEvent ) { - - // #8545, #7054, preventing memory leaks for custom events in IE6-8 - // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === strundefined ) { - elem[ name ] = null; - } - - elem.detachEvent( name, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - // Support: IE < 9, Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - if ( !e ) { - return; - } - - // If preventDefault exists, run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // Support: IE - // Otherwise set the returnValue property of the original event to false - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - if ( !e ) { - return; - } - // If stopPropagation exists, run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - - // Support: IE - // Set the cancelBubble property of the original event to true - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !jQuery._data( form, "submitBubbles" ) ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submit_bubble = true; - }); - jQuery._data( form, "submitBubbles", true ); - } - }); - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( event._submit_bubble ) { - delete event._submit_bubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - } - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - } - // Allow triggered, simulated change events (#11500) - jQuery.event.simulate( "change", this, event, true ); - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - jQuery._data( elem, "changeBubbles", true ); - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return !rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - jQuery._removeData( doc, fix ); - } else { - jQuery._data( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var type, origFn; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, - rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rtbody = /\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - option: [ 1, "" ], - legend: [ 1, "