PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/pulse2/web/modules/msc/includes/command_history.php

https://github.com/vmasilva/mmc
PHP | 514 lines | 438 code | 30 blank | 46 comment | 78 complexity | a471a3acb0369f15edb0b6a42dcd3f15 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * (c) 2004-2007 Linbox / Free&ALter Soft, http://linbox.com
  4. * (c) 2007 Mandriva, http://www.mandriva.com/
  5. *
  6. * $Id$
  7. *
  8. * This file is part of Mandriva Management Console (MMC).
  9. *
  10. * MMC is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * MMC is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with MMC; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. require_once("functions.php"); # for return_icon
  25. require_once("utilities.php"); # for pretty bw display
  26. require_once("mscoptions_xmlrpc.php"); # to read msc.ini
  27. class CommandOnHost {
  28. function CommandOnHost($coh) {
  29. $statusTable = getStatusTable();
  30. $this->db_coh = get_commands_on_host($coh);
  31. #$this->db_cmd = command_detail($this->db_coh['fk_commands']);
  32. $this->values = array(
  33. array(_T('Host', 'msc'), $this->db_coh['host'], 1),
  34. array(_T('Current State', 'msc'), $statusTable[$this->db_coh['current_state']], 1),
  35. array(_T('awoken', 'msc'), _plusIcon($this->db_coh['awoken']), 1),
  36. array(_T('uploaded', 'msc'), _plusIcon($this->db_coh['uploaded']), 1),
  37. array(_T('executed', 'msc'), _plusIcon($this->db_coh['executed']), 1),
  38. array(_T('deleted', 'msc'), _plusIcon($this->db_coh['deleted']), 1),
  39. array(_T('inventoried', 'msc'), _plusIcon($this->db_coh['inventoried']), 1),
  40. array(_T('rebooted', 'msc'), _plusIcon($this->db_coh['rebooted']), 1),
  41. array(_T('halted', 'msc'), _plusIcon($this->db_coh['halted']), 1)
  42. );
  43. }
  44. function display() {
  45. $n = new ListInfos(array_map("_names", $this->values), _T('Name', 'msc'));
  46. $n->addExtraInfo(array_map("_values", $this->values), _T('Value', 'msc'));
  47. $n->setRowsPerPage(count($this->values));
  48. $n->drawTable(0);
  49. }
  50. function quickDisplay($actions = array(), $params = array()) {
  51. $statusTable = getStatusTable();
  52. $n = null;
  53. $params = array();
  54. foreach ($this->values as $col) {
  55. if ($col[2]) {
  56. if ($n) {
  57. $n->addExtraInfo(array($col[1]), $col[0]);
  58. } else {
  59. $n = new ListInfos(array($col[1]), $col[0]);
  60. }
  61. }
  62. }
  63. $n->setParamInfo(array($params));
  64. foreach ($actions as $a) {
  65. $n->addActionItem($a);
  66. }
  67. $n->col_width=array("50px", "50px", "50px", "50px", "50px", "50px", "50px", "50px", "50px");
  68. $n->drawTable(0);
  69. }
  70. }
  71. class Bundle {
  72. function Bundle($bundle_id) {
  73. $this->db_bundle = bundle_detail($bundle_id);
  74. if (!$this->db_cmd) { # use does not have the good permissions
  75. return false;
  76. }
  77. }
  78. function quickDisplay($actions = array(), $params = array()) {
  79. if (!$this->db_bundle || $this->db_bundle[0] == null) { # user does not have the good permissions
  80. $widget = new RenderedMSCCommandDontExists();
  81. $widget->display();
  82. return false;
  83. }
  84. if (!strlen($this->db_bundle[0]['title'])) {
  85. $this->db_bundle[0]['title'] = "Bundle #".$this->db_bundle[0]['id'];
  86. }
  87. $n = new ListInfos(array($this->db_bundle[0]['title']), _T('Bundle', 'msc'));
  88. $n->addExtraInfo(array(_toDate($this->db_bundle[0]['creation_date'])), _T('Creation date', 'msc'));
  89. $n->setParamInfo(array($params));
  90. foreach ($actions as $a) {
  91. $n->addActionItem($a);
  92. }
  93. $n->drawTable(0);
  94. return true;
  95. }
  96. }
  97. class Command {
  98. function Command($cmd) {
  99. $this->db_cmd = command_detail($cmd);
  100. $this->error = false;
  101. if (!$this->db_cmd) { # use does not have the good permissions
  102. return false;
  103. }
  104. $this->values = array(
  105. array(_T('Command name', 'msc'),$this->db_cmd['title'], 1),
  106. array(_T('Creation date', 'msc'),_toDate($this->db_cmd['creation_date']), 1),
  107. array(_T('User command creator', 'msc'),$this->db_cmd['creator'], 0),
  108. array(_T('Execute file', 'msc'),$this->db_cmd['start_file'], 0),
  109. array(_T('Execution arguments', 'msc'),$this->db_cmd['parameters'], 0),
  110. array(_T('Start execute file', 'msc'),$this->db_cmd['start_script'], 0),
  111. array(_T('Start inventory agent', 'msc'),$this->db_cmd['do_inventory'], 0),
  112. array(_T('Start "Wake On Lan" query if connection fails', 'msc'),$this->db_cmd['do_wol'], 0),
  113. array(_T('Delay between two connections', 'msc'),$this->db_cmd['next_connection_delay'], 0),
  114. array(_T('Command start date', 'msc'),_toDate($this->db_cmd['start_date']), 0),
  115. array(_T('Command expiry date', 'msc'),_toDate($this->db_cmd['end_date']), 0),
  116. );
  117. }
  118. function display() {
  119. if (!$this->db_cmd) { # user do not have the right permissions
  120. $widget = new RenderedMSCCommandDontExists();
  121. $widget->display();
  122. return false;
  123. }
  124. $name = array_map("_names", $this->values);
  125. $value = array_map("_values", $this->values);
  126. $n = new ListInfos($name, _T('Name', 'msc'));
  127. $n->addExtraInfo($value, _T('Value', 'msc'));
  128. $n->setRowsPerPage(count($this->values));
  129. $n->drawTable(0);
  130. return true;
  131. }
  132. function quickDisplay($actions = array(), $params = array()) {
  133. if (!$this->db_cmd) { # user do not have the right permissions
  134. $widget = new RenderedMSCCommandDontExists();
  135. $widget->display();
  136. return false;
  137. }
  138. $n = null;
  139. foreach ($this->values as $col) {
  140. if ($col[2]) {
  141. if ($n) {
  142. $n->addExtraInfo(array($col[1]), $col[0]);
  143. } else {
  144. $n = new ListInfos(array($col[1]), $col[0]);
  145. }
  146. }
  147. }
  148. $n->setParamInfo(array($params));
  149. foreach ($actions as $a) {
  150. $n->addActionItem($a);
  151. }
  152. $n->drawTable(0);
  153. return true;
  154. }
  155. }
  156. function my_convert($str) {
  157. return _T($str, 'msc');
  158. }
  159. function i18nparts($str) {
  160. if (is_array($str)) {
  161. return implode(', ', array_map('my_convert', $str));
  162. } elseif (!empty($str))
  163. return implode(', ', array_map('my_convert', explode(',', $str)));
  164. else return _T('<i>not set</i>', 'msc');
  165. }
  166. class CommandHistory {
  167. function CommandHistory($coh_id) {
  168. // TODO : ch is a list, we have to chose the good one (ie : the most recent date)
  169. $this->db_ch = get_command_history($coh_id);
  170. $this->db_coh = get_commands_on_host($coh_id);
  171. if ($this->db_coh['fk_use_as_proxy'])
  172. $this->db_lproxy = get_commands_on_host($this->db_coh['fk_use_as_proxy']);
  173. else
  174. $this->db_lproxy = NULL;
  175. $this->db_cmd = command_detail($this->db_coh['fk_commands']);
  176. }
  177. function display() {
  178. // display parameters
  179. if (!$this->db_cmd) { # use does not have the good permissions
  180. $widget = new RenderedMSCCommandDontExists();
  181. $widget->display();
  182. return;
  183. }
  184. # FIXME: stolen from ajaxLogsFilter.php, should be factorized
  185. $a_uploaded ='<img style="vertical-align: middle;" alt="'.$this->db_coh['uploaded'].'" src="modules/msc/graph/images/status/'.return_icon($this->db_coh['uploaded']).'"/> ';
  186. $a_executed ='<img style="vertical-align: middle;" alt="'.$this->db_coh['executed'].'" src="modules/msc/graph/images/status/'.return_icon($this->db_coh['executed']).'"/> ';
  187. $a_deleted = '<img style="vertical-align: middle;" alt="'.$this->db_coh['deleted'].'" src="modules/msc/graph/images/status/'.return_icon($this->db_coh['deleted']).'"/> ';
  188. $state = $a_uploaded . $a_executed . $a_deleted;
  189. if ($this->db_cmd['start_date'])
  190. if ($this->db_cmd['end_date'])
  191. $validity = sprintf(_T('<i>from</i> %s <i>to</i> %s', 'msc'), _toDate($this->db_cmd['start_date']), _toDate($this->db_cmd['end_date']));
  192. else
  193. $validity = sprintf(_T('<i>from</i> %s', 'msc'), _toDate($this->db_cmd['start_date']));
  194. else
  195. if ($this->db_cmd['end_date'])
  196. $validity = sprintf(_T('<i>to</i> %s', 'msc'), _toDate($this->db_cmd['end_date']));
  197. else
  198. $validity = _T('<i>forever</i>', 'msc');
  199. if ($this->db_cmd['deployment_intervals']) {
  200. $deploy_interv = str_replace(array('-', ','), array(' - ', ', '), $this->db_cmd['deployment_intervals']);
  201. } else
  202. $deploy_interv = _T('<i>whole day</i>', 'msc');
  203. if ($this->db_cmd['deployment_intervals']) {
  204. $deploy_interv = str_replace(array('-', ','), array(' - ', ', '), $this->db_cmd['deployment_intervals']);
  205. } else
  206. $deploy_interv = _T('<i>whole day</i>', 'msc');
  207. if ($this->db_coh['next_launch_date'])
  208. $next_launch_date = _toDate($this->db_coh['next_launch_date']);
  209. else
  210. if ($this->db_cmd['start_date'])
  211. $next_launch_date = _toDate($this->db_cmd['start_date']);
  212. else
  213. $next_launch_date = _T('<i>as soon as possible</i>', 'msc');
  214. if ($this->db_coh['start_date'])
  215. $start_date = _toDate($this->db_coh['start_date']);
  216. else
  217. $start_date = _T('<i>not yet available</i>', 'msc');
  218. if ($this->db_coh['end_date'])
  219. $end_date = _toDate($this->db_coh['end_date']);
  220. else
  221. $end_date = _T('<i>not yet available</i>', 'msc');
  222. if ($this->db_coh['last_wol_attempt'])
  223. $last_wol_attempt = _toDate($this->db_coh['last_wol_attempt']);
  224. else
  225. $last_wol_attempt = _T('<i>not available</i>', 'msc');
  226. if ($this->db_cmd['start_file'])
  227. if ($this->db_cmd['parameters'])
  228. $command_line = sprintf(_T('%s %s', 'msc'), $this->db_cmd['start_file'], $this->db_cmd['parameters']);
  229. else
  230. $command_line = sprintf(_T('%s <i>(no additional parameter given)</i>', 'msc'), $this->db_cmd['start_file']);
  231. else
  232. $command_line = _T('<i>not set</i>', 'msc');
  233. if ($this->db_coh['order_in_proxy'] == '')
  234. $proxy_priority = _T('None (Local Proxy Client)', 'msc');
  235. else
  236. $proxy_priority = sprintf(_T('%s (Local Proxy Server)', 'msc'), $this->db_coh['order_in_proxy']);
  237. if ($this->db_cmd['proxy_mode'] == 'split')
  238. $proxy_mode = _T('Multiple', 'msc');
  239. elseif ($this->db_cmd['proxy_mode'] == 'queue')
  240. $proxy_mode = _T('Single with fallback', 'msc');
  241. elseif ($this->db_cmd['proxy_mode'] == 'none') {
  242. $proxy_mode = _T('No proxy', 'msc');
  243. $proxy_priority = _T('None', 'msc');
  244. } else {
  245. $proxy_mode = _T('<i>not available</i>', 'msc');
  246. $proxy_priority = _T('<i>not available</i>', 'msc');
  247. }
  248. if ($this->db_lproxy)
  249. $current_proxy = $this->db_lproxy['host'];
  250. else
  251. $current_proxy = _T('<i>not available</i>', 'msc');
  252. // gettext obfucation
  253. _T('enable', 'msc');
  254. _T('disable', 'msc');
  255. _T('done', 'msc');
  256. _T('failed', 'msc');
  257. _T('over_time', 'msc');
  258. _T('out_of_interval', 'msc');
  259. ### Display command overview ###
  260. $values = array(
  261. array(_T('State', 'msc'), $state),
  262. array(_T('Command name', 'msc'), $this->db_cmd['title']),
  263. array(_T('Creation', 'msc'), sprintf(_T('<i>on</i> %s <i>by</i> %s', 'msc'), _toDate($this->db_cmd['creation_date']),$this->db_cmd['creator'])),
  264. array(_T('Validity period', 'msc'), $validity),
  265. array(_T('Deployment interval', 'msc'), $deploy_interv),
  266. );
  267. $n = new ListInfos(array_map("_names", $values), _T('<b>Command Overview</b>', 'msc'));
  268. $n->addExtraInfo(array_map("_values", $values), '', '400px');
  269. $n->setTableHeaderPadding(0);
  270. $n->setRowsPerPage(count($values));
  271. $n->drawTable(0);
  272. print "<hr/><br/>";
  273. ### Display command stages ###
  274. $values = array(
  275. array(_T('Command line to run', 'msc'), $command_line),
  276. array(_T('Start "Wake On Lan" query if connection fails', 'msc'), $this->db_cmd['do_wol'] == 'enable' ? _T('yes', 'msc') : _T('no', 'msc')),
  277. array(_T('Execute command line ?', 'msc'), $this->db_cmd['start_script'] == 'enable' ? _T('yes', 'msc') : _T('no', 'msc')),
  278. array(_T('Delete files after a successful execution ?', 'msc'), $this->db_cmd['clean_on_success'] == 'enable' ? _T('yes', 'msc') : _T('no', 'msc')),
  279. array(_T('Do an inventory after a successful execution ?', 'msc'), $this->db_cmd['do_inventory'] == 'enable' ? _T('yes', 'msc') : _T('no', 'msc')),
  280. array(_T('Reboot client after a successful deletion ?', 'msc'), $this->db_cmd['do_reboot'] == 'enable' ? _T('yes', 'msc') : _T('no', 'msc')),
  281. array(_T('Halt client after :', 'msc'), i18nparts($this->db_cmd['do_halt'])),
  282. );
  283. $n = new ListInfos(array_map("_names", $values), _T('<b>Command Stages</b>', 'msc'));
  284. $n->addExtraInfo(array_map("_values", $values), '', '400px');
  285. $n->setTableHeaderPadding(0);
  286. $n->setRowsPerPage(count($values));
  287. $n->drawTable(0);
  288. print "<hr/><br/>";
  289. ### Display command environment ###
  290. $values = array(
  291. array(_T('Reserved bandwidth', 'msc'), $this->db_cmd['maxbw'] == '0' ? _T('<i>none</i>', 'msc') : prettyOctetDisplay($this->db_cmd['maxbw'], 1024, _T('bit/s', 'msc'))),
  292. array(_T('Proxy mode', 'msc'), $proxy_mode),
  293. array(_T('Proxy priority', 'msc'), $proxy_priority),
  294. array(_T('Scheduler', 'msc'), $this->db_coh['scheduler']),
  295. array(_T('Current launcher', 'msc'), $this->db_coh['launcher'] == '' ? _T('<i>not available</i>', 'msc') : $this->db_coh['launcher']),
  296. array(_T('Current proxy', 'msc'), $current_proxy),
  297. );
  298. $n = new ListInfos(array_map("_names", $values), _T('<b>Command Environment</b>', 'msc'));
  299. $n->addExtraInfo(array_map("_values", $values), '', '400px');
  300. $n->setTableHeaderPadding(0);
  301. $n->setRowsPerPage(count($values));
  302. $n->drawTable(0);
  303. print "<hr/><br/>";
  304. ### Display command life cycle ###
  305. $values = array(
  306. array(_T('First operation at', 'msc'), $start_date),
  307. array(_T('Remaining connection attempts', 'msc'), sprintf(_T('%s (on %s)', 'msc'), $this->db_coh['attempts_left'], $this->db_cmd['max_connection_attempt'])),
  308. array(_T('Delay between two attempts (minutes)', 'msc'), $this->db_cmd['next_connection_delay'] ? $this->db_cmd['next_connection_delay'] : _T('<i>not set</i>', 'msc')),
  309. array(_T('Last WOL attempt', 'msc'), $last_wol_attempt),
  310. array(_T('Next attempt', 'msc'), $next_launch_date),
  311. array(_T('Last operation at', 'msc'), $end_date),
  312. );
  313. $n = new ListInfos(array_map("_names", $values), _T('<b>Command Life Cycle</b>', 'msc'));
  314. $n->addExtraInfo(array_map("_values", $values), '', '400px');
  315. $n->setTableHeaderPadding(0);
  316. $n->setRowsPerPage(count($values));
  317. $n->drawTable(0);
  318. print "<hr/><br/>";
  319. ### Display to be transfered files ###
  320. $files = array(_T('List of files to be transfered is empty.', 'msc'));
  321. if ($this->db_cmd["files"]!="" && $this->db_cmd["files"]!=array()) {
  322. if (gettype($command["files"]) != 'array') {
  323. $files = explode("\n", $this->db_cmd["files"]);
  324. } else {
  325. $files = $this->db_cmd["files"];
  326. }
  327. }
  328. $n = new ListInfos($files, _T('<b>Files to be transfered</b>', 'msc'));
  329. $n->setTableHeaderPadding(0);
  330. $n->setRowsPerPage(count($values));
  331. $n->drawTable(0);
  332. print "<hr/><br/>";
  333. # display command history
  334. # display log files
  335. $statusTable = getStatusTable();
  336. $i = 1;
  337. foreach ($this->db_ch as $hist) {
  338. if (($hist['state'] == 'upload_in_progress') && ($hist['error_code'] == '0') && (array_key_exists('stderr', $hist)) && ($i != count($this->db_ch)) && (strpos($hist['stderr'], 'is available on mirror') !== False)) {
  339. /*
  340. We are displaying which package server was used in push pull
  341. mode. We want to keep the led green instead of orange to
  342. tell the user that there was no problem.
  343. */
  344. $staticon = history_stat2icon("upload_done");
  345. } elseif ($hist['state'] == 'wol_failed' && $hist['error_code'] == '2001') {
  346. $staticon = history_stat2icon("stop");
  347. } else {
  348. $staticon = history_stat2icon($hist['state']);
  349. }
  350. $history = '<img style="vertical-align: middle;" alt="'.$hist['state'].'" src="modules/msc/graph/images/status/'.$staticon.'"/> '.date("Y-m-d H:i:s", $hist['date']).': <b>'.$statusTable[$hist['state']].'</b>';
  351. /* Split lines in stdout and stderr */
  352. if (gettype($hist["stdout"]) != 'array')
  353. $hist["stdout"] = split("\n", $hist["stdout"]);
  354. if (gettype($hist["stderr"]) != 'array')
  355. $hist["stderr"] = split("\n", $hist["stderr"]);
  356. if (count($hist["stdout"]) > 0 &&
  357. !(count($hist["stdout"]) == 1 && $hist["stdout"][0] == '')
  358. ) {
  359. $hist["stderr"] = array_merge($hist["stderr"], $hist["stdout"]);
  360. }
  361. if (strpos($hist['state'], '_failed') !== False || ($hist['error_code'] > 4501 && $hist['error_code'] < 5000)) {
  362. $msgs = array(
  363. // BIG HUGE TODO: should get base value (230) from the agent (PULSE2_WRAPPER_ERROR_PRECHECK_BASE from consts.py)
  364. /* When SSH returns 255, an error occurred while
  365. connecting to the host. On some platforms like
  366. RHEL 4, buggy SSH returns 1 */
  367. 255 => _T("Error while connecting to secure agent on this host. Please check network connectivity, and that the secure agent is installed on this host.", 'msc'),
  368. /* Known exit codes : killed by signal */
  369. 200 + 9 => _T("The script was killed by Pulse 2 (timeout ?).", 'msc'),
  370. 200 + 15 => _T("The script was terminated by Pulse 2.", 'msc'),
  371. /* Known exit codes : pre-check */
  372. 240 + 0 => _T("Something goes wrong while checking client identity.", 'msc'),
  373. 240 + 1 => _T("The current host name doesn't match the host name from the inventory database.", 'msc'),
  374. 240 + 2 => _T("The current host IP address doesn't match the IP address from the inventory database.", 'msc'),
  375. 240 + 3 => _T("The current host MAC address doesn't match the MAC address from the inventory database.", 'msc'),
  376. /* Known exit codes : */
  377. 4000 + 1 => sprintf(_T("The package '%s' is not available on any mirror.", "msc"), $hist['stderr'][0]),
  378. 4000 + 2 => sprintf(_T("Can't get files URI for package '%s' on mirror %s.\nPlease check that the package and its files have not been modified since the planning of the command.", "msc"), $hist['stderr'][0], $hist['stderr'][1]),
  379. 4000 + 3 => sprintf(_T("Can't get files URI for package '%s' on fallback mirror %s.\nPlease check that the package and its files have not been modified since the planning of the command.", "msc"), $hist['stderr'][0], $hist['stderr'][1]),
  380. 4000 + 4 => sprintf(_T("An error occurred when trying to contact the mirror '%s' : the connection was refused.", "msc"), $hist['stderr'][0]),
  381. 4000 + 5 => sprintf(_T("An error occurred when trying to contact the fallback mirror '%s' : the connection was refused.", "msc"), $hist['stderr'][0]),
  382. 4000 + 6 => sprintf(_T("An error occurred when trying to contact the mirror '%s' : the mountpoint doesn't exists.", "msc"), $hist['stderr'][0]),
  383. 4000 + 7 => sprintf(_T("An error occurred when trying to contact the fallback mirror '%s' : the mountpoint doesn't exists.", "msc"), $hist['stderr'][0]),
  384. 4500 + 8 => sprintf(_T("Package '%s' is NOT available on primary mirror %s\nPackage '%s' is available on fallback mirror %s", "msc"), $hist['stdout'][0], $hist['stdout'][1], $hist['stdout'][2], $hist['stdout'][3]),
  385. 4500 + 9 => sprintf(_T("Package '%s' is available on primary mirror %s", "msc"), $hist['stdout'][0], $hist['stdout'][1]),
  386. );
  387. if ($hist['error_code'] >= 4001 && $hist['error_code'] < 5000) { $hist["stderr"] = array(''); }
  388. if (array_key_exists($hist['error_code'], $msgs)) {
  389. $hist['stderr'][] = $msgs[$hist['error_code']];
  390. }
  391. }
  392. $raw_errors = array_map('_colorise', array_filter($hist["stderr"]));
  393. $purge_errors = array();
  394. foreach ($raw_errors as $error)
  395. if (isset($error))
  396. array_push($purge_errors, $error);
  397. $n = new ListInfos($purge_errors, $history);
  398. $n->setTableHeaderPadding(0);
  399. $n->setRowsPerPage(count($purge_errors) + 1);
  400. if (count($hist["stderr"]) > 0 &&
  401. !(count($hist["stderr"]) == 1 && $hist["stderr"][0] == '')
  402. ) {
  403. $n->drawTable(0);
  404. }
  405. $i++;
  406. }
  407. }
  408. }
  409. function _values($a) { return $a[1]; }
  410. function _names($a) { return $a[0]; }
  411. function _colorise($line) {
  412. if (preg_match_all("|^(.*) ([A-Z]): (.*)$|", $line, $matches)) {
  413. if (strlen($matches[3][0]) == 0)
  414. return;
  415. $date = date(_T("Y-m-d H:i:s", "msc"), $matches[1][0]);
  416. if ($matches[2][0] == "E") {
  417. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  418. $out .= '<font color=red face=sans-serif>';
  419. $out .= $matches[3][0];
  420. $out .= '</font><br/>';
  421. } elseif ($matches[2][0] == "C") {
  422. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  423. $out .= '<font color=navy face=sans-serif>';
  424. $out .= join(split('路', $matches[3][0]), ' ');
  425. $out .= '</font><br/>';
  426. } elseif ($matches[2][0] == "T") {
  427. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  428. $out .= '<font color=purple face=sans-serif>';
  429. $out .= join(split('路', $matches[3][0]), ' ');
  430. $out .= '</font><br/>';
  431. } elseif ($matches[2][0] == "O") {
  432. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  433. $out .= '<font color=green face=sans-serif>';
  434. $out .= $matches[3][0];
  435. $out .= '</font><br/>';
  436. } elseif ($matches[2][0] == "P") {
  437. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  438. $out .= '<font color=teal face=sans-serif>';
  439. $out .= join(split('路', $matches[3][0]), ' ');
  440. $out .= '</font><br/>';
  441. } elseif ($matches[2][0] == "W") {
  442. $out .= '<font color=grey>' . $date . '</font>&nbsp;';
  443. $out .= '<font color=orange face=sans-serif>';
  444. $out .= join(split('路', $matches[3][0]), ' ');
  445. $out .= '</font><br/>';
  446. } elseif ($matches[2][0] == "X") {
  447. $out .= '<font color=black face=sans-serif>' . sprintf(_T("Exit code : %s", "msc"), $matches[3][0]) . '</font>';
  448. }
  449. } else {
  450. $out .= '<font color=black face=sans-serif>' . $line . '</font>';
  451. }
  452. return $out;
  453. }
  454. function _toDate($a, $noneIsAsap = False) {
  455. $never = array(2031, 12, 31, 23, 59, 59);
  456. $asap = array(1970, 1, 1, 0, 0, 0);
  457. if (is_array($a) && (count($a) == 6 || count($a) == 9)) {
  458. if (count(array_diff(array_slice($a, 0, 6), $never)) == 0)
  459. return _T('Never', 'msc');
  460. if (count(array_diff(array_slice($a, 0, 6), $asap)) == 0)
  461. return _T('As soon as possible', 'msc');
  462. $parsed_date = mktime($a[3], $a[4], $a[5], $a[1], $a[2], $a[0]);
  463. return strftime(web_def_date_fmt(), $parsed_date);
  464. } elseif ($noneIsAsap && !$a) {
  465. return _T('As soon as possible', 'msc');
  466. } else { # can't guess if we talk about a date or something else :/
  467. return _T('<i>undefined</i>', 'msc');
  468. }
  469. }
  470. function _plusIcon($a) {
  471. $statusTable = getStatusTable();
  472. return sprintf('<img title="%s" alt="%s" src="modules/msc/graph/images/status/%s" />', $statusTable[$a], $a, return_icon($a));
  473. }