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