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 /* Check file accessibility */
67 if(!file_exists($this->s_queue_file)){
68 $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
69 return(FALSE);
70 }
71 if(!is_readable($this->s_queue_file)){
72 $this->set_error(sprintf(_("Can't read gotomasses queue file '%s'."),$this->s_queue_file));
73 return(FALSE);
74 }
76 /* Check if file contents could be read */
77 $fp = @fopen($this->s_queue_file,"r");
78 if(!$fp){
79 $this->set_error(sprintf(_("Can't read gotomasses storage file '%s'."),$this->s_queue_file));
80 return(FALSE);
81 }
82 $this->i_fileversion = filemtime($this->s_queue_file);
83 clearstatcache();
85 /* Get file contents */
86 $data ="";
87 while(!feof($fp)){
88 $data.= fread($fp,512);
89 }
91 /* Get lines from file */
92 $this->a_queue = array();
93 $comment = "";
94 $rows = split("\n",$data);
96 $used_ids = array();
98 /* Walk trough rows and parse data */
99 foreach($rows as $row){
101 /* Skip empty lines */
102 $row = trim($row);
103 if(empty($row)){
104 continue;
105 }
107 /* Get comment, if available */
108 if(preg_match("/^#/",$row)){
109 $comment = preg_replace("/^#/","",$row);
110 continue;
111 }
113 $entry_id = $taks_id= 0;
115 /* Comment must be set correctly */
116 if(empty($comment)){
117 $desc = "";
118 }else{
119 $task_id =preg_replace("/^.*taskid:([0-9]*).*$/","\\1",$comment);
120 $entry_id=preg_replace("/^.*entryid:([0-9]*).*$/","\\1",$comment);
121 $desc =preg_replace("/^.*desc:(.*)$/","\\1",$comment);
122 }
123 if($task_id == 0 || empty($task_id)){
124 $task_id = preg_replace("/[^0-9]*/","",microtime());
125 }
126 if($entry_id == 0 || empty($entry_id)){
127 $entry_id = preg_replace("/[^0-9]*/","",microtime());
128 }
130 /* Get unige id */
131 while(in_array($entry_id,$used_ids)){
132 $entry_id = preg_replace("/[^0-9]*/","",microtime());
133 }
134 $used_ids[] = $entry_id;
136 /* Split row into minutes/ hours ...*/
137 $row = preg_replace('/[\t ]/umi'," ",$row);
138 $row = preg_replace('/ */umi'," ",$row);
139 $parts = split(" ",$row);
141 if(count($parts) != 10){
142 print_red(_("Entry broken, skipped."));
143 }else{
145 $entry = array();
146 $entry['TASK_ID'] = $task_id;
147 $entry['ID'] = $entry_id;
148 $entry['Minute'] = $parts[0];
149 $entry['Hour'] = $parts[1];
150 $entry['Day'] = $parts[2];
151 $entry['Month'] = $parts[3];
152 $entry['Weekday'] = $parts[4];
153 $entry['Action'] = $parts[5];
154 $entry['OGroup'] = $parts[6];
155 $entry['Zone'] = $parts[7];
156 $entry['Section'] = $parts[8];
157 if($entry['Action'] == "initial_install"){
158 $tmp2 = split(";",$parts[9]);
159 foreach($tmp2 as $target){
160 $tmp = split(",",$target);
161 $entry['Initial_Target'][] = array(
162 "MAC" => $tmp[0],
163 "IP" => $tmp[1],
164 "NAME" => $tmp[2]);
165 }
166 $entry['Target'] = array();
167 }else{
168 $entry['Initial_Target'] = array();
169 $entry['Target'] = split(";",$parts[9]);
170 }
171 $entry['Comment'] = $desc;
172 $this->a_queue[] = $entry;
174 }
175 }
177 /* Udpate ENTRY_ID -> id mapping */
178 foreach($this->a_queue as $id => $entry){
179 $this->id_entry_map[$entry['ID']] = $id;
180 }
182 return(TRUE);
183 }
186 private function _save_data()
187 {
188 $this->_reset_error();
190 /* Check file accessibility */
191 if(!file_exists($this->s_queue_file)){
192 $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
193 return(FALSE);
194 }
195 if(!is_writeable($this->s_queue_file)){
196 $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
197 return(FALSE);
198 }
199 if($this->i_fileversion != filemtime($this->s_queue_file)){
200 $this->set_error(_("The queue file was modified since last reload. Can't save changes."));
201 return(FALSE);
202 }
203 $fp = @fopen($this->s_queue_file,"w");
204 if(!$fp){
205 $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
206 return(FALSE);
207 }
209 $str = "#GOsa generated file, please just modify if you really know what you do.";
210 foreach($this->a_queue as $task){
211 $str .= "\n#taskid:".trim($task['TASK_ID']).";entryid:".$task['ID'].";desc:".trim($task['Comment']);
212 $str .= "\n";
213 if($task['Action'] == "initial_install"){
214 $str .= "* * * * * ";
215 }else{
216 $str .= str_pad($task['Minute'] ,5," ")." ";
217 $str .= str_pad($task['Hour'] ,5," ")." ";
218 $str .= str_pad($task['Day'] ,5," ")." ";
219 $str .= str_pad($task['Month'] ,5," ")." ";
220 $str .= str_pad($task['Weekday'],5," ")." ";
221 }
222 $str .= str_pad($task['Action'] ,5," ")." ";
223 $str .= str_pad($task['OGroup'] ,5," ")." ";
224 $str .= str_pad($task['Zone'] ,5," ")." ";
225 $str .= str_pad($task['Section'],5," ")." ";
226 if($task['Action'] == "initial_install"){
227 foreach($task['Initial_Target'] as $target){
228 $str .= trim($target['MAC']).",".trim($target['IP']).",".trim($target['NAME']).";";
229 }
230 }else{
231 foreach($task['Target'] as $target){
232 $str .= $target.";";
233 }
234 }
235 $str = preg_replace("/;$/","",$str);
236 }
238 /* Write contents */
239 $str .= "\n";
240 fwrite($fp,$str);
241 fclose($fp);
242 clearstatcache();
243 $this->i_fileversion = filemtime($this->s_queue_file);
244 clearstatcache();
245 return(TRUE);
246 }
248 private function _add_entry($entry,$task_id = 0)
249 {
250 if($task_id == 0 || empty($task_id)){
251 $task_id=preg_replace("/[^0-9]*/","",microtime());
252 }
253 $entry['TASK_ID'] = $task_id;
254 if(!isset($entry['ID']) || empty($entry['ID']) || !isset($entry['ID']) || empty($entry['ID'])){
255 $entry['ID'] = preg_replace("/[^0-9]*/","",microtime());
256 }
257 $this->a_queue[] = $entry;
259 return(true);
260 }
262 public function get_entry($id)
263 {
264 if(isset($this->a_queue[$this->id_entry_map[$id]])){
265 return($this->a_queue[$this->id_entry_map[$id]]);
266 }else{
267 $this->set_error(sprintf(_("Entry with id '%s' not found."),$id));
268 }
269 }
271 public function update_entry($id,$entry)
272 {
273 if(isset($this->id_entry_map[$id])){
274 $this->a_queue[$this->id_entry_map[$id]] = $entry;
275 return($this->_save_data());
276 }else{
277 $this->set_error(sprintf(_("Could not update entry, entry with id '%s' not found."),$id));
278 }
279 }
281 public function remove_entry($id)
282 {
283 if(isset($this->id_entry_map[$id])){
284 unset($this->a_queue[$this->id_entry_map[$id]]);
285 unset($this->id_entry_map[$id]);
286 return($this->_save_data());
287 }else{
288 $this->set_error(sprintf(_("Could not remove entry, entry with id '%s' not found."),$id));
289 }
290 }
292 public function id_exists($id)
293 {
294 return(isset($this->id_entry_map[$id]));
295 }
298 public function add($entry)
299 {
300 if(!$this->_add_entry($entry)){
301 return(FALSE);
302 }
303 return($this->_save_data());
304 }
306 public function add_multiple($array)
307 {
308 $task_id = preg_replace("/[^0-9]*/","",microtime());
309 foreach($array as $entry){
310 if(!$this->_add_entry($entry,$task_id)){
311 return(FALSE);
312 }
313 }
314 return($this->_save_data());
315 }
317 public function fetch()
318 {
319 if(isset($this->a_queue[$this->i_pointer])){
320 $p = $this->a_queue[$this->i_pointer];
321 $this->i_pointer ++;
322 return($p);
323 }
324 return(FALSE);
325 }
327 public function load()
328 {
329 return($this->_reload_queue());
330 }
332 public function save()
333 {
334 return($this->_save_data());
335 }
337 private function _reset_error()
338 {
339 $this->b_error = FALSE;
340 $this->s_error = "";
341 }
343 private function set_error($str)
344 {
345 $this->b_error = TRUE;
346 $this->s_error = $str;
347 }
349 public function is_error()
350 {
351 return($this->b_error);
352 }
354 public function get_error()
355 {
356 return($this->s_error);
357 }
359 }
360 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
361 ?>