Code

0be94032ba0dceeaf7653de2608b72675b74d37e
[gosa.git] / gosa-core / include / class_gosaSupportDaemon.inc
1 <?php
2 /*
4    This code is part of GOsa (https://gosa.gonicus.de)
5    Copyright (C) 2008  Fabian Hickert
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 Function overview:
24    __construct              - Create a new deamon handle. 
25    connect                  - Connect to deamon socket.
26    disconnect               - Disconnect from socket.
27    set_error                - Sets a new error.
28    is_error                 - Returns TRUE if there was an error.
29    get_error                - Returns the last error or "".
30    get_queued_entries       - Returns all queued entries, with limitations.
31    ids_exist                - Checks if the given id exists.
32    get_entries_by_id        - Returns a set of entries.
33    id_exists                - Checks if a set entries exists.
34    get_entry_by_id          - Returns a single entry.
35    remove_entries           - Remove a set of entries.
36    remove_entry             - Removes a single entry.
37    update_entries           - Updates a set of entries.
38    xml_to_array             - XML to Array. 
39    number_of_queued_entries - Returns the number of currently queued entries.   
40 */
42 class gosaSupportDaemon
43 {
44   private $s_host       = "";
45   private $i_port       = 0;
46   private $s_encryption_key = "";
48   private $o_sock       = NULL;
49   private $f_timeout    = 2;
50   private $s_error      = "";
51   private $b_error      = FALSE;
53   private $is_connected     = FALSE;
56   /*! \brief  Creates a new gosaSupportDaemon object.
57     @param string   Host    The Host where the deamon is running on.  
58     @param integer  Port    The port which the deamon use.
59     @param string   Key     The encryption string.
60     @param boolean  Connect Directly connect to deamon socket.
61     @param float    Timeout The timelimit for all socket actions.
62    */
63   public function __construct($connect=TRUE,$timeout=0.2)
64   {
65     #FIXME: bad idea about referencing global variables from within classes
66     global $config;
68     # load from config, store statically
69     if (isset($config->current['GOSA_SI'])){
71       if ($this->s_host == ""){
72         $this->s_host= preg_replace("/^.*@([^:]+):.*$/", "$1", $config->current['GOSA_SI']);
73         $this->i_port= preg_replace("/^.*@[^:]+:(.*)$/", "$1", $config->current['GOSA_SI']);
74         $this->s_encryption_key = preg_replace("/^(.*)@[^:]+:.*$/", "$1", $config->current['GOSA_SI']);
75       }
77       $this->f_timeout = $timeout;
78       if($connect){
79         $this->connect();
80       }
81     }
82   }
85   /*! \brief  Establish deamon connection. 
86     @return boolean Returns true if the connection was succesfully established. 
87    */
88   public function connect()
89   {
90     $this->o_sock = new Socket_Client($this->s_host,$this->i_port,TRUE,$this->f_timeout);
91     if($this->o_sock->connected()){ 
92       $this->o_sock->setEncryptionKey($this->s_encryption_key); 
93       $this->is_connected = TRUE;
94     }else{
95       $this->error = $this->o_sock->get_error();
96       $this->disconnect();
97     }
98     return($this->is_connected);
99   }
102   /*! \brief  Disconnect from gosa deamon.
103    */
104   public function disconnect()
105   {
106     $this->o_sock->close();
107     $this->is_connected = FALSE;
108   }
111   /*! \brief  Sets an error message, which can be returned with get_error().
112     @param  string  The Error message,
113    */
114   private function set_error($str)
115   {
116     $this->b_error = TRUE;
117     $this->s_error = $str;
118   }
121   /*! \brief  Checks if an error occured.
122     @return boolean returns TRUE or FALSE, whether there is an error or not.
123    */
124   public function is_error()
125   {
126     return($this->b_error);
127   }
130   /*! \brief  Returns the last error. 
131     @return Returns the last error.
132    */
133   public function get_error()
134   {
135     return($this->s_error);
136   }
139   /*! \brief  Returns an array containing all queued entries.
140     @return Array All queued entries as an array.
141    */
142   public function get_queued_entries($from=0,$to=10,$sort="timestamp DESC")
143   {
144     $this->b_error = FALSE;
145     $this->s_error = "";
146     $ret = array();
148     $xml_msg = "<xml>
149       <header>gosa_query_jobdb</header>
150       <where>
151       <clause>
152         <phrase>
153         <operator>ne</operator>
154         <HEADERTAG>*</HEADERTAG>
155         </phrase>
156       </clause>
157       </where>
158       <orderby>".$sort."</orderby>
159       <limit>
160       <from>".$from."</from>
161       <to>".$to."</to>
162       </limit>
163       </xml>";
165     if($this->connect()){
166       $this->o_sock->write($xml_msg);
167       $str = trim($this->o_sock->read());
168       $entries = $this->xml_to_array($str);
169       if(isset($entries['XML']) && is_array($entries['XML'])){
171         /* Check if returned values represent a valid answer */
172         if($entries['XML']['HEADER'] == "answer"){
173           
174           /* Unset header tags */
175           foreach(array("HEADER","SOURCE","TARGET") as $type){
176             unset($entries['XML'][$type]);
177           }
178           $ret = $entries; 
179         }
180       }
181     }
182     
183     return($ret);
184   }
187   /*! \brief  Checks if the given ids are used queue ids.
188     @param  Array   The ids we want to check..
189     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
190    */
191   public function ids_exist($ids)
192   {
193     if(!is_array($ids)){
194       trigger_error("Requires an array as parameter.");
195       return;
196     }
197     $this->b_error = FALSE;
198     $this->s_error = "";
200     $ret = array();
202     $xml_msg = "<xml>
203       <header>gosa_query_jobdb</header>
204       <where>
205       <clause>
206       <connector>or</connector>";
207     foreach($ids as $id){
208       $xml_msg .= "<phrase>
209         <operator>eq</operator>
210         <id>".$id."</id>
211         </phrase>";
212     }
213     $xml_msg .= "</clause>
214       </where>
215       </xml>";
217     if($this->connect()){
218       $this->o_sock->write($xml_msg);
219       $str = trim($this->o_sock->read());
220       $entries = $this->xml_to_array($str);
221       if(isset($entries['XML']) && is_array($entries['XML'])){
222         foreach($entries['XML'] as $entry){
223           if(isset($entry['ID'])){
224             $ret[] = $entry['ID'];
225           }
226         }
227       }
228     }
229     return($ret);
230   }
233   /*! \brief  Returns an entry containing all requested ids.
234     @param  Array   The IDs of the entries we want to return.
235     @return Array   Of the requested entries. 
236    */
237   public function get_entries_by_id($ids)
238   {
239     if(!is_array($ids)){
240       trigger_error("Requires an array as parameter.");
241       return;
242     }
243     $this->b_error = FALSE;
244     $this->s_error = "";
246     $ret = array();
248     $xml_msg = "<xml>
249       <header>gosa_query_jobdb</header>
250       <where>
251       <clause>
252       <connector>or</connector>";
253     foreach($ids as $id){
254       $xml_msg .= "<phrase>
255         <operator>eq</operator>
256         <id>".$id."</id>
257         </phrase>";
258     }
259     $xml_msg .= "</clause>
260       </where>
261       </xml>";
263     if($this->connect()){
264       $this->o_sock->write($xml_msg);
265       $str = trim($this->o_sock->read());
266       $entries = $this->xml_to_array($str); 
267       if(isset($entries['XML'])){
268         foreach($entries['XML'] as $name => $entry){
269           if(preg_match("/^ANSWER[0-9]*$/",$name)){
270             $ret[$name] = $entry;
271           }
272         }
273       }
274     }
275     return($ret);
276   }
279   /*! \brief  Checks if the given id is in use.
280     @param  Integer The ID of the entry.
281     @return Boolean TRUE if entry exists. 
282    */
283   public function id_exists($id)
284   {
285     if(!is_numeric($id)){
286       trigger_error("Requires an integer as parameter.");
287       return;
288     }
290     $this->b_error = FALSE;
291     $this->s_error = "";
292     $xml_msg = "<xml>
293       <header>gosa_query_jobdb</header>
294       <where>
295       <clause>
296       <phrase>
297       <operator>eq</operator>
298       <id>".$id."</id>
299       </phrase>
300       </clause>
301       </where>
302       </xml>";
304     if($this->connect()){
305       $this->o_sock->write($xml_msg);
306       $str = trim($this->o_sock->read());
307       $entries = $this->xml_to_array($str); 
308       if( isset($entries['XML']['HEADER']) && 
309           $entries['XML']['HEADER']=="answer" && 
310           isset($entries['XML']['ANSWER1'])){
311         return(TRUE);
312       }
313     }
314     return(FALSE);
315   }
318   /*! \brief  Returns an entry from the gosaSupportQueue
319     @param  Integer The ID of the entry we want to return.
320     @return Array   Of the requested entry. 
321    */
322   public function get_entry_by_id($id)
323   {
324     if(!is_numeric($id)){
325       trigger_error("Requires an integer as parameter.");
326       return;
327     }
328   
329     $this->b_error = FALSE;
330     $this->s_error = "";
331     $ret = array();
332     $xml_msg = "<xml>
333       <header>gosa_query_jobdb</header>
334       <where>
335       <clause>
336       <phrase>
337       <operator>eq</operator>
338       <id>".$id."</id>
339       </phrase>
340       </clause>
341       </where>
342       </xml>";
343     if($this->connect()){
344       $this->o_sock->write($xml_msg);
345       $str = trim($this->o_sock->read());
346       $entries = $this->xml_to_array($str); 
347       if( isset($entries['XML']['HEADER']) &&
348           $entries['XML']['HEADER']=="answer" &&
349           isset($entries['XML']['ANSWER1'])){
350         $ret = $entries['XML']['ANSWER1'];
351       }
352     }
353     return($ret);
354   }
357   /*! \brief  Removes a set of entries from the GOsa support queue. 
358     @param  Array The IDs to remove.
359     @return Boolean True on success.
360    */
361   public function remove_entries($ids)
362   {
363     if(!is_array($ids)){
364       trigger_error("Requires an array as parameter.");
365       return;
366     }
367     $this->b_error = FALSE;
368     $this->s_error = "";
370     $ret = array();
372     $xml_msg = "<xml>
373       <header>gosa_delete_jobdb_entry</header>
374       <where>
375       <clause>
376       <connector>or</connector>";
377     foreach($ids as $id){
378       $xml_msg .= "<phrase>
379         <operator>eq</operator>
380         <id>".$id."</id>
381         </phrase>";
382     }
383     $xml_msg .= "</clause>
384       </where>
385       </xml>";
386     $this->b_error = FALSE;
387     $this->s_error = "";
389     if($this->connect()){
390       $this->o_sock->write($xml_msg);
391       $str = $this->o_sock->read();
392       $entries = $this->xml_to_array($str);
393       if(isset($entries['XML'])){
394         return(TRUE);
395       }
396     }
397     return(FALSE);
398   }
402   /*! \brief  Removes an entry from the GOsa support queue. 
403     @param  Integer The ID of the entry we want to remove.
404     @return Boolean True on success.
405    */
406   public function remove_entry($id)
407   {
408     $this->b_error = FALSE;
409     $this->s_error = "";
411     $xml_msg = "<xml>
412       <header>gosa_delete_jobdb_entry</header>
413       <where>
414       <clause>
415       <phrase>
416       <operator>eq</operator>
417       <id>".$id."</id>
418       </phrase>
419       </clause>
420       </where>
421       </xml>";
422     if($this->connect()){
423       $this->o_sock->write($xml_msg);
424       $str = $this->o_sock->read();
425       $entries = $this->xml_to_array($str);
426       if(isset($entries['XML'])){
427         return(TRUE);
428       }
429     }
430     return(FALSE);
431   }
434   /*! \brief  Parses the given xml string into an array 
435     @param  String XML string  
436     @return Array Returns an array containing the xml structure. 
437    */
438   public function xml_to_array($xml)
439   {
440     $params = array();
441     $level = array();
442     $parser  = xml_parser_create_ns();
443     xml_parse_into_struct($parser, $xml, $vals, $index);
445     $err_id = xml_get_error_code($parser);
446     if($err_id){
447       xml_parser_free($parser);
448     }else{
449       xml_parser_free($parser);
451       foreach ($vals as $xml_elem) {
452         if ($xml_elem['type'] == 'open') {
453           if (array_key_exists('attributes',$xml_elem)) {
454             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
455           } else {
456             $level[$xml_elem['level']] = $xml_elem['tag'];
457           }
458         }
459         if ($xml_elem['type'] == 'complete') {
460           $start_level = 1;
461           $php_stmt = '$params';
462           while($start_level < $xml_elem['level']) {
463             $php_stmt .= '[$level['.$start_level.']]';
464             $start_level++;
465           }
466           $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
467           @eval($php_stmt);
468         }
469       }
470     }
472     if(!isset($params['XML'])){
473       if (!array_key_exists('XML', $params)){
474         $this->set_error(_("Could not parse XML."));
475       }
476       $params = array("COUNT" => 0);
477     }
479     return($params); 
480   }
483   /*! \brief  Updates an entry with a set of new values, 
484     @param  Integer The ID of the entry, we want to update.
485     @param  Array   The variables to update.   
486     @return Boolean Returns TRUE on success. 
487    */
488   public function update_entries($ids,$entry)
489   {
490     $this->b_error = FALSE;
491     $this->s_error = "";
492     if(!is_array($ids)){
493       trigger_error("Requires an array as first parameter.");
494       return;
495     }
497     if(!is_array($entry)){
498       trigger_error("Requires an array as second parameter.");
499       return;
500     }
502     $attr = "";
503     foreach($entry as $name => $entry){
504       $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
505     }
506     $xml_msg = "<xml>
507       <header>gosa_update_status_jobdb_entry</header>
508       <where>
509       <clause>
510       <connector>or</connector>";
511     foreach($ids as $id){
512       $xml_msg .= "<phrase>
513         <operator>eq</operator>
514         <id>".$id."</id>
515         </phrase>";
516     }
517     $xml_msg .= "</clause>
518       </where>
519       <update>
520       ".$attr." 
521       </update>
522       </xml>";
523     if($this->connect()){
524       $this->o_sock->write($xml_msg);
525       $str      = trim($this->o_sock->read());
526       $entries = $this->xml_to_array($str);
527       if(isset($entries['XML'])){
528         return(TRUE);
529       }
530     }
531     return(FALSE);
532   }
535   /*! \brief  Returns the number of currently queued objects.
536       @return Integer  
537    */
538   public function number_of_queued_entries()
539   {
540     $xml_msg ="<xml><header>gosa_count_jobdb</header></xml>";
541     $this->connect();
542     if($this->connect()){
543       $this->o_sock->write($xml_msg);
544       $str     = trim($this->o_sock->read());
545       $entries = $this->xml_to_array($str);
546       if(isset($entries['XML'])){
547         return($entries['XML']['COUNT']);
548       }
549     }
550     return(-1);
551   } 
554   /*! \brief  Returns an array containing all queued entries.
555     @return Array All queued entries as an array.
556    */
557   public function _send($data, $answer_expected= FALSE)
558   {
559     $this->b_error = FALSE;
560     $this->s_error = "";
561     $ret = array();
563     if($this->connect()){
564       $this->o_sock->write($data);
565       if ($answer_expected){
566         $str = trim($this->o_sock->read());
567         $entries = $this->xml_to_array($str);
568         if(isset($entries['XML']) && is_array($entries['XML'])){
569           $ret = $entries; 
570         }
571       }
572     }
573     return($ret);
574   }
577   static function send($header, $to, $data= array())
578   {
579     $xml_message= "";
581     /* Get communication object */
582     $d= new gosaSupportDaemon(TRUE,10);
584     /* Prepare data */
585     foreach ($data as $key => $value){
586       $xml_message.= "<$key>$value</$key>";
587     }
589     return $d->_send("<xml><header>$header</header><source>GOSA</source><target>$to</target>".$xml_message."</xml>");
590   }
593   static function ping($target)
594   {
595     if (tests::is_mac($target)){
596     /* Get communication object */
597         $d= new gosaSupportDaemon(TRUE,0.5);
599         $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
600         return (count($answer) ? TRUE:FALSE);
601     }
603     return (FALSE);
604   }
608 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
609 ?>