Subversion Repositories Applications.gtt

Rev

Rev 187 | Details | Compare with Previous | Last modification | View Log | RSS feed

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