Code

Updated gosaSupportDaemon.
[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 daemon handle. 
25    connect                  - Connect to daemon 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 daemon is running on.  
58     @param integer  Port    The port which the daemon use.
59     @param string   Key     The encryption string.
60     @param boolean  Connect Directly connect to daemon 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 daemon 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->set_error($this->o_sock->get_error());
96       $this->disconnect();
97     }
98     return($this->is_connected);
99   }
102   /*! \brief  Disconnect from gosa daemon.
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  Sets an error message, which can be returned with get_error().
122     @param  string  The Error message,
123    */
124   private function reset_error()
125   {
126     $this->b_error = FALSE;
127     $this->s_error = "";
128   }
131   /*! \brief  Checks if an error occured.
132     @return boolean returns TRUE or FALSE, whether there is an error or not.
133    */
134   public function is_error()
135   {
136     return($this->b_error);
137   }
140   /*! \brief  Returns the last error. 
141     @return Returns the last error.
142    */
143   public function get_error()
144   {
145     $str = $this->s_error;
146     $str = preg_replace("/ /","&nbsp;",$str);
147     return($str);
148   }
151   /*! \brief  Returns an array containing all queued entries.
152     @return Array All queued entries as an array.
153    */
154   public function get_queued_entries($from=-1,$to=-1,$sort="timestamp DESC")
155   {
156     $this->reset_error();
157     $ret = array();
159     $xml_msg = "<xml>
160       <header>gosa_query_jobdb</header>
161       <target>GOSA</target>
162       <source>GOSA</source>
163       <orderby>".$sort."</orderby>";
164 if($from != -1 && $to != -1){
165 $xml_msg.= "
166       <limit>
167        <from>".$from."</from>
168        <to>".$to."</to>
169       </limit>";
171 $xml_msg.= "
172       </xml>";
174     if($this->connect()){
175       $this->o_sock->write($xml_msg);
176       $str = trim($this->o_sock->read());
177       $entries = $this->xml_to_array($str);
178       if(isset($entries['XML']) && is_array($entries['XML'])){
180         /* Check if returned values represent a valid answer */
181         if(isset($entries['XML'])){
182           
183           /* Unset header tags */
184           foreach(array("HEADER","SOURCE","TARGET") as $type){
185             unset($entries['XML'][$type]);
186           }
187           $ret = $entries['XML']; 
188         }
189       }
190     }
191     
192     return($ret);
193   }
196   /*! \brief  Checks if the given ids are used queue ids.
197     @param  Array   The ids we want to check..
198     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
199    */
200   public function ids_exist($ids)
201   {
202     if(!is_array($ids)){
203       trigger_error("Requires an array as parameter.");
204       return;
205     }
206     $this->reset_error();
208     $ret = array();
210     $xml_msg = "<xml>
211       <header>gosa_query_jobdb</header>
212       <target>GOSA</target>
213       <source>GOSA</source>
214       <where>
215       <clause>
216       <connector>or</connector>";
217     foreach($ids as $id){
218       $xml_msg .= "<phrase>
219         <operator>eq</operator>
220         <id>".$id."</id>
221         </phrase>";
222     }
223     $xml_msg .= "</clause>
224       </where>
225       </xml>";
227     if($this->connect()){
228       $this->o_sock->write($xml_msg);
229       $str = trim($this->o_sock->read());
230       $entries = $this->xml_to_array($str);
231       if(isset($entries['XML']) && is_array($entries['XML'])){
232         foreach($entries['XML'] as $entry){
233           if(isset($entry['ID'])){
234             $ret[] = $entry['ID'];
235           }
236         }
237       }
238     }
239     return($ret);
240   }
243   /*! \brief  Returns an entry containing all requested ids.
244     @param  Array   The IDs of the entries we want to return.
245     @return Array   Of the requested entries. 
246    */
247   public function get_entries_by_id($ids)
248   {
249     if(!is_array($ids)){
250       trigger_error("Requires an array as parameter.");
251       return;
252     }
253     $this->reset_error();
255     $ret = array();
257     $xml_msg = "<xml>
258       <header>gosa_query_jobdb</header>
259       <target>GOSA</target>
260       <source>GOSA</source>
261       <where>
262       <clause>
263       <connector>or</connector>";
264     foreach($ids as $id){
265       $xml_msg .= "<phrase>
266         <operator>eq</operator>
267         <id>".$id."</id>
268         </phrase>";
269     }
270     $xml_msg .= "</clause>
271       </where>
272       </xml>";
274     if($this->connect()){
275       $this->o_sock->write($xml_msg);
276       $str = trim($this->o_sock->read());
277       $entries = $this->xml_to_array($str); 
278       if(isset($entries['XML'])){
279         foreach($entries['XML'] as $name => $entry){
280           if(preg_match("/^ANSWER[0-9]*$/",$name)){
281             $ret[$name] = $entry;
282           }
283         }
284       }
285     }
286     return($ret);
287   }
290   /*! \brief  Checks if the given id is in use.
291     @param  Integer The ID of the entry.
292     @return Boolean TRUE if entry exists. 
293    */
294   public function id_exists($id)
295   {
296     if(!is_numeric($id)){
297       trigger_error("Requires an integer as parameter.");
298       return;
299     }
301     $this->reset_error();
303     $xml_msg = "<xml>
304       <header>gosa_query_jobdb</header>
305       <target>GOSA</target>
306       <source>GOSA</source>
307       <where>
308       <clause>
309       <phrase>
310       <operator>eq</operator>
311       <id>".$id."</id>
312       </phrase>
313       </clause>
314       </where>
315       </xml>";
317     if($this->connect()){
318       $this->o_sock->write($xml_msg);
319       $str = trim($this->o_sock->read());
320       $entries = $this->xml_to_array($str); 
321       if( isset($entries['XML']['HEADER']) && 
322           $entries['XML']['HEADER']=="answer" && 
323           isset($entries['XML']['ANSWER1'])){
324         return(TRUE);
325       }
326     }
327     return(FALSE);
328   }
331   /*! \brief  Returns an entry from the gosaSupportQueue
332     @param  Integer The ID of the entry we want to return.
333     @return Array   Of the requested entry. 
334    */
335   public function get_entry_by_id($id)
336   {
337     if(!is_numeric($id)){
338       trigger_error("Requires an integer as parameter.");
339       return;
340     }
341     $this->reset_error();
342   
343     $ret = array();
344     $xml_msg = "<xml>
345       <header>gosa_query_jobdb</header>
346       <target>GOSA</target>
347       <source>GOSA</source>
348       <where>
349       <clause>
350       <phrase>
351       <operator>eq</operator>
352       <id>".$id."</id>
353       </phrase>
354       </clause>
355       </where>
356       </xml>";
357     if($this->connect()){
358       $this->o_sock->write($xml_msg);
359       $str = trim($this->o_sock->read());
360       $entries = $this->xml_to_array($str); 
361       if( isset($entries['XML']['HEADER']) &&
362           $entries['XML']['HEADER']=="answer" &&
363           isset($entries['XML']['ANSWER1'])){
364         $ret = $entries['XML']['ANSWER1'];
365       }
366     }
367     return($ret);
368   }
371   /*! \brief  Removes a set of entries from the GOsa support queue. 
372     @param  Array The IDs to remove.
373     @return Boolean True on success.
374    */
375   public function remove_entries($ids)
376   {
377     if(!is_array($ids)){
378       trigger_error("Requires an array as parameter.");
379       return;
380     }
382     $this->reset_error();
384     $ret = array();
386     $xml_msg = "<xml>
387       <header>gosa_delete_jobdb_entry</header>
388       <target>GOSA</target>
389       <source>GOSA</source>
390       <where>
391       <clause>
392       <connector>or</connector>";
393     foreach($ids as $id){
394       $xml_msg .= "<phrase>
395         <operator>eq</operator>
396         <id>".$id."</id>
397         </phrase>";
398     }
399     $xml_msg .= "</clause>
400       </where>
401       </xml>";
403     if($this->connect()){
404       $this->o_sock->write($xml_msg);
405       $str = $this->o_sock->read();
406       $entries = $this->xml_to_array($str);
407       if(isset($entries['XML'])){
408         return(TRUE);
409       }
410     }
411     return(FALSE);
412   }
416   /*! \brief  Removes an entry from the GOsa support queue. 
417     @param  Integer The ID of the entry we want to remove.
418     @return Boolean True on success.
419    */
420   public function remove_entry($id)
421   {
422     $this->reset_error();
424     $xml_msg = "<xml>
425       <header>gosa_delete_jobdb_entry</header>
426       <target>GOSA</target>
427       <source>GOSA</source>
428       <where>
429       <clause>
430       <phrase>
431       <operator>eq</operator>
432       <id>".$id."</id>
433       </phrase>
434       </clause>
435       </where>
436       </xml>";
437     if($this->connect()){
438       $this->o_sock->write($xml_msg);
439       $str = $this->o_sock->read();
440       $entries = $this->xml_to_array($str);
441       if(isset($entries['XML'])){
442         return(TRUE);
443       }
444     }
445     return(FALSE);
446   }
449   /*! \brief  Parses the given xml string into an array 
450     @param  String XML string  
451     @return Array Returns an array containing the xml structure. 
452    */
453   private function xml_to_array($xml)
454   {
455     $params = array();
456     $level = array();
457     $parser  = xml_parser_create_ns();
458     xml_parse_into_struct($parser, $xml, $vals, $index);
460     $err_id = xml_get_error_code($parser);
461     if($err_id){
462       xml_parser_free($parser);
463     }else{
464       xml_parser_free($parser);
466       foreach ($vals as $xml_elem) {
467         if ($xml_elem['type'] == 'open') {
468           if (array_key_exists('attributes',$xml_elem)) {
469             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
470           } else {
471             $level[$xml_elem['level']] = $xml_elem['tag'];
472           }
473         }
474         if ($xml_elem['type'] == 'complete') {
475           $start_level = 1;
476           $php_stmt = '$params';
477           while($start_level < $xml_elem['level']) {
478             $php_stmt .= '[$level['.$start_level.']]';
479             $start_level++;
480           }
481           $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
482           @eval($php_stmt);
483         }
484       }
485     }
487     if(!isset($params['XML'])){
488       if (!array_key_exists('XML', $params)){
489         $this->set_error(_("Could not parse XML."));
490       }
491       $params = array("COUNT" => 0);
492     }
494     return($params); 
495   }
498   /*! \brief  Updates an entry with a set of new values, 
499     @param  Integer The ID of the entry, we want to update.
500     @param  Array   The variables to update.   
501     @return Boolean Returns TRUE on success. 
502    */
503   public function update_entries($ids,$entry)
504   {
505     $this->reset_error();
506     if(!is_array($ids)){
507       trigger_error("Requires an array as first parameter.");
508       return;
509     }
511     if(!is_array($entry)){
512       trigger_error("Requires an array as second parameter.");
513       return;
514     }
516     $attr = "";
517     foreach($entry as $name => $entry){
518       $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
519     }
520     $xml_msg = "<xml>
521       <header>gosa_update_status_jobdb_entry</header>
522       <target>GOSA</target>
523       <source>GOSA</source>
524       <where>
525       <clause>
526       <connector>or</connector>";
527     foreach($ids as $id){
528       $xml_msg .= "<phrase>
529         <operator>eq</operator>
530         <id>".$id."</id>
531         </phrase>";
532     }
533     $xml_msg .= "</clause>
534       </where>
535       <update>
536       ".$attr." 
537       </update>
538       </xml>";
539     if($this->connect()){
540       $this->o_sock->write($xml_msg);
541       $str      = trim($this->o_sock->read());
542       $entries = $this->xml_to_array($str);
543       if(isset($entries['XML'])){
544         return(TRUE);
545       }
546     }
547     return(FALSE);
548   }
551   /*! \brief  Returns the number of currently queued objects.
552       @return Integer  
553    */
554   public function number_of_queued_entries()
555   {
556     $xml_msg ="<xml><header>gosa_count_jobdb</header><target>GOSA</target><source>GOSA</source></xml>";
557     $this->connect();
558     if($this->connect()){
559       $this->o_sock->write($xml_msg);
560       $str     = trim($this->o_sock->read());
561       $entries = $this->xml_to_array($str);
562       if(isset($entries['XML'])){
563         return($entries['XML']['COUNT']);
564       }
565     }
566     return(-1);
567   } 
570   public function send_data($header, $to, $data= array(), $answer_expected = FALSE)
571   {
572     $xml_message= "";
574     /* Prepare data */
575     foreach ($data as $key => $value){
576       $xml_message.= "<$key>$value</$key>";
577     }
579     /* Multiple targets? */
580     if (!is_array($to)){
581       $to_targets= array($to);
582     } else {
583       $to_targets= $to;
584     }
586     /* Build target strings */
587     $target ="";
588     foreach($to_targets as $to){
589       $target.= "<target>$to</target>";
590     }
592     return $this->_send("<xml><header>$header</header><source>GOSA</source>$target".$xml_message."</xml>",$answer_expected);
593   }
596   /*! \brief  Returns an array containing all queued entries.
597     @return Array All queued entries as an array.
598    */
599   public function _send($data, $answer_expected= FALSE)
600   {
601     $this->reset_error();
602     $ret = array();
604     if($this->connect()){
605       $this->o_sock->write($data);
606       if ($answer_expected){
607         $str = trim($this->o_sock->read());
608         $entries = $this->xml_to_array($str);
609         if(isset($entries['XML']) && is_array($entries['XML'])){
610           $ret = $entries;
611           if(isset($entries['XML']['ERROR_STRING'])) {
612             $this->set_error($entries['XML']['ERROR_STRING']);
613           }
614         }
615       }
616     }
617     return($ret);
618   }
621   static function send($header, $to, $data= array(), $answer_expected = FALSE)
622   {
623     $xml_message= "";
625     /* Get communication object */
626     $d= new gosaSupportDaemon(TRUE,10);
628     /* Prepare data */
629     foreach ($data as $key => $value){
630       $xml_message.= "<$key>$value</$key>";
631     }
633     /* Multiple targets? */
634     if (!is_array($to)){
635       $to_targets= array($to);
636     } else {
637       $to_targets= $to;
638     }
640     /* Build target strings */
641     $target ="";
642     foreach($to_targets as $to){
643       $target.= "<target>$to</target>";
644     }
646     return $d->_send("<xml><header>$header</header><source>GOSA</source>$target".$xml_message."</xml>",$answer_expected);
647   }
650   static function ping($target)
651   {
652     if (tests::is_mac($target)){
653     /* Get communication object */
654         $d= new gosaSupportDaemon(TRUE,0.5);
655         $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
656         return (count($answer) ? TRUE:FALSE);
657     }
659     return (FALSE);
660   }
664 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
665 ?>