PageRenderTime 25ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/namiltd-ini/plugins/smart/class.smart.inc.php

#
PHP | 280 lines | 209 code | 11 blank | 60 comment | 60 complexity | a992b56c08d4a86b5bdc4fed979f75b9 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * SMART Plugin
  4. *
  5. * PHP version 5
  6. *
  7. * @category PHP
  8. * @package PSI_Plugin_SMART
  9. * @author Antoine Bertin <diaoulael@users.sourceforge.net>
  10. * @copyright 2009 phpSysInfo
  11. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  12. * @version SVN: $Id: class.smart.inc.php 707 2012-11-28 10:20:49Z namiltd $
  13. * @link http://phpsysinfo.sourceforge.net
  14. */
  15. /**
  16. * SMART plugin, which displays all SMART informations available
  17. *
  18. * @category PHP
  19. * @package PSI_Plugin_SMART
  20. * @author Antoine Bertin <diaoulael@users.sourceforge.net>
  21. * @copyright 2009 phpSysInfo
  22. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  23. * @version Release: 3.0
  24. * @link http://phpsysinfo.sourceforge.net
  25. */
  26. class SMART extends PSI_Plugin
  27. {
  28. /**
  29. * variable, which holds the content of the command
  30. * @var array
  31. */
  32. private $_filecontent = array();
  33. /**
  34. * variable, which holds the result before the xml is generated out of this array
  35. * @var array
  36. */
  37. private $_result = array();
  38. /**
  39. * variable, which holds PSI_PLUGIN_SMART_IDS well formated datas
  40. * @var array
  41. */
  42. private $_ids = array();
  43. /**
  44. * read the data into an internal array and also call the parent constructor
  45. *
  46. * @param String $enc target encoding
  47. */
  48. public function __construct($enc)
  49. {
  50. parent::__construct(__CLASS__, $enc);
  51. switch (strtolower(PSI_PLUGIN_SMART_ACCESS)) {
  52. case 'command':
  53. if ( defined('PSI_PLUGIN_SMART_DEVICES') && is_string(PSI_PLUGIN_SMART_DEVICES) ) {
  54. if (preg_match(ARRAY_EXP, PSI_PLUGIN_SMART_DEVICES)) {
  55. $disks = eval(PSI_PLUGIN_SMART_DEVICES);
  56. } else {
  57. $disks = array(PSI_PLUGIN_SMART_DEVICES);
  58. }
  59. foreach ($disks as $disk) {
  60. $buffer = "";
  61. if (CommonFunctions::executeProgram('smartctl', '--all'.((PSI_PLUGIN_SMART_DEVICE) ? ' --device '.PSI_PLUGIN_SMART_DEVICE : '').' '.$disk, $buffer, PSI_DEBUG)) {
  62. $this->_filecontent[$disk] = $buffer;
  63. }
  64. }
  65. }
  66. if ( defined('PSI_PLUGIN_SMART_IDS') && is_string(PSI_PLUGIN_SMART_IDS) ) {
  67. if (preg_match(ARRAY_EXP, PSI_PLUGIN_SMART_IDS)) {
  68. $fullIds = eval(PSI_PLUGIN_SMART_IDS);
  69. } else {
  70. $fullIds = array(PSI_PLUGIN_SMART_IDS);
  71. }
  72. foreach ($fullIds as $fullId) {
  73. $arrFullId = preg_split('/-/', $fullId);
  74. $this->_ids[intval($arrFullId[0])] = strtolower($arrFullId[1]);
  75. if (!empty($arrFullId[2]))
  76. $this->_ids[intval($arrFullId[2])] = "#replace-".intval($arrFullId[0]);
  77. }
  78. }
  79. break;
  80. case 'data':
  81. if ( defined('PSI_PLUGIN_SMART_DEVICES') && is_string(PSI_PLUGIN_SMART_DEVICES) ) {
  82. if (preg_match(ARRAY_EXP, PSI_PLUGIN_SMART_DEVICES)) {
  83. $disks = eval(PSI_PLUGIN_SMART_DEVICES);
  84. } else {
  85. $disks = array(PSI_PLUGIN_SMART_DEVICES);
  86. }
  87. $dn=0;
  88. foreach ($disks as $disk) {
  89. $buffer="";
  90. if ((CommonFunctions::rfts(APP_ROOT."/data/smart{$dn}.txt", $buffer))&&(!empty($buffer))){
  91. $this->_filecontent[$disk] = $buffer;
  92. }
  93. $dn++;
  94. }
  95. }
  96. if ( defined('PSI_PLUGIN_SMART_IDS') && is_string(PSI_PLUGIN_SMART_IDS) ) {
  97. if (preg_match(ARRAY_EXP, PSI_PLUGIN_SMART_IDS)) {
  98. $fullIds = eval(PSI_PLUGIN_SMART_IDS);
  99. } else {
  100. $fullIds = array(PSI_PLUGIN_SMART_IDS);
  101. }
  102. foreach ($fullIds as $fullId) {
  103. $arrFullId = preg_split('/-/', $fullId);
  104. $this->_ids[intval($arrFullId[0])] = strtolower($arrFullId[1]);
  105. if (!empty($arrFullId[2]))
  106. $this->_ids[intval($arrFullId[2])] = "#replace-".intval($arrFullId[0]);
  107. }
  108. }
  109. break;
  110. default:
  111. $this->global_error->addError("switch(PSI_PLUGIN_SMART_ACCESS)", "Bad SMART configuration in SMART.config.php");
  112. break;
  113. }
  114. }
  115. /**
  116. * doing all tasks to get the required informations that the plugin needs
  117. * result is stored in an internal array
  118. *
  119. * @return void
  120. */
  121. public function execute()
  122. {
  123. if ( empty($this->_filecontent) || empty($this->_ids)) {
  124. return;
  125. }
  126. foreach ($this->_filecontent as $disk=>$result) {
  127. // set the start and end offset in the result string at the beginning and end respectively
  128. // just in case we don't find the two strings, so that it still works as expected.
  129. $startIndex = 0;
  130. $endIndex = 0;
  131. $vendorInfos = "";
  132. // locate the beginning string offset for the attributes
  133. if ( preg_match('/(Vendor Specific SMART Attributes with Thresholds)/', $result, $matches, PREG_OFFSET_CAPTURE) )
  134. $startIndex = $matches[0][1];
  135. // locate the end string offset for the attributes, this is usually right before string "SMART Error Log Version" or "SMART Error Log not supported" (hopefully every output has it!)
  136. if ( preg_match('/(SMART Error Log Version)|(SMART Error Log not supported)/', $result, $matches, PREG_OFFSET_CAPTURE) )
  137. $endIndex = $matches[0][1];
  138. if (($startIndex)&&($endIndex)&&($endIndex>$startIndex))
  139. $vendorInfos = preg_split("/\n/", substr ( $result, $startIndex, $endIndex - $startIndex ));
  140. if (!empty($vendorInfos)) {
  141. $labels = preg_split('/[\s]+/', $vendorInfos[1]);
  142. foreach ($labels as $k=>$v) {
  143. $labels[$k] = str_replace('#', '', strtolower($v));
  144. }
  145. $i = 0; // Line number
  146. foreach ($vendorInfos as $line) {
  147. $line = preg_replace('/^[\s]+/', '', $line);
  148. $values = preg_split('/[\s]+/', $line);
  149. if (count($values) > count($labels)) {
  150. $values = array_slice($values, 0, count($labels), true);
  151. }
  152. $j = 0;
  153. $found = false;
  154. foreach ($values as $value) {
  155. if ((in_array($value, array_keys($this->_ids)) && $labels[$j] == 'id')) {
  156. $arrFullVa = preg_split('/-/', $this->_ids[$value]);
  157. if (($arrFullVa[0]=="#replace")&&(!empty($arrFullVa[1])))
  158. $value=$arrFullVa[1];
  159. }
  160. if (((in_array($value, array_keys($this->_ids)) && $labels[$j] == 'id') || ($found && (in_array($labels[$j], array_values($this->_ids)))) || ($found && $labels[$j] == 'attribute_name'))) {
  161. $this->_result[$disk][$i][$labels[$j]] = $value;
  162. $found = true;
  163. }
  164. $j++;
  165. }
  166. $i++;
  167. }
  168. } else {
  169. //SCSI devices
  170. if ((!empty($this->_ids[1]))&&($this->_ids[1]=="raw_value")) {
  171. preg_match('/read\: (.*)\n/', $result, $lines);
  172. if ((!empty($lines))&&(!empty($lines[0]))) {
  173. $values=preg_split('/[\s,]+/',$lines[0]);
  174. if ((!empty($values))&&($values[7]!=null)){
  175. $this->_result[$disk][0]['id'] = 1;
  176. $this->_result[$disk][0]['attribute_name'] = "Raw_Read_Error_Rate";
  177. $this->_result[$disk][0]['raw_value'] = $values[7];
  178. }
  179. }
  180. }
  181. if ((!empty($this->_ids[5]))&&($this->_ids[5]=="raw_value")) {
  182. preg_match('/Elements in grown defect list\: (.*)\n/', $result, $lines);
  183. if ((!empty($lines))&&(!empty($lines[0]))) {
  184. $values=preg_split('/[\s,]+/',$lines[0]);
  185. if ((!empty($values))&&($values[5]!=null)){
  186. $this->_result[$disk][1]['id'] = 5;
  187. $this->_result[$disk][1]['attribute_name'] = "Reallocated_Sector_Ct";
  188. $this->_result[$disk][1]['raw_value'] = $values[5];
  189. }
  190. }
  191. }
  192. if ((!empty($this->_ids[9]))&&($this->_ids[9]=="raw_value")) {
  193. preg_match('/ number of hours powered up = (.*)\n/', $result, $lines);
  194. if ((!empty($lines))&&(!empty($lines[0]))) {
  195. $values=preg_split('/[\s,.]+/',$lines[0]);
  196. if ((!empty($values))&&($values[7]!=null)){
  197. $this->_result[$disk][2]['id'] = 9;
  198. $this->_result[$disk][2]['attribute_name'] = "Power_On_Hours";
  199. $this->_result[$disk][2]['raw_value'] = $values[7];
  200. }
  201. }
  202. }
  203. if ((!empty($this->_ids[194]))&&($this->_ids[194]=="raw_value")) {
  204. preg_match('/Current Drive Temperature\: (.*)\n/', $result, $lines);
  205. if ((!empty($lines))&&(!empty($lines[0]))) {
  206. $values=preg_split('/[\s,]+/',$lines[0]);
  207. if ((!empty($values))&&($values[3]!=null)){
  208. $this->_result[$disk][3]['id'] = 194;
  209. $this->_result[$disk][3]['attribute_name'] = "Temperature_Celsius";
  210. $this->_result[$disk][3]['raw_value'] = $values[3];
  211. }
  212. }
  213. }
  214. }
  215. }
  216. //Usage test
  217. $newIds = array();
  218. foreach ($this->_ids as $id=>$column_name) {
  219. $found = 0;
  220. foreach ($this->_result as $diskName=>$diskInfos) {
  221. if ($found!=2) foreach ($diskInfos as $lineInfos) {
  222. if ($found!=2) {
  223. $found = 0;
  224. foreach ($lineInfos as $label=>$value) {
  225. if (($found==0)&&($label=="id")&&($value==$id))
  226. $found = 1;
  227. if (($found==1)&&($label==$column_name))
  228. $found = 2;
  229. }
  230. }
  231. }
  232. }
  233. if ($found==2) $newIds[$id] = $this->_ids[$id];
  234. }
  235. $this->_ids = $newIds;
  236. }
  237. /**
  238. * generates the XML content for the plugin
  239. *
  240. * @return SimpleXMLObject entire XML content for the plugin
  241. */
  242. public function xml()
  243. {
  244. if ( empty($this->_result) || empty($this->_ids)) {
  245. return $this->xml->getSimpleXmlElement();
  246. }
  247. $columnsChild = $this->xml->addChild('columns');
  248. // Fill the xml with preferences
  249. foreach ($this->_ids as $id=>$column_name) {
  250. $columnChild = $columnsChild->addChild('column');
  251. $columnChild->addAttribute('id', $id);
  252. $columnChild->addAttribute('name', $column_name);
  253. }
  254. $disksChild = $this->xml->addChild('disks');
  255. // Now fill the xml with S.M.A.R.T datas
  256. foreach ($this->_result as $diskName=>$diskInfos) {
  257. $diskChild = $disksChild->addChild('disk');
  258. $diskChild->addAttribute('name', $diskName);
  259. foreach ($diskInfos as $lineInfos) {
  260. $lineChild = $diskChild->addChild('attribute');
  261. foreach ($lineInfos as $label=>$value) {
  262. $lineChild->addAttribute($label, $value);
  263. }
  264. }
  265. }
  266. return $this->xml->getSimpleXmlElement();
  267. }
  268. }
  269. ?>