annotate vendor/pear/pear-core-minimal/src/OS/Guess.php @ 19:fa3358dc1485 tip

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