1 <?php
2 /*
3 This code is part of GOsa (https://gosa.gonicus.de)
4 Copyright (C) 2007 Fabian Hickert
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
22 /*!
23 \brief This class represents the host action queue.
24 \author Fabian Hickert <hickert@gonicus.de>
25 \version 2.6
26 \date 24.10.2007
28 This class is a queue handler, which allows adding,removing,
29 priority settings,stop and resume actions... for each queue entry
30 */
31 class hostActionQueue {
33 private $o_config = NULL;
34 private $s_queue_file = "";
35 private $s_error = "";
36 private $b_error = FALSE;
38 private $a_queue = array();
39 private $i_pointer = 0;
40 private $b_queue_loaded = false;
41 private $i_fileversion = 0;
43 private $id_entry_map = array();
45 public function __construct($config)
46 {
47 $this->o_config= $config;
49 /* Define source file */
50 $this->s_queue_file = CONFIG_DIR."/gotomasses_machines";
52 $file = $this->o_config->search("gotomasses", "STORAGE_FILE",array('menu'));
53 if(!empty($file)){
54 $this->s_queue_file = $file;
55 }
56 }
58 private function _reload_queue()
59 {
60 $this->_reset_error();
61 $this->b_queue_loaded = FALSE;
62 $this->b_error = FALSE;
63 $this->s_error = "";
64 $this->i_pointer = 0;
66 $this->get_new_id();
68 /* Check file accessibility */
69 if(!file_exists($this->s_queue_file)){
70 $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
71 return(FALSE);
72 }
73 if(!is_readable($this->s_queue_file)){
74 $this->set_error(sprintf(_("Can't read gotomasses queue file '%s'."),$this->s_queue_file));
75 return(FALSE);
76 }
78 /* Check if file contents could be read */
79 $fp = @fopen($this->s_queue_file,"r");
80 if(!$fp){
81 $this->set_error(sprintf(_("Can't read gotomasses storage file '%s'."),$this->s_queue_file));
82 return(FALSE);
83 }
84 $this->i_fileversion = filemtime($this->s_queue_file);
85 clearstatcache();
87 /* Get file contents */
88 $data ="";
89 while(!feof($fp)){
90 $data.= fread($fp,512);
91 }
93 /* Get lines from file */
94 $this->a_queue = array();
95 $comment = "";
96 $rows = split("\n",$data);
98 $used_ids = array();
100 /* Walk trough rows and parse data */
101 foreach($rows as $row){
103 /* Skip empty lines */
104 $row = trim($row);
105 if(empty($row)){
106 continue;
107 }
109 /* Get comment, if available */
110 if(preg_match("/^#/",$row)){
111 $comment = preg_replace("/^#/","",$row);
112 continue;
113 }
115 $entry_id = $task_id= 0;
117 /* Comment must be set correctly */
118 if(empty($comment)){
119 $desc = "";
120 }else{
121 $task_id =preg_replace("/^.*taskid:([0-9]*).*$/","\\1",$comment);
122 $entry_id=preg_replace("/^.*entryid:([0-9]*).*$/","\\1",$comment);
123 $desc =preg_replace("/^.*desc:(.*)$/","\\1",$comment);
124 }
125 if($task_id == 0 || empty($task_id)){
126 $task_id = preg_replace("/[^0-9]*/","",microtime());
127 }
128 if($entry_id == 0 || empty($entry_id)){
129 $entry_id = preg_replace("/[^0-9]*/","",microtime());
130 }
132 /* Get unige id */
133 while(in_array($entry_id,$used_ids)){
134 $entry_id = preg_replace("/[^0-9]*/","",microtime());
135 }
136 $used_ids[] = $entry_id;
138 /* Split row into minutes/ hours ...*/
139 $row = preg_replace('/[\t ]/umi'," ",$row);
140 $row = preg_replace('/ */umi'," ",$row);
141 $parts = split(" ",$row);
143 if(count($parts) != 10){
144 print_red(_("Entry broken, skipped."));
145 }else{
147 $entry = array();
148 $entry['TASK_ID'] = $task_id;
149 $entry['ID'] = $entry_id;
150 $entry['Minute'] = $parts[0];
151 $entry['Hour'] = $parts[1];
152 $entry['Day'] = $parts[2];
153 $entry['Month'] = $parts[3];
154 $entry['Weekday'] = $parts[4];
155 $entry['Action'] = $parts[5];
156 $entry['OGroup'] = $parts[6];
157 $entry['Zone'] = $parts[7];
158 $entry['Section'] = $parts[8];
159 if($entry['Action'] == "initial_install"){
160 $tmp2 = split(";",$parts[9]);
161 foreach($tmp2 as $target){
162 $tmp = split(",",$target);
163 $entry['Initial_Target'][] = array(
164 "MAC" => $tmp[0],
165 "IP" => $tmp[1],
166 "NAME" => $tmp[2]);
167 }
168 $entry['Target'] = array();
169 }else{
170 $entry['Initial_Target'] = array();
171 $entry['Target'] = split(";",$parts[9]);
172 }
173 $entry['Comment'] = $desc;
174 $this->a_queue[] = $entry;
176 }
177 }
179 /* Udpate ENTRY_ID -> id mapping */
180 reset($this->a_queue);
181 foreach($this->a_queue as $id => $entry){
182 $this->id_entry_map[$entry['ID']] = $id;
183 }
185 return(TRUE);
186 }
189 private function _save_data()
190 {
191 $this->_reset_error();
193 /* Check file accessibility */
194 if(!file_exists($this->s_queue_file)){
195 $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
196 return(FALSE);
197 }
198 if(!is_writeable($this->s_queue_file)){
199 $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
200 return(FALSE);
201 }
202 if($this->i_fileversion != filemtime($this->s_queue_file)){
203 $this->set_error(_("The queue file was modified since last reload. Can't save changes."));
204 return(FALSE);
205 }
206 $fp = @fopen($this->s_queue_file,"w");
207 if(!$fp){
208 $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
209 return(FALSE);
210 }
212 $str = "#GOsa generated file, please just modify if you really know what you do.";
213 reset($this->a_queue);
214 foreach($this->a_queue as $task){
215 $str .= "\n#taskid:".trim($task['TASK_ID']).";entryid:".$task['ID'].";desc:".trim($task['Comment']);
216 $str .= "\n";
217 if($task['Action'] == "initial_install"){
218 $str .= "* * * * * ";
219 }else{
220 $str .= str_pad($task['Minute'] ,5," ")." ";
221 $str .= str_pad($task['Hour'] ,5," ")." ";
222 $str .= str_pad($task['Day'] ,5," ")." ";
223 $str .= str_pad($task['Month'] ,5," ")." ";
224 $str .= str_pad($task['Weekday'],5," ")." ";
225 }
226 $str .= str_pad($task['Action'] ,5," ")." ";
227 $str .= str_pad($task['OGroup'] ,5," ")." ";
228 $str .= str_pad($task['Zone'] ,5," ")." ";
229 $str .= str_pad($task['Section'],5," ")." ";
230 if($task['Action'] == "initial_install"){
231 foreach($task['Initial_Target'] as $target){
232 $str .= trim($target['MAC']).",".trim($target['IP']).",".trim($target['NAME']).";";
233 }
234 }else{
235 foreach($task['Target'] as $target){
236 $str .= $target.";";
237 }
238 }
239 $str = preg_replace("/;$/","",$str);
240 }
242 /* Write contents */
243 $str .= "\n";
244 fwrite($fp,$str);
245 fclose($fp);
246 clearstatcache();
247 $this->i_fileversion = filemtime($this->s_queue_file);
248 clearstatcache();
250 /* Update ENTRY_ID -> id mapping */
251 reset($this->a_queue);
252 foreach($this->a_queue as $id => $entry){
253 $this->id_entry_map[$entry['ID']] = $id;
254 }
256 return(TRUE);
257 }
259 private function _add_entry($entry,$task_id = 0)
260 {
261 if($task_id == 0 || empty($task_id)){
262 $task_id=preg_replace("/[^0-9]*/","",microtime());
263 }
264 $entry['TASK_ID'] = $task_id;
265 if(!isset($entry['ID']) || empty($entry['ID']) || !isset($entry['ID']) || empty($entry['ID'])){
266 $entry['ID'] = preg_replace("/[^0-9]*/","",microtime());
267 }
268 $this->a_queue[] = $entry;
270 return(true);
271 }
273 public function get_entry($id)
274 {
275 if(isset($this->a_queue[$this->id_entry_map[$id]])){
276 return($this->a_queue[$this->id_entry_map[$id]]);
277 }else{
278 $this->set_error(sprintf(_("Entry with id '%s' not found."),$id));
279 }
280 }
282 public function update_entry($id,$entry)
283 {
284 if(isset($this->id_entry_map[$id])){
285 $this->a_queue[$this->id_entry_map[$id]] = $entry;
286 return($this->_save_data());
287 }else{
288 $this->set_error(sprintf(_("Could not update entry, entry with id '%s' not found."),$id));
289 }
290 }
292 public function remove_entry($id)
293 {
294 if(isset($this->id_entry_map[$id])){
295 unset($this->a_queue[$this->id_entry_map[$id]]);
296 unset($this->id_entry_map[$id]);
297 return($this->_save_data());
298 }else{
299 $this->set_error(sprintf(_("Could not remove entry, entry with id '%s' not found."),$id));
300 }
301 }
303 public function id_exists($id)
304 {
305 return(isset($this->id_entry_map[$id]));
306 }
309 public function add($entry)
310 {
311 if(!$this->_add_entry($entry)){
312 return(FALSE);
313 }
314 return($this->_save_data());
315 }
317 public function add_multiple($array)
318 {
319 $task_id = preg_replace("/[^0-9]*/","",microtime());
320 foreach($array as $entry){
321 if(!$this->_add_entry($entry,$task_id)){
322 return(FALSE);
323 }
324 }
325 return($this->_save_data());
326 }
328 public function fetch()
329 {
330 if(isset($this->a_queue[$this->i_pointer])){
331 $p = $this->a_queue[$this->i_pointer];
332 $this->i_pointer ++;
333 return($p);
334 }
335 return(FALSE);
336 }
338 public function load()
339 {
340 return($this->_reload_queue());
341 }
343 public function save()
344 {
345 return($this->_save_data());
346 }
348 private function _reset_error()
349 {
350 $this->b_error = FALSE;
351 $this->s_error = "";
352 }
354 private function set_error($str)
355 {
356 $this->b_error = TRUE;
357 $this->s_error = $str;
358 }
360 public function is_error()
361 {
362 return($this->b_error);
363 }
365 public function get_error()
366 {
367 return($this->s_error);
368 }
370 public function max_entry_priority($id)
371 {
372 if(!$this->id_exists($id)){
373 $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
374 return(FALSE);
375 }
376 $tmp = array();
377 $tmp[]= $this->get_entry($id);
378 reset($this->a_queue);
379 foreach($this->a_queue as $key => $entry){
380 if($id != $entry['ID']){
381 $tmp[] = $entry;
382 }
383 }
384 $this->a_queue=$tmp;
385 return($this->_save_data());
386 }
388 public function increase_entry_priority($id)
389 {
390 if(!$this->id_exists($id)){
391 $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
392 return(FALSE);
393 }
394 $tmp = array();
395 $skip = NULL;
396 $next = NULL;
397 reset($this->a_queue);
398 foreach($this->a_queue as $key => $entry){
399 if($next != NULL){
400 if($id == $entry['ID']){
401 $tmp[] = $entry;
402 $tmp[] = $next;
403 $next = NULL;
404 }else{
405 $tmp[] = $next;
406 $next = $entry;
407 }
408 }else{
409 $next = $entry;
410 }
411 }
412 if($next != NULL){
413 $tmp[] = $next;
414 }
415 $this->a_queue=$tmp;
416 return($this->_save_data());
417 }
419 public function decrease_entry_priority($id)
420 {
421 if(!$this->id_exists($id)){
422 $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
423 return(FALSE);
424 }
425 $tmp = array();
426 $skip = NULL;
427 reset($this->a_queue);
428 foreach($this->a_queue as $key => $entry){
429 if($id != $entry['ID']){
430 $tmp[] = $entry;
431 if($skip != NULL){
432 $tmp[] = $skip;
433 $skip = NULL;
434 }
435 }else{
436 $skip = $entry;
437 }
438 }
439 if($skip != NULL){
440 $tmp[] = $skip;
441 }
442 $this->a_queue=$tmp;
443 return($this->_save_data());
444 }
446 private function get_new_id()
447 {
448 }
450 public function min_entry_priority($id)
451 {
452 if(!$this->id_exists($id)){
453 $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
454 return(FALSE);
455 }
456 reset($this->a_queue);
457 $tmp = array();
458 foreach($this->a_queue as $key => $entry){
459 if($id != $entry['ID']){
460 $tmp[] = $entry;
461 }
462 }
463 $tmp[]= $this->get_entry($id);
464 $this->a_queue=$tmp;
465 return($this->_save_data());
466 }
467 }
468 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
469 ?>