You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.9 KiB

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 5 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available through the world-wide-web at the following url: |
  11. // | http://www.php.net/license/3_0.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stig Bakken <ssb@php.net> |
  17. // | |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Guess.php,v 1.13.4.1 2004/10/19 04:15:56 cellog Exp $
  21. // {{{ uname examples
  22. // php_uname() without args returns the same as 'uname -a', or a PHP-custom
  23. // string for Windows.
  24. // PHP versions prior to 4.3 return the uname of the host where PHP was built,
  25. // as of 4.3 it returns the uname of the host running the PHP code.
  26. //
  27. // PC RedHat Linux 7.1:
  28. // Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
  29. //
  30. // PC Debian Potato:
  31. // Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
  32. //
  33. // PC FreeBSD 3.3:
  34. // 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
  35. //
  36. // PC FreeBSD 4.3:
  37. // 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
  38. //
  39. // PC FreeBSD 4.5:
  40. // 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
  41. //
  42. // PC FreeBSD 4.5 w/uname from GNU shellutils:
  43. // FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
  44. //
  45. // HP 9000/712 HP-UX 10:
  46. // HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
  47. //
  48. // HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
  49. // HP-UX host B.10.10 A 9000/712 unknown
  50. //
  51. // IBM RS6000/550 AIX 4.3:
  52. // AIX host 3 4 000003531C00
  53. //
  54. // AIX 4.3 w/uname from GNU shellutils:
  55. // AIX host 3 4 000003531C00 unknown
  56. //
  57. // SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
  58. // IRIX64 host 6.5 01091820 IP19 mips
  59. //
  60. // SGI Onyx IRIX 6.5:
  61. // IRIX64 host 6.5 01091820 IP19
  62. //
  63. // SparcStation 20 Solaris 8 w/uname from GNU shellutils:
  64. // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
  65. //
  66. // SparcStation 20 Solaris 8:
  67. // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
  68. //
  69. // Mac OS X (Darwin)
  70. // 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
  71. //
  72. // Mac OS X early versions
  73. //
  74. // }}}
  75. /* TODO:
  76. * - define endianness, to allow matchSignature("bigend") etc.
  77. */
  78. class OS_Guess
  79. {
  80. var $sysname;
  81. var $nodename;
  82. var $cpu;
  83. var $release;
  84. var $extra;
  85. function OS_Guess($uname = null)
  86. {
  87. list($this->sysname,
  88. $this->release,
  89. $this->cpu,
  90. $this->extra,
  91. $this->nodename) = $this->parseSignature($uname);
  92. }
  93. function parseSignature($uname = null)
  94. {
  95. static $sysmap = array(
  96. 'HP-UX' => 'hpux',
  97. 'IRIX64' => 'irix',
  98. );
  99. static $cpumap = array(
  100. 'i586' => 'i386',
  101. 'i686' => 'i386',
  102. 'ppc' => 'powerpc',
  103. );
  104. if ($uname === null) {
  105. $uname = php_uname();
  106. }
  107. $parts = split('[[:space:]]+', trim($uname));
  108. $n = count($parts);
  109. $release = $machine = $cpu = '';
  110. $sysname = $parts[0];
  111. $nodename = $parts[1];
  112. $cpu = $parts[$n-1];
  113. $extra = '';
  114. if ($cpu == 'unknown') {
  115. $cpu = $parts[$n-2];
  116. }
  117. switch ($sysname) {
  118. case 'AIX':
  119. $release = "$parts[3].$parts[2]";
  120. break;
  121. case 'Windows':
  122. switch ($parts[1]) {
  123. case '95/98':
  124. $release = '9x';
  125. break;
  126. default:
  127. $release = $parts[1];
  128. break;
  129. }
  130. $cpu = 'i386';
  131. break;
  132. case 'Linux':
  133. $extra = $this->_detectGlibcVersion();
  134. // use only the first two digits from the kernel version
  135. $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]);
  136. break;
  137. case 'Mac' :
  138. $sysname = 'darwin';
  139. $nodename = $parts[2];
  140. $release = $parts[3];
  141. if ($cpu == 'Macintosh') {
  142. if ($parts[$n - 2] == 'Power') {
  143. $cpu = 'powerpc';
  144. }
  145. }
  146. break;
  147. case 'Darwin' :
  148. if ($cpu == 'Macintosh') {
  149. if ($parts[$n - 2] == 'Power') {
  150. $cpu = 'powerpc';
  151. }
  152. }
  153. $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]);
  154. break;
  155. default:
  156. $release = ereg_replace('-.*', '', $parts[2]);
  157. break;
  158. }
  159. if (isset($sysmap[$sysname])) {
  160. $sysname = $sysmap[$sysname];
  161. } else {
  162. $sysname = strtolower($sysname);
  163. }
  164. if (isset($cpumap[$cpu])) {
  165. $cpu = $cpumap[$cpu];
  166. }
  167. return array($sysname, $release, $cpu, $extra, $nodename);
  168. }
  169. function _detectGlibcVersion()
  170. {
  171. // Use glibc's <features.h> header file to
  172. // get major and minor version number:
  173. include_once "System.php";
  174. $tmpfile = System::mktemp("glibctest");
  175. $fp = fopen($tmpfile, "w");
  176. fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
  177. fclose($fp);
  178. $cpp = popen("/usr/bin/cpp $tmpfile", "r");
  179. $major = $minor = 0;
  180. while ($line = fgets($cpp, 1024)) {
  181. if ($line{0} == '#' || trim($line) == '') {
  182. continue;
  183. }
  184. if (list($major, $minor) = explode(' ', trim($line))) {
  185. break;
  186. }
  187. }
  188. pclose($cpp);
  189. unlink($tmpfile);
  190. if (!($major && $minor) && is_link('/lib/libc.so.6')) {
  191. // Let's try reading the libc.so.6 symlink
  192. if (ereg('^libc-([.*])\.so$', basename(readlink('/lib/libc.so.6')), $matches)) {
  193. list($major, $minor) = explode('.', $matches);
  194. }
  195. }
  196. if (!($major && $minor)) {
  197. return '';
  198. }
  199. return "glibc{$major}.{$minor}";
  200. }
  201. function getSignature()
  202. {
  203. if (empty($this->extra)) {
  204. return "{$this->sysname}-{$this->release}-{$this->cpu}";
  205. }
  206. return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
  207. }
  208. function getSysname()
  209. {
  210. return $this->sysname;
  211. }
  212. function getNodename()
  213. {
  214. return $this->nodename;
  215. }
  216. function getCpu()
  217. {
  218. return $this->cpu;
  219. }
  220. function getRelease()
  221. {
  222. return $this->release;
  223. }
  224. function getExtra()
  225. {
  226. return $this->extra;
  227. }
  228. function matchSignature($match)
  229. {
  230. if (is_array($match)) {
  231. $fragments = $match;
  232. } else {
  233. $fragments = explode('-', $match);
  234. }
  235. $n = count($fragments);
  236. $matches = 0;
  237. if ($n > 0) {
  238. $matches += $this->_matchFragment($fragments[0], $this->sysname);
  239. }
  240. if ($n > 1) {
  241. $matches += $this->_matchFragment($fragments[1], $this->release);
  242. }
  243. if ($n > 2) {
  244. $matches += $this->_matchFragment($fragments[2], $this->cpu);
  245. }
  246. if ($n > 3) {
  247. $matches += $this->_matchFragment($fragments[3], $this->extra);
  248. }
  249. return ($matches == $n);
  250. }
  251. function _matchFragment($fragment, $value)
  252. {
  253. if (strcspn($fragment, '*?') < strlen($fragment)) {
  254. $reg = '^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$';
  255. return eregi($reg, $value);
  256. }
  257. return ($fragment == '*' || !strcasecmp($fragment, $value));
  258. }
  259. }
  260. /*
  261. * Local Variables:
  262. * indent-tabs-mode: nil
  263. * c-basic-offset: 4
  264. * End:
  265. */
  266. ?>