Редакция 69 | Содержимое файла | Сравнить с предыдущей | Последнее изменение | Открыть журнал | RSS
Редакция | Автор | № строки | Строка |
---|---|---|---|
69 | alex-w | 1 | <?php |
2 | /** |
||
3 | * The OS_Guess class |
||
4 | * |
||
5 | * PHP versions 4 and 5 |
||
6 | * |
||
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license |
||
8 | * that is available through the world-wide-web at the following URI: |
||
9 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of |
||
10 | * the PHP License and are unable to obtain it through the web, please |
||
11 | * send a note to license@php.net so we can mail you a copy immediately. |
||
12 | * |
||
13 | * @category pear |
||
14 | * @package PEAR |
||
15 | * @author Stig Bakken <ssb@php.net> |
||
16 | * @author Gregory Beaver <cellog@php.net> |
||
17 | * @copyright 1997-2008 The PHP Group |
||
18 | * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||
19 | * @version CVS: $Id: Guess.php,v 1.26 2008/01/03 20:26:34 cellog Exp $ |
||
20 | * @link http://pear.php.net/package/PEAR |
||
21 | * @since File available since PEAR 0.1 |
||
22 | */ |
||
23 | |||
24 | // {{{ uname examples |
||
25 | |||
26 | // php_uname() without args returns the same as 'uname -a', or a PHP-custom |
||
27 | // string for Windows. |
||
28 | // PHP versions prior to 4.3 return the uname of the host where PHP was built, |
||
29 | // as of 4.3 it returns the uname of the host running the PHP code. |
||
30 | // |
||
31 | // PC RedHat Linux 7.1: |
||
32 | // Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown |
||
33 | // |
||
34 | // PC Debian Potato: |
||
35 | // Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown |
||
36 | // |
||
37 | // PC FreeBSD 3.3: |
||
38 | // FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386 |
||
39 | // |
||
40 | // PC FreeBSD 4.3: |
||
41 | // FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386 |
||
42 | // |
||
43 | // PC FreeBSD 4.5: |
||
44 | // FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386 |
||
45 | // |
||
46 | // PC FreeBSD 4.5 w/uname from GNU shellutils: |
||
47 | // FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown |
||
48 | // |
||
49 | // HP 9000/712 HP-UX 10: |
||
50 | // HP-UX iq B.10.10 A 9000/712 2008429113 two-user license |
||
51 | // |
||
52 | // HP 9000/712 HP-UX 10 w/uname from GNU shellutils: |
||
53 | // HP-UX host B.10.10 A 9000/712 unknown |
||
54 | // |
||
55 | // IBM RS6000/550 AIX 4.3: |
||
56 | // AIX host 3 4 000003531C00 |
||
57 | // |
||
58 | // AIX 4.3 w/uname from GNU shellutils: |
||
59 | // AIX host 3 4 000003531C00 unknown |
||
60 | // |
||
61 | // SGI Onyx IRIX 6.5 w/uname from GNU shellutils: |
||
62 | // IRIX64 host 6.5 01091820 IP19 mips |
||
63 | // |
||
64 | // SGI Onyx IRIX 6.5: |
||
65 | // IRIX64 host 6.5 01091820 IP19 |
||
66 | // |
||
67 | // SparcStation 20 Solaris 8 w/uname from GNU shellutils: |
||
68 | // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc |
||
69 | // |
||
70 | // SparcStation 20 Solaris 8: |
||
71 | // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 |
||
72 | // |
||
73 | // Mac OS X (Darwin) |
||
74 | // Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh |
||
75 | // |
||
76 | // Mac OS X early versions |
||
77 | // |
||
78 | |||
79 | // }}} |
||
80 | |||
81 | /* TODO: |
||
82 | * - define endianness, to allow matchSignature("bigend") etc. |
||
83 | */ |
||
84 | |||
85 | /** |
||
86 | * Retrieves information about the current operating system |
||
87 | * |
||
88 | * This class uses php_uname() to grok information about the current OS |
||
89 | * |
||
90 | * @category pear |
||
91 | * @package PEAR |
||
92 | * @author Stig Bakken <ssb@php.net> |
||
93 | * @author Gregory Beaver <cellog@php.net> |
||
94 | * @copyright 1997-2008 The PHP Group |
||
95 | * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||
96 | * @version Release: 1.7.2 |
||
97 | * @link http://pear.php.net/package/PEAR |
||
98 | * @since Class available since Release 0.1 |
||
99 | */ |
||
100 | class OS_Guess |
||
101 | { |
||
102 | var $sysname; |
||
103 | var $nodename; |
||
104 | var $cpu; |
||
105 | var $release; |
||
106 | var $extra; |
||
107 | |||
108 | function OS_Guess($uname = null) |
||
109 | { |
||
110 | list($this->sysname, |
||
111 | $this->release, |
||
112 | $this->cpu, |
||
113 | $this->extra, |
||
114 | $this->nodename) = $this->parseSignature($uname); |
||
115 | } |
||
116 | |||
117 | function parseSignature($uname = null) |
||
118 | { |
||
119 | static $sysmap = array( |
||
120 | 'HP-UX' => 'hpux', |
||
121 | 'IRIX64' => 'irix', |
||
122 | ); |
||
123 | static $cpumap = array( |
||
124 | 'i586' => 'i386', |
||
125 | 'i686' => 'i386', |
||
126 | 'ppc' => 'powerpc', |
||
127 | ); |
||
128 | if ($uname === null) { |
||
129 | $uname = php_uname(); |
||
130 | } |
||
131 | $parts = split('[[:space:]]+', trim($uname)); |
||
132 | $n = count($parts); |
||
133 | |||
134 | $release = $machine = $cpu = ''; |
||
135 | $sysname = $parts[0]; |
||
136 | $nodename = $parts[1]; |
||
137 | $cpu = $parts[$n-1]; |
||
138 | $extra = ''; |
||
139 | if ($cpu == 'unknown') { |
||
140 | $cpu = $parts[$n-2]; |
||
141 | } |
||
142 | |||
143 | switch ($sysname) { |
||
144 | case 'AIX' : |
||
145 | $release = "$parts[3].$parts[2]"; |
||
146 | break; |
||
147 | case 'Windows' : |
||
148 | switch ($parts[1]) { |
||
149 | case '95/98': |
||
150 | $release = '9x'; |
||
151 | break; |
||
152 | default: |
||
153 | $release = $parts[1]; |
||
154 | break; |
||
155 | } |
||
156 | $cpu = 'i386'; |
||
157 | break; |
||
158 | case 'Linux' : |
||
159 | $extra = $this->_detectGlibcVersion(); |
||
160 | // use only the first two digits from the kernel version |
||
161 | $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]); |
||
162 | break; |
||
163 | case 'Mac' : |
||
164 | $sysname = 'darwin'; |
||
165 | $nodename = $parts[2]; |
||
166 | $release = $parts[3]; |
||
167 | if ($cpu == 'Macintosh') { |
||
168 | if ($parts[$n - 2] == 'Power') { |
||
169 | $cpu = 'powerpc'; |
||
170 | } |
||
171 | } |
||
172 | break; |
||
173 | case 'Darwin' : |
||
174 | if ($cpu == 'Macintosh') { |
||
175 | if ($parts[$n - 2] == 'Power') { |
||
176 | $cpu = 'powerpc'; |
||
177 | } |
||
178 | } |
||
179 | $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]); |
||
180 | break; |
||
181 | default: |
||
182 | $release = ereg_replace('-.*', '', $parts[2]); |
||
183 | break; |
||
184 | } |
||
185 | |||
186 | |||
187 | if (isset($sysmap[$sysname])) { |
||
188 | $sysname = $sysmap[$sysname]; |
||
189 | } else { |
||
190 | $sysname = strtolower($sysname); |
||
191 | } |
||
192 | if (isset($cpumap[$cpu])) { |
||
193 | $cpu = $cpumap[$cpu]; |
||
194 | } |
||
195 | return array($sysname, $release, $cpu, $extra, $nodename); |
||
196 | } |
||
197 | |||
198 | function _detectGlibcVersion() |
||
199 | { |
||
200 | static $glibc = false; |
||
201 | if ($glibc !== false) { |
||
202 | return $glibc; // no need to run this multiple times |
||
203 | } |
||
204 | $major = $minor = 0; |
||
205 | include_once "System.php"; |
||
206 | // Use glibc's <features.h> header file to |
||
207 | // get major and minor version number: |
||
208 | if (@file_exists('/usr/include/features.h') && |
||
209 | @is_readable('/usr/include/features.h')) { |
||
210 | if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { |
||
211 | $features_file = fopen('/usr/include/features.h', 'rb'); |
||
212 | while (!feof($features_file)) { |
||
213 | $line = fgets($features_file, 8192); |
||
214 | if (!$line || (strpos($line, '#define') === false)) { |
||
215 | continue; |
||
216 | } |
||
217 | if (strpos($line, '__GLIBC__')) { |
||
218 | // major version number #define __GLIBC__ version |
||
219 | $line = preg_split('/\s+/', $line); |
||
220 | $glibc_major = trim($line[2]); |
||
221 | if (isset($glibc_minor)) { |
||
222 | break; |
||
223 | } |
||
224 | continue; |
||
225 | } |
||
226 | if (strpos($line, '__GLIBC_MINOR__')) { |
||
227 | // got the minor version number |
||
228 | // #define __GLIBC_MINOR__ version |
||
229 | $line = preg_split('/\s+/', $line); |
||
230 | $glibc_minor = trim($line[2]); |
||
231 | if (isset($glibc_major)) { |
||
232 | break; |
||
233 | } |
||
234 | continue; |
||
235 | } |
||
236 | } |
||
237 | fclose($features_file); |
||
238 | if (!isset($glibc_major) || !isset($glibc_minor)) { |
||
239 | return $glibc = ''; |
||
240 | } |
||
241 | return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ; |
||
242 | } // no cpp |
||
243 | $tmpfile = System::mktemp("glibctest"); |
||
244 | $fp = fopen($tmpfile, "w"); |
||
245 | fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n"); |
||
246 | fclose($fp); |
||
247 | $cpp = popen("/usr/bin/cpp $tmpfile", "r"); |
||
248 | while ($line = fgets($cpp, 1024)) { |
||
249 | if ($line{0} == '#' || trim($line) == '') { |
||
250 | continue; |
||
251 | } |
||
252 | if (list($major, $minor) = explode(' ', trim($line))) { |
||
253 | break; |
||
254 | } |
||
255 | } |
||
256 | pclose($cpp); |
||
257 | unlink($tmpfile); |
||
258 | } // features.h |
||
259 | if (!($major && $minor) && @is_link('/lib/libc.so.6')) { |
||
260 | // Let's try reading the libc.so.6 symlink |
||
261 | if (ereg('^libc-(.*)\.so$', basename(readlink('/lib/libc.so.6')), $matches)) { |
||
262 | list($major, $minor) = explode('.', $matches[1]); |
||
263 | } |
||
264 | } |
||
265 | if (!($major && $minor)) { |
||
266 | return $glibc = ''; |
||
267 | } |
||
268 | return $glibc = "glibc{$major}.{$minor}"; |
||
269 | } |
||
270 | |||
271 | function getSignature() |
||
272 | { |
||
273 | if (empty($this->extra)) { |
||
274 | return "{$this->sysname}-{$this->release}-{$this->cpu}"; |
||
275 | } |
||
276 | return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}"; |
||
277 | } |
||
278 | |||
279 | function getSysname() |
||
280 | { |
||
281 | return $this->sysname; |
||
282 | } |
||
283 | |||
284 | function getNodename() |
||
285 | { |
||
286 | return $this->nodename; |
||
287 | } |
||
288 | |||
289 | function getCpu() |
||
290 | { |
||
291 | return $this->cpu; |
||
292 | } |
||
293 | |||
294 | function getRelease() |
||
295 | { |
||
296 | return $this->release; |
||
297 | } |
||
298 | |||
299 | function getExtra() |
||
300 | { |
||
301 | return $this->extra; |
||
302 | } |
||
303 | |||
304 | function matchSignature($match) |
||
305 | { |
||
306 | if (is_array($match)) { |
||
307 | $fragments = $match; |
||
308 | } else { |
||
309 | $fragments = explode('-', $match); |
||
310 | } |
||
311 | $n = count($fragments); |
||
312 | $matches = 0; |
||
313 | if ($n > 0) { |
||
314 | $matches += $this->_matchFragment($fragments[0], $this->sysname); |
||
315 | } |
||
316 | if ($n > 1) { |
||
317 | $matches += $this->_matchFragment($fragments[1], $this->release); |
||
318 | } |
||
319 | if ($n > 2) { |
||
320 | $matches += $this->_matchFragment($fragments[2], $this->cpu); |
||
321 | } |
||
322 | if ($n > 3) { |
||
323 | $matches += $this->_matchFragment($fragments[3], $this->extra); |
||
324 | } |
||
325 | return ($matches == $n); |
||
326 | } |
||
327 | |||
328 | function _matchFragment($fragment, $value) |
||
329 | { |
||
330 | if (strcspn($fragment, '*?') < strlen($fragment)) { |
||
331 | $reg = '^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$'; |
||
332 | return eregi($reg, $value); |
||
333 | } |
||
334 | return ($fragment == '*' || !strcasecmp($fragment, $value)); |
||
335 | } |
||
336 | |||
337 | } |
||
338 | /* |
||
339 | * Local Variables: |
||
340 | * indent-tabs-mode: nil |
||
341 | * c-basic-offset: 4 |
||
342 | * End: |
||
343 | */ |
||
344 | ?> |