code cleaning
[phpsysinfo.git] / read_config.php
1 <?php
2 if (!defined('PSI_CONFIG_FILE')) {
3     /**
4      * phpSysInfo version
5      */
6     define('PSI_VERSION', '3.3.x');
7     /**
8      * phpSysInfo configuration
9      */
10     define('PSI_CONFIG_FILE', PSI_APP_ROOT.'/phpsysinfo.ini');
11
12     define('ARRAY_EXP', '/^return array \([^;]*\);$/'); //array expression search
13
14     if (!is_readable(PSI_CONFIG_FILE) || !($config = @parse_ini_file(PSI_CONFIG_FILE, true))) {
15         echo "ERROR: phpsysinfo.ini does not exist or is not readable by the webserver in the phpsysinfo directory";
16         die();
17     } else {
18         foreach ($config as $name=>$group) {
19             if (strtoupper($name)=="MAIN") {
20                 $name_prefix='PSI_';
21             } elseif (strtoupper(substr($name, 0, 7))=="SENSOR_") {
22                 $name_prefix='PSI_'.strtoupper($name).'_';
23             } else {
24                 $name_prefix='PSI_PLUGIN_'.strtoupper($name).'_';
25             }
26             foreach ($group as $param=>$value) {
27                 if ((trim($value)==="") || (trim($value)==="0")) {
28                     define($name_prefix.strtoupper($param), false);
29                 } elseif (trim($value)==="1") {
30                     define($name_prefix.strtoupper($param), true);
31                 } else {
32                     if (strstr($value, ',')) {
33                         define($name_prefix.strtoupper($param), 'return '.var_export(preg_split('/\s*,\s*/', trim($value), -1, PREG_SPLIT_NO_EMPTY), 1).';');
34                     } else {
35                         define($name_prefix.strtoupper($param), trim($value));
36                     }
37                 }
38             }
39         }
40     }
41
42     if (defined('PSI_ALLOWED') && is_string(PSI_ALLOWED)) {
43         if (preg_match(ARRAY_EXP, PSI_ALLOWED)) {
44             $allowed = eval(strtolower(PSI_ALLOWED));
45         } else {
46             $allowed = array(strtolower(PSI_ALLOWED));
47         }
48
49         if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
50             $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
51         } else {
52             if (isset($_SERVER["HTTP_CLIENT_IP"])) {
53                 $ip = $_SERVER["HTTP_CLIENT_IP"];
54             } else {
55                 $ip = $_SERVER["REMOTE_ADDR"];
56             }
57         }
58         $ip = preg_replace("/^::ffff:/", "", strtolower($ip));
59
60         if (!in_array($ip, $allowed, true)) {
61             echo "Client IP address not allowed";
62             die();
63         }
64     }
65
66     /* default error handler */
67     if (function_exists('errorHandlerPsi')) {
68         restore_error_handler();
69     }
70
71     /* fatal errors only */
72     $old_err_rep = error_reporting();
73     error_reporting(E_ERROR);
74
75     /* get git revision */
76     if (file_exists(PSI_APP_ROOT.'/.git/HEAD')) {
77         $contents = @file_get_contents(PSI_APP_ROOT.'/.git/HEAD');
78         if ($contents && preg_match("/^ref:\s+(.*)\/([^\/\s]*)/m", $contents, $matches)) {
79             $contents = @file_get_contents(PSI_APP_ROOT.'/.git/'.$matches[1]."/".$matches[2]);
80             if ($contents && preg_match("/^([^\s]*)/m", $contents, $revision)) {
81                 define('PSI_VERSION_STRING', PSI_VERSION ."-".$matches[2]."-".substr($revision[1], 0, 7));
82             } else {
83                 define('PSI_VERSION_STRING', PSI_VERSION ."-".$matches[2]);
84             }
85         }
86     }
87     /* get svn revision */
88     if (!defined('PSI_VERSION_STRING') && file_exists(PSI_APP_ROOT.'/.svn/entries')) {
89         $contents = @file_get_contents(PSI_APP_ROOT.'/.svn/entries');
90         if ($contents && preg_match("/dir\n(.+)/", $contents, $matches)) {
91             define('PSI_VERSION_STRING', PSI_VERSION."-r".$matches[1]);
92         } else {
93             define('PSI_VERSION_STRING', PSI_VERSION);
94         }
95     }
96     if (!defined('PSI_VERSION_STRING')) {
97         define('PSI_VERSION_STRING', PSI_VERSION);
98     }
99
100     if (!defined('PSI_OS')) { //if not overloaded in phpsysinfo.ini
101         /* get Linux code page */
102         if (PHP_OS == 'Linux') {
103             if (file_exists($fname = '/etc/sysconfig/i18n')
104                || file_exists($fname = '/etc/default/locale')
105                || file_exists($fname = '/etc/locale.conf')
106                || file_exists($fname = '/etc/sysconfig/language')
107                || file_exists($fname = '/etc/profile.d/lang.sh')
108                || file_exists($fname = '/etc/profile')) {
109                 $contents = @file_get_contents($fname);
110             } else {
111                 $contents = false;
112                 if (file_exists('/system/build.prop')) { //Android
113                     define('PSI_OS', 'Android');
114                     if (@exec('uname -o 2>/dev/null', $unameo) && (sizeof($unameo)>0) && (($unameo0 = trim($unameo[0])) != "")) {
115                         define('PSI_UNAMEO', $unameo0);
116                     }
117                     if (!defined('PSI_MODE_POPEN')) { //if not overloaded in phpsysinfo.ini
118                         if (!function_exists("proc_open")) { //proc_open function test by executing 'pwd' command
119                             define('PSI_MODE_POPEN', true); //use popen() function - no stderr error handling (but with problems with timeout)
120                         } else {
121                             $out = '';
122                             $err = '';
123                             $pipes = array();
124                             $descriptorspec = array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w"));
125                             $process = proc_open("pwd 2>/dev/null ", $descriptorspec, $pipes);
126                             if (!is_resource($process)) {
127                                 define('PSI_MODE_POPEN', true);
128                             } else {
129                                 $w = null;
130                                 $e = null;
131
132                                 while (!(feof($pipes[1]) && feof($pipes[2]))) {
133                                     $read = array($pipes[1], $pipes[2]);
134
135                                     $n = stream_select($read, $w, $e, 5);
136
137                                     if (($n === false) || ($n === 0)) {
138                                         break;
139                                     }
140
141                                     foreach ($read as $r) {
142                                         if ($r == $pipes[1]) {
143                                             $out .= fread($r, 4096);
144                                         } elseif (feof($pipes[1]) && ($r == $pipes[2])) {//read STDERR after STDOUT
145                                             $err .= fread($r, 4096);
146                                         }
147                                     }
148                                 }
149
150                                 if (is_null($out) || (trim($out) == "") || (substr(trim($out), 0, 1) != "/")) {
151                                     define('PSI_MODE_POPEN', true);
152                                 }
153                                 fclose($pipes[0]);
154                                 fclose($pipes[1]);
155                                 fclose($pipes[2]);
156                                 // It is important that you close any pipes before calling
157                                 // proc_close in order to avoid a deadlock
158                                 proc_close($process);
159                             }
160                         }
161                     }
162                 }
163             }
164             if (!(defined('PSI_SYSTEM_CODEPAGE') && defined('PSI_SYSTEM_LANG')) //also if both not overloaded in phpsysinfo.ini
165                && $contents && (preg_match('/^(LANG="?[^"\n]*"?)/m', $contents, $matches)
166                || preg_match('/^RC_(LANG="?[^"\n]*"?)/m', $contents, $matches)
167                || preg_match('/^\s*export (LANG="?[^"\n]*"?)/m', $contents, $matches))) {
168                 if (!defined('PSI_SYSTEM_CODEPAGE')) {
169                     if (file_exists($vtfname = '/sys/module/vt/parameters/default_utf8')
170                        && (trim(@file_get_contents($vtfname)) === "1")) {
171                             define('PSI_SYSTEM_CODEPAGE', 'UTF-8');
172                     } elseif (@exec($matches[1].' locale -k LC_CTYPE 2>/dev/null', $lines)) { //if not overloaded in phpsysinfo.ini
173                         foreach ($lines as $line) {
174                             if (preg_match('/^charmap="?([^"]*)/', $line, $matches2)) {
175                                 define('PSI_SYSTEM_CODEPAGE', $matches2[1]);
176                                 break;
177                             }
178                         }
179                     }
180                 }
181                 if (!defined('PSI_SYSTEM_LANG') && @exec($matches[1].' locale 2>/dev/null', $lines2)) { //also if not overloaded in phpsysinfo.ini
182                     foreach ($lines2 as $line) {
183                         if (preg_match('/^LC_MESSAGES="?([^\."@]*)/', $line, $matches2)) {
184                             $lang = "";
185                             if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) {
186                                 if (isset($langdata['Linux']['_'.$matches2[1]])) {
187                                     $lang = $langdata['Linux']['_'.$matches2[1]];
188                                 }
189                             }
190                             if ($lang == "") {
191                                 $lang = 'Unknown';
192                             }
193                             define('PSI_SYSTEM_LANG', $lang.' ('.$matches2[1].')');
194                             break;
195                         }
196                     }
197                 }
198             }
199         } elseif (PHP_OS == 'Haiku') {
200             if (!(defined('PSI_SYSTEM_CODEPAGE') && defined('PSI_SYSTEM_LANG')) //also if both not overloaded in phpsysinfo.ini
201                 && @exec('locale -m 2>/dev/null', $lines)) {
202                 foreach ($lines as $line) {
203                     if (preg_match('/^"?([^\."]*)\.?([^"]*)/', $line, $matches2)) {
204
205                         if (!defined('PSI_SYSTEM_CODEPAGE') && isset($matches2[2]) && !is_null($matches2[2]) && (trim($matches2[2]) != "")) { //also if not overloaded in phpsysinfo.ini
206                             define('PSI_SYSTEM_CODEPAGE', $matches2[2]);
207                         }
208
209                         if (!defined('PSI_SYSTEM_LANG')) { //if not overloaded in phpsysinfo.ini
210                             $lang = "";
211                             if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) {
212                                 if (isset($langdata['Linux']['_'.$matches2[1]])) {
213                                     $lang = $langdata['Linux']['_'.$matches2[1]];
214                                 }
215                             }
216                             if ($lang == "") {
217                                 $lang = 'Unknown';
218                             }
219                             define('PSI_SYSTEM_LANG', $lang.' ('.$matches2[1].')');
220                         }
221                         break;
222                     }
223                 }
224             }
225         } elseif (PHP_OS == 'Darwin') {
226             if (!defined('PSI_SYSTEM_LANG') //if not overloaded in phpsysinfo.ini
227                 && @exec('defaults read /Library/Preferences/.GlobalPreferences AppleLocale 2>/dev/null', $lines)) {
228                 $lang = "";
229                 if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) {
230                     if (isset($langdata['Linux']['_'.$lines[0]])) {
231                         $lang = $langdata['Linux']['_'.$lines[0]];
232                     }
233                 }
234                 if ($lang == "") {
235                     $lang = 'Unknown';
236                 }
237                 define('PSI_SYSTEM_LANG', $lang.' ('.$lines[0].')');
238             }
239         }
240     }
241
242     /* executeProgram() timeout value in seconds */
243     if (defined('PSI_EXEC_TIMEOUT')) {
244         define('PSI_EXEC_TIMEOUT_INT', max(intval(PSI_EXEC_TIMEOUT), 1));
245     } else {
246         define('PSI_EXEC_TIMEOUT_INT', 30);
247     }
248
249     /* snmprealwalk() and executeProgram("snmpwalk") number of seconds until the first timeout */
250     if (defined('PSI_SNMP_TIMEOUT')) {
251         define('PSI_SNMP_TIMEOUT_INT', max(intval(PSI_SNMP_TIMEOUT), 1));
252     } else {
253         define('PSI_SNMP_TIMEOUT_INT', 3);
254     }
255
256     /* snmprealwalk() and executeProgram("snmpwalk") number of times to retry if timeouts occur */
257     if (defined('PSI_SNMP_RETRY')) {
258         define('PSI_SNMP_RETRY_INT', max(intval(PSI_SNMP_RETRY), 0));
259     } else {
260         define('PSI_SNMP_RETRY_INT', 0);
261     }
262
263     if (!defined('PSI_OS')) {
264         define('PSI_OS', PHP_OS);
265     }
266
267     if (!defined('PSI_SYSTEM_LANG')) {
268         define('PSI_SYSTEM_LANG', null);
269     }
270     if (!defined('PSI_SYSTEM_CODEPAGE')) { //if not overloaded in phpsysinfo.ini
271         if ((PSI_OS=='Android') || (PSI_OS=='Darwin')) {
272             define('PSI_SYSTEM_CODEPAGE', 'UTF-8');
273         } elseif (PSI_OS=='Minix') {
274             define('PSI_SYSTEM_CODEPAGE', 'CP437');
275         } else {
276             define('PSI_SYSTEM_CODEPAGE', null);
277         }
278     }
279
280     if (!defined('PSI_JSON_ISSUE')) { //if not overloaded in phpsysinfo.ini
281         if (!extension_loaded("xml")) {
282             die("phpSysInfo requires the xml extension to php in order to work properly.");
283         }
284         if (simplexml_load_string("<A><B><C/></B>\n</A>") !== simplexml_load_string("<A><B><C/></B></A>")) { // json_encode issue test
285             define('PSI_JSON_ISSUE', true); // Problem must be solved
286         }
287     }
288
289     /* restore error level */
290     error_reporting($old_err_rep);
291
292     /* restore error handler */
293     if (function_exists('errorHandlerPsi')) {
294         set_error_handler('errorHandlerPsi');
295     }
296 }