Code

a657419d6303eee9825965a2763d44630f13bd5a
[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->s_error = $this->o_sock->get_error();
96       $this->b_error = TRUE;
97       $this->disconnect();
98     }
99     return($this->is_connected);
100   }
103   /*! \brief  Disconnect from gosa deamon.
104    */
105   public function disconnect()
106   {
107     $this->o_sock->close();
108     $this->is_connected = FALSE;
109   }
112   /*! \brief  Sets an error message, which can be returned with get_error().
113     @param  string  The Error message,
114    */
115   private function set_error($str)
116   {
117     $this->b_error = TRUE;
118     $this->s_error = $str;
119   }
122   /*! \brief  Checks if an error occured.
123     @return boolean returns TRUE or FALSE, whether there is an error or not.
124    */
125   public function is_error()
126   {
127     return($this->b_error);
128   }
131   /*! \brief  Returns the last error. 
132     @return Returns the last error.
133    */
134   public function get_error()
135   {
136     return($this->s_error);
137   }
140   /*! \brief  Returns an array containing all queued entries.
141     @return Array All queued entries as an array.
142    */
143   public function get_queued_entries($from=-1,$to=-1,$sort="timestamp DESC")
144   {
145     $this->b_error = FALSE;
146     $this->s_error = "";
147     $ret = array();
149     $xml_msg = "<xml>
150       <header>gosa_query_jobdb</header>
151       <where>
152       <clause>
153         <phrase>
154         <operator>ne</operator>
155         <HEADERTAG>*</HEADERTAG>
156         </phrase>
157       </clause>
158       </where>
159       <orderby>".$sort."</orderby>";
160 if($from != -1 && $to != -1){
161 $xml_msg.= "
162       <limit>
163        <from>".$from."</from>
164        <to>".$to."</to>
165       </limit>";
167 $xml_msg.= "
168       </xml>";
170     if($this->connect()){
171       $this->o_sock->write($xml_msg);
172       $str = trim($this->o_sock->read());
173       $entries = $this->xml_to_array($str);
174       if(isset($entries['XML']) && is_array($entries['XML'])){
176         /* Check if returned values represent a valid answer */
177         if($entries['XML']['HEADER'] == "answer"){
178           
179           /* Unset header tags */
180           foreach(array("HEADER","SOURCE","TARGET") as $type){
181             unset($entries['XML'][$type]);
182           }
183           $ret = $entries['XML']; 
184         }
185       }
186     }
187     
188     return($ret);
189   }
192   /*! \brief  Checks if the given ids are used queue ids.
193     @param  Array   The ids we want to check..
194     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
195    */
196   public function ids_exist($ids)
197   {
198     if(!is_array($ids)){
199       trigger_error("Requires an array as parameter.");
200       return;
201     }
202     $this->b_error = FALSE;
203     $this->s_error = "";
205     $ret = array();
207     $xml_msg = "<xml>
208       <header>gosa_query_jobdb</header>
209       <where>
210       <clause>
211       <connector>or</connector>";
212     foreach($ids as $id){
213       $xml_msg .= "<phrase>
214         <operator>eq</operator>
215         <id>".$id."</id>
216         </phrase>";
217     }
218     $xml_msg .= "</clause>
219       </where>
220       </xml>";
222     if($this->connect()){
223       $this->o_sock->write($xml_msg);
224       $str = trim($this->o_sock->read());
225       $entries = $this->xml_to_array($str);
226       if(isset($entries['XML']) && is_array($entries['XML'])){
227         foreach($entries['XML'] as $entry){
228           if(isset($entry['ID'])){
229             $ret[] = $entry['ID'];
230           }
231         }
232       }
233     }
234     return($ret);
235   }
238   /*! \brief  Returns an entry containing all requested ids.
239     @param  Array   The IDs of the entries we want to return.
240     @return Array   Of the requested entries. 
241    */
242   public function get_entries_by_id($ids)
243   {
244     if(!is_array($ids)){
245       trigger_error("Requires an array as parameter.");
246       return;
247     }
248     $this->b_error = FALSE;
249     $this->s_error = "";
251     $ret = array();
253     $xml_msg = "<xml>
254       <header>gosa_query_jobdb</header>
255       <where>
256       <clause>
257       <connector>or</connector>";
258     foreach($ids as $id){
259       $xml_msg .= "<phrase>
260         <operator>eq</operator>
261         <id>".$id."</id>
262         </phrase>";
263     }
264     $xml_msg .= "</clause>
265       </where>
266       </xml>";
268     if($this->connect()){
269       $this->o_sock->write($xml_msg);
270       $str = trim($this->o_sock->read());
271       $entries = $this->xml_to_array($str); 
272       if(isset($entries['XML'])){
273         foreach($entries['XML'] as $name => $entry){
274           if(preg_match("/^ANSWER[0-9]*$/",$name)){
275             $ret[$name] = $entry;
276           }
277         }
278       }
279     }
280     return($ret);
281   }
284   /*! \brief  Checks if the given id is in use.
285     @param  Integer The ID of the entry.
286     @return Boolean TRUE if entry exists. 
287    */
288   public function id_exists($id)
289   {
290     if(!is_numeric($id)){
291       trigger_error("Requires an integer as parameter.");
292       return;
293     }
295     $this->b_error = FALSE;
296     $this->s_error = "";
297     $xml_msg = "<xml>
298       <header>gosa_query_jobdb</header>
299       <where>
300       <clause>
301       <phrase>
302       <operator>eq</operator>
303       <id>".$id."</id>
304       </phrase>
305       </clause>
306       </where>
307       </xml>";
309     if($this->connect()){
310       $this->o_sock->write($xml_msg);
311       $str = trim($this->o_sock->read());
312       $entries = $this->xml_to_array($str); 
313       if( isset($entries['XML']['HEADER']) && 
314           $entries['XML']['HEADER']=="answer" && 
315           isset($entries['XML']['ANSWER1'])){
316         return(TRUE);
317       }
318     }
319     return(FALSE);
320   }
323   /*! \brief  Returns an entry from the gosaSupportQueue
324     @param  Integer The ID of the entry we want to return.
325     @return Array   Of the requested entry. 
326    */
327   public function get_entry_by_id($id)
328   {
329     if(!is_numeric($id)){
330       trigger_error("Requires an integer as parameter.");
331       return;
332     }
333   
334     $this->b_error = FALSE;
335     $this->s_error = "";
336     $ret = array();
337     $xml_msg = "<xml>
338       <header>gosa_query_jobdb</header>
339       <where>
340       <clause>
341       <phrase>
342       <operator>eq</operator>
343       <id>".$id."</id>
344       </phrase>
345       </clause>
346       </where>
347       </xml>";
348     if($this->connect()){
349       $this->o_sock->write($xml_msg);
350       $str = trim($this->o_sock->read());
351       $entries = $this->xml_to_array($str); 
352       if( isset($entries['XML']['HEADER']) &&
353           $entries['XML']['HEADER']=="answer" &&
354           isset($entries['XML']['ANSWER1'])){
355         $ret = $entries['XML']['ANSWER1'];
356       }
357     }
358     return($ret);
359   }
362   /*! \brief  Removes a set of entries from the GOsa support queue. 
363     @param  Array The IDs to remove.
364     @return Boolean True on success.
365    */
366   public function remove_entries($ids)
367   {
368     if(!is_array($ids)){
369       trigger_error("Requires an array as parameter.");
370       return;
371     }
372     $this->b_error = FALSE;
373     $this->s_error = "";
375     $ret = array();
377     $xml_msg = "<xml>
378       <header>gosa_delete_jobdb_entry</header>
379       <where>
380       <clause>
381       <connector>or</connector>";
382     foreach($ids as $id){
383       $xml_msg .= "<phrase>
384         <operator>eq</operator>
385         <id>".$id."</id>
386         </phrase>";
387     }
388     $xml_msg .= "</clause>
389       </where>
390       </xml>";
391     $this->b_error = FALSE;
392     $this->s_error = "";
394     if($this->connect()){
395       $this->o_sock->write($xml_msg);
396       $str = $this->o_sock->read();
397       $entries = $this->xml_to_array($str);
398       if(isset($entries['XML'])){
399         return(TRUE);
400       }
401     }
402     return(FALSE);
403   }
407   /*! \brief  Removes an entry from the GOsa support queue. 
408     @param  Integer The ID of the entry we want to remove.
409     @return Boolean True on success.
410    */
411   public function remove_entry($id)
412   {
413     $this->b_error = FALSE;
414     $this->s_error = "";
416     $xml_msg = "<xml>
417       <header>gosa_delete_jobdb_entry</header>
418       <where>
419       <clause>
420       <phrase>
421       <operator>eq</operator>
422       <id>".$id."</id>
423       </phrase>
424       </clause>
425       </where>
426       </xml>";
427     if($this->connect()){
428       $this->o_sock->write($xml_msg);
429       $str = $this->o_sock->read();
430       $entries = $this->xml_to_array($str);
431       if(isset($entries['XML'])){
432         return(TRUE);
433       }
434     }
435     return(FALSE);
436   }
439   /*! \brief  Parses the given xml string into an array 
440     @param  String XML string  
441     @return Array Returns an array containing the xml structure. 
442    */
443   private function xml_to_array($xml)
444   {
445     $params = array();
446     $level = array();
447     $parser  = xml_parser_create_ns();
448     xml_parse_into_struct($parser, $xml, $vals, $index);
450     $err_id = xml_get_error_code($parser);
451     if($err_id){
452       xml_parser_free($parser);
453     }else{
454       xml_parser_free($parser);
456       foreach ($vals as $xml_elem) {
457         if ($xml_elem['type'] == 'open') {
458           if (array_key_exists('attributes',$xml_elem)) {
459             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
460           } else {
461             $level[$xml_elem['level']] = $xml_elem['tag'];
462           }
463         }
464         if ($xml_elem['type'] == 'complete') {
465           $start_level = 1;
466           $php_stmt = '$params';
467           while($start_level < $xml_elem['level']) {
468             $php_stmt .= '[$level['.$start_level.']]';
469             $start_level++;
470           }
471           $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
472           @eval($php_stmt);
473         }
474       }
475     }
477     if(!isset($params['XML'])){
478       if (!array_key_exists('XML', $params)){
479         $this->set_error(_("Could not parse XML."));
480       }
481       $params = array("COUNT" => 0);
482     }
484     return($params); 
485   }
488   /*! \brief  Updates an entry with a set of new values, 
489     @param  Integer The ID of the entry, we want to update.
490     @param  Array   The variables to update.   
491     @return Boolean Returns TRUE on success. 
492    */
493   public function update_entries($ids,$entry)
494   {
495     $this->b_error = FALSE;
496     $this->s_error = "";
497     if(!is_array($ids)){
498       trigger_error("Requires an array as first parameter.");
499       return;
500     }
502     if(!is_array($entry)){
503       trigger_error("Requires an array as second parameter.");
504       return;
505     }
507     $attr = "";
508     foreach($entry as $name => $entry){
509       $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
510     }
511     $xml_msg = "<xml>
512       <header>gosa_update_status_jobdb_entry</header>
513       <where>
514       <clause>
515       <connector>or</connector>";
516     foreach($ids as $id){
517       $xml_msg .= "<phrase>
518         <operator>eq</operator>
519         <id>".$id."</id>
520         </phrase>";
521     }
522     $xml_msg .= "</clause>
523       </where>
524       <update>
525       ".$attr." 
526       </update>
527       </xml>";
528     if($this->connect()){
529       $this->o_sock->write($xml_msg);
530       $str      = trim($this->o_sock->read());
531       $entries = $this->xml_to_array($str);
532       if(isset($entries['XML'])){
533         return(TRUE);
534       }
535     }
536     return(FALSE);
537   }
540   /*! \brief  Returns the number of currently queued objects.
541       @return Integer  
542    */
543   public function number_of_queued_entries()
544   {
545     $xml_msg ="<xml><header>gosa_count_jobdb</header></xml>";
546     $this->connect();
547     if($this->connect()){
548       $this->o_sock->write($xml_msg);
549       $str     = trim($this->o_sock->read());
550       $entries = $this->xml_to_array($str);
551       if(isset($entries['XML'])){
552         return($entries['XML']['COUNT']);
553       }
554     }
555     return(-1);
556   } 
559   /*! \brief  Returns an array containing all queued entries.
560     @return Array All queued entries as an array.
561    */
562   public function _send($data, $answer_expected= FALSE)
563   {
564     $this->b_error = FALSE;
565     $this->s_error = "";
566     $ret = array();
568     if($this->connect()){
569       $this->o_sock->write($data);
570       if ($answer_expected){
571         $str = trim($this->o_sock->read());
572         $entries = $this->xml_to_array($str);
573         if(isset($entries['XML']) && is_array($entries['XML'])){
574           $ret = $entries; 
575         }
576       }
577     }
578     return($ret);
579   }
582   static function send($header, $to, $data= array(), $answer_expected = FALSE)
583   {
584     $xml_message= "";
586     /* Get communication object */
587     $d= new gosaSupportDaemon(TRUE,10);
589     /* Prepare data */
590     foreach ($data as $key => $value){
591       $xml_message.= "<$key>$value</$key>";
592     }
594     return $d->_send("<xml><header>$header</header><source>GOSA</source><target>$to</target>".$xml_message."</xml>",$answer_expected);
595   }
598   static function ping($target)
599   {
600     if (tests::is_mac($target)){
601     /* Get communication object */
602         $d= new gosaSupportDaemon(TRUE,0.5);
603         $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
604         return (count($answer) ? TRUE:FALSE);
605     }
607     return (FALSE);
608   }
612 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
613 ?>