Code

51a7160a8ae6a19d2ac9a6a9491780c4a5bf8027
[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       <target>GOSA</target>
152       <source>GOSA</source>
153       <where>
154       <clause>
155         <phrase>
156         <operator>ne</operator>
157         <HEADERTAG>*</HEADERTAG>
158         </phrase>
159       </clause>
160       </where>
161       <orderby>".$sort."</orderby>";
162 if($from != -1 && $to != -1){
163 $xml_msg.= "
164       <limit>
165        <from>".$from."</from>
166        <to>".$to."</to>
167       </limit>";
169 $xml_msg.= "
170       </xml>";
172     if($this->connect()){
173       $this->o_sock->write($xml_msg);
174       $str = trim($this->o_sock->read());
175       $entries = $this->xml_to_array($str);
176       if(isset($entries['XML']) && is_array($entries['XML'])){
178         /* Check if returned values represent a valid answer */
179         if($entries['XML']['HEADER'] == "answer"){
180           
181           /* Unset header tags */
182           foreach(array("HEADER","SOURCE","TARGET") as $type){
183             unset($entries['XML'][$type]);
184           }
185           $ret = $entries['XML']; 
186         }
187       }
188     }
189     
190     return($ret);
191   }
194   /*! \brief  Checks if the given ids are used queue ids.
195     @param  Array   The ids we want to check..
196     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
197    */
198   public function ids_exist($ids)
199   {
200     if(!is_array($ids)){
201       trigger_error("Requires an array as parameter.");
202       return;
203     }
204     $this->b_error = FALSE;
205     $this->s_error = "";
207     $ret = array();
209     $xml_msg = "<xml>
210       <header>gosa_query_jobdb</header>
211       <target>GOSA</target>
212       <source>GOSA</source>
213       <where>
214       <clause>
215       <connector>or</connector>";
216     foreach($ids as $id){
217       $xml_msg .= "<phrase>
218         <operator>eq</operator>
219         <id>".$id."</id>
220         </phrase>";
221     }
222     $xml_msg .= "</clause>
223       </where>
224       </xml>";
226     if($this->connect()){
227       $this->o_sock->write($xml_msg);
228       $str = trim($this->o_sock->read());
229       $entries = $this->xml_to_array($str);
230       if(isset($entries['XML']) && is_array($entries['XML'])){
231         foreach($entries['XML'] as $entry){
232           if(isset($entry['ID'])){
233             $ret[] = $entry['ID'];
234           }
235         }
236       }
237     }
238     return($ret);
239   }
242   /*! \brief  Returns an entry containing all requested ids.
243     @param  Array   The IDs of the entries we want to return.
244     @return Array   Of the requested entries. 
245    */
246   public function get_entries_by_id($ids)
247   {
248     if(!is_array($ids)){
249       trigger_error("Requires an array as parameter.");
250       return;
251     }
252     $this->b_error = FALSE;
253     $this->s_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->b_error = FALSE;
302     $this->s_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   
342     $this->b_error = FALSE;
343     $this->s_error = "";
344     $ret = array();
345     $xml_msg = "<xml>
346       <header>gosa_query_jobdb</header>
347       <target>GOSA</target>
348       <source>GOSA</source>
349       <where>
350       <clause>
351       <phrase>
352       <operator>eq</operator>
353       <id>".$id."</id>
354       </phrase>
355       </clause>
356       </where>
357       </xml>";
358     if($this->connect()){
359       $this->o_sock->write($xml_msg);
360       $str = trim($this->o_sock->read());
361       $entries = $this->xml_to_array($str); 
362       if( isset($entries['XML']['HEADER']) &&
363           $entries['XML']['HEADER']=="answer" &&
364           isset($entries['XML']['ANSWER1'])){
365         $ret = $entries['XML']['ANSWER1'];
366       }
367     }
368     return($ret);
369   }
372   /*! \brief  Removes a set of entries from the GOsa support queue. 
373     @param  Array The IDs to remove.
374     @return Boolean True on success.
375    */
376   public function remove_entries($ids)
377   {
378     if(!is_array($ids)){
379       trigger_error("Requires an array as parameter.");
380       return;
381     }
382     $this->b_error = FALSE;
383     $this->s_error = "";
385     $ret = array();
387     $xml_msg = "<xml>
388       <header>gosa_delete_jobdb_entry</header>
389       <target>GOSA</target>
390       <source>GOSA</source>
391       <where>
392       <clause>
393       <connector>or</connector>";
394     foreach($ids as $id){
395       $xml_msg .= "<phrase>
396         <operator>eq</operator>
397         <id>".$id."</id>
398         </phrase>";
399     }
400     $xml_msg .= "</clause>
401       </where>
402       </xml>";
403     $this->b_error = FALSE;
404     $this->s_error = "";
406     if($this->connect()){
407       $this->o_sock->write($xml_msg);
408       $str = $this->o_sock->read();
409       $entries = $this->xml_to_array($str);
410       if(isset($entries['XML'])){
411         return(TRUE);
412       }
413     }
414     return(FALSE);
415   }
419   /*! \brief  Removes an entry from the GOsa support queue. 
420     @param  Integer The ID of the entry we want to remove.
421     @return Boolean True on success.
422    */
423   public function remove_entry($id)
424   {
425     $this->b_error = FALSE;
426     $this->s_error = "";
428     $xml_msg = "<xml>
429       <header>gosa_delete_jobdb_entry</header>
430       <target>GOSA</target>
431       <source>GOSA</source>
432       <where>
433       <clause>
434       <phrase>
435       <operator>eq</operator>
436       <id>".$id."</id>
437       </phrase>
438       </clause>
439       </where>
440       </xml>";
441     if($this->connect()){
442       $this->o_sock->write($xml_msg);
443       $str = $this->o_sock->read();
444       $entries = $this->xml_to_array($str);
445       if(isset($entries['XML'])){
446         return(TRUE);
447       }
448     }
449     return(FALSE);
450   }
453   /*! \brief  Parses the given xml string into an array 
454     @param  String XML string  
455     @return Array Returns an array containing the xml structure. 
456    */
457   private function xml_to_array($xml)
458   {
459     $params = array();
460     $level = array();
461     $parser  = xml_parser_create_ns();
462     xml_parse_into_struct($parser, $xml, $vals, $index);
464     $err_id = xml_get_error_code($parser);
465     if($err_id){
466       xml_parser_free($parser);
467     }else{
468       xml_parser_free($parser);
470       foreach ($vals as $xml_elem) {
471         if ($xml_elem['type'] == 'open') {
472           if (array_key_exists('attributes',$xml_elem)) {
473             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
474           } else {
475             $level[$xml_elem['level']] = $xml_elem['tag'];
476           }
477         }
478         if ($xml_elem['type'] == 'complete') {
479           $start_level = 1;
480           $php_stmt = '$params';
481           while($start_level < $xml_elem['level']) {
482             $php_stmt .= '[$level['.$start_level.']]';
483             $start_level++;
484           }
485           $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
486           @eval($php_stmt);
487         }
488       }
489     }
491     if(!isset($params['XML'])){
492       if (!array_key_exists('XML', $params)){
493         $this->set_error(_("Could not parse XML."));
494       }
495       $params = array("COUNT" => 0);
496     }
498     return($params); 
499   }
502   /*! \brief  Updates an entry with a set of new values, 
503     @param  Integer The ID of the entry, we want to update.
504     @param  Array   The variables to update.   
505     @return Boolean Returns TRUE on success. 
506    */
507   public function update_entries($ids,$entry)
508   {
509     $this->b_error = FALSE;
510     $this->s_error = "";
511     if(!is_array($ids)){
512       trigger_error("Requires an array as first parameter.");
513       return;
514     }
516     if(!is_array($entry)){
517       trigger_error("Requires an array as second parameter.");
518       return;
519     }
521     $attr = "";
522     foreach($entry as $name => $entry){
523       $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
524     }
525     $xml_msg = "<xml>
526       <header>gosa_update_status_jobdb_entry</header>
527       <target>GOSA</target>
528       <source>GOSA</source>
529       <where>
530       <clause>
531       <connector>or</connector>";
532     foreach($ids as $id){
533       $xml_msg .= "<phrase>
534         <operator>eq</operator>
535         <id>".$id."</id>
536         </phrase>";
537     }
538     $xml_msg .= "</clause>
539       </where>
540       <update>
541       ".$attr." 
542       </update>
543       </xml>";
544     if($this->connect()){
545       $this->o_sock->write($xml_msg);
546       $str      = trim($this->o_sock->read());
547       $entries = $this->xml_to_array($str);
548       if(isset($entries['XML'])){
549         return(TRUE);
550       }
551     }
552     return(FALSE);
553   }
556   /*! \brief  Returns the number of currently queued objects.
557       @return Integer  
558    */
559   public function number_of_queued_entries()
560   {
561     $xml_msg ="<xml><header>gosa_count_jobdb</header><target>GOSA</target><source>GOSA</source></xml>";
562     $this->connect();
563     if($this->connect()){
564       $this->o_sock->write($xml_msg);
565       $str     = trim($this->o_sock->read());
566       $entries = $this->xml_to_array($str);
567       if(isset($entries['XML'])){
568         return($entries['XML']['COUNT']);
569       }
570     }
571     return(-1);
572   } 
575   /*! \brief  Returns an array containing all queued entries.
576     @return Array All queued entries as an array.
577    */
578   public function _send($data, $answer_expected= FALSE)
579   {
580     $this->b_error = FALSE;
581     $this->s_error = "";
582     $ret = array();
584     if($this->connect()){
585       $this->o_sock->write($data);
586       if ($answer_expected){
587         $str = trim($this->o_sock->read());
588         $entries = $this->xml_to_array($str);
589         if(isset($entries['XML']) && is_array($entries['XML'])){
590           $ret = $entries; 
591         }
592       }
593     }
594     return($ret);
595   }
598   static function send($header, $to, $data= array(), $answer_expected = FALSE)
599   {
600     $xml_message= "";
602     /* Get communication object */
603     $d= new gosaSupportDaemon(TRUE,10);
605     /* Prepare data */
606     foreach ($data as $key => $value){
607       $xml_message.= "<$key>$value</$key>";
608     }
610     return $d->_send("<xml><header>$header</header><source>GOSA</source><target>$to</target>".$xml_message."</xml>",$answer_expected);
611   }
614   static function ping($target)
615   {
616     if (tests::is_mac($target)){
617     /* Get communication object */
618         $d= new gosaSupportDaemon(TRUE,0.5);
619         $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
620         return (count($answer) ? TRUE:FALSE);
621     }
623     return (FALSE);
624   }
628 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
629 ?>