Guess.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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 2004/01/08 17:33:11 sniper 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. // }}}
  70. /* TODO:
  71. * - define endianness, to allow matchSignature("bigend") etc.
  72. */
  73. class OS_Guess
  74. {
  75. var $sysname;
  76. var $nodename;
  77. var $cpu;
  78. var $release;
  79. var $extra;
  80. function OS_Guess($uname = null)
  81. {
  82. list($this->sysname,
  83. $this->release,
  84. $this->cpu,
  85. $this->extra,
  86. $this->nodename) = $this->parseSignature($uname);
  87. }
  88. function parseSignature($uname = null)
  89. {
  90. static $sysmap = array(
  91. 'HP-UX' => 'hpux',
  92. 'IRIX64' => 'irix',
  93. // Darwin?
  94. );
  95. static $cpumap = array(
  96. 'i586' => 'i386',
  97. 'i686' => 'i386',
  98. );
  99. if ($uname === null) {
  100. $uname = php_uname();
  101. }
  102. $parts = split('[[:space:]]+', trim($uname));
  103. $n = count($parts);
  104. $release = $machine = $cpu = '';
  105. $sysname = $parts[0];
  106. $nodename = $parts[1];
  107. $cpu = $parts[$n-1];
  108. $extra = '';
  109. if ($cpu == 'unknown') {
  110. $cpu = $parts[$n-2];
  111. }
  112. switch ($sysname) {
  113. case 'AIX':
  114. $release = "$parts[3].$parts[2]";
  115. break;
  116. case 'Windows':
  117. switch ($parts[1]) {
  118. case '95/98':
  119. $release = '9x';
  120. break;
  121. default:
  122. $release = $parts[1];
  123. break;
  124. }
  125. $cpu = 'i386';
  126. break;
  127. case 'Linux':
  128. $extra = $this->_detectGlibcVersion();
  129. // use only the first two digits from the kernel version
  130. $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]);
  131. break;
  132. default:
  133. $release = ereg_replace('-.*', '', $parts[2]);
  134. break;
  135. }
  136. if (isset($sysmap[$sysname])) {
  137. $sysname = $sysmap[$sysname];
  138. } else {
  139. $sysname = strtolower($sysname);
  140. }
  141. if (isset($cpumap[$cpu])) {
  142. $cpu = $cpumap[$cpu];
  143. }
  144. return array($sysname, $release, $cpu, $extra, $nodename);
  145. }
  146. function _detectGlibcVersion()
  147. {
  148. // Use glibc's <features.h> header file to
  149. // get major and minor version number:
  150. include_once "System.php";
  151. $tmpfile = System::mktemp("glibctest");
  152. $fp = fopen($tmpfile, "w");
  153. fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
  154. fclose($fp);
  155. $cpp = popen("/usr/bin/cpp $tmpfile", "r");
  156. $major = $minor = 0;
  157. while ($line = fgets($cpp, 1024)) {
  158. if ($line{0} == '#' || trim($line) == '') {
  159. continue;
  160. }
  161. if (list($major, $minor) = explode(' ', trim($line))) {
  162. break;
  163. }
  164. }
  165. pclose($cpp);
  166. unlink($tmpfile);
  167. if (!($major && $minor) && is_link('/lib/libc.so.6')) {
  168. // Let's try reading the libc.so.6 symlink
  169. if (ereg('^libc-([.*])\.so$', basename(readlink('/lib/libc.so.6')), $matches)) {
  170. list($major, $minor) = explode('.', $matches);
  171. }
  172. }
  173. if (!($major && $minor)) {
  174. return '';
  175. }
  176. return "glibc{$major}.{$minor}";
  177. }
  178. function getSignature()
  179. {
  180. if (empty($this->extra)) {
  181. return "{$this->sysname}-{$this->release}-{$this->cpu}";
  182. }
  183. return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
  184. }
  185. function getSysname()
  186. {
  187. return $this->sysname;
  188. }
  189. function getNodename()
  190. {
  191. return $this->nodename;
  192. }
  193. function getCpu()
  194. {
  195. return $this->cpu;
  196. }
  197. function getRelease()
  198. {
  199. return $this->release;
  200. }
  201. function getExtra()
  202. {
  203. return $this->extra;
  204. }
  205. function matchSignature($match)
  206. {
  207. if (is_array($match)) {
  208. $fragments = $match;
  209. } else {
  210. $fragments = explode('-', $match);
  211. }
  212. $n = count($fragments);
  213. $matches = 0;
  214. if ($n > 0) {
  215. $matches += $this->_matchFragment($fragments[0], $this->sysname);
  216. }
  217. if ($n > 1) {
  218. $matches += $this->_matchFragment($fragments[1], $this->release);
  219. }
  220. if ($n > 2) {
  221. $matches += $this->_matchFragment($fragments[2], $this->cpu);
  222. }
  223. if ($n > 3) {
  224. $matches += $this->_matchFragment($fragments[3], $this->extra);
  225. }
  226. return ($matches == $n);
  227. }
  228. function _matchFragment($fragment, $value)
  229. {
  230. if (strcspn($fragment, '*?') < strlen($fragment)) {
  231. $reg = '^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$';
  232. return eregi($reg, $value);
  233. }
  234. return ($fragment == '*' || !strcasecmp($fragment, $value));
  235. }
  236. }
  237. /*
  238. * Local Variables:
  239. * indent-tabs-mode: nil
  240. * c-basic-offset: 4
  241. * End:
  242. */
  243. ?>