Code

1cb7a819072fc2dcf4de7c175e055f889d6c2544
[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->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 daemon.
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       <orderby>".$sort."</orderby>";
154 if($from != -1 && $to != -1){
155 $xml_msg.= "
156       <limit>
157        <from>".$from."</from>
158        <to>".$to."</to>
159       </limit>";
161 $xml_msg.= "
162       </xml>";
164     if($this->connect()){
165       $this->o_sock->write($xml_msg);
166       $str = trim($this->o_sock->read());
167       $entries = $this->xml_to_array($str);
168       if(isset($entries['XML']) && is_array($entries['XML'])){
170         /* Check if returned values represent a valid answer */
171         if(isset($entries['XML'])){
172           
173           /* Unset header tags */
174           foreach(array("HEADER","SOURCE","TARGET") as $type){
175             unset($entries['XML'][$type]);
176           }
177           $ret = $entries['XML']; 
178         }
179       }
180     }
181     
182     return($ret);
183   }
186   /*! \brief  Checks if the given ids are used queue ids.
187     @param  Array   The ids we want to check..
188     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
189    */
190   public function ids_exist($ids)
191   {
192     if(!is_array($ids)){
193       trigger_error("Requires an array as parameter.");
194       return;
195     }
196     $this->b_error = FALSE;
197     $this->s_error = "";
199     $ret = array();
201     $xml_msg = "<xml>
202       <header>gosa_query_jobdb</header>
203       <target>GOSA</target>
204       <source>GOSA</source>
205       <where>
206       <clause>
207       <connector>or</connector>";
208     foreach($ids as $id){
209       $xml_msg .= "<phrase>
210         <operator>eq</operator>
211         <id>".$id."</id>
212         </phrase>";
213     }
214     $xml_msg .= "</clause>
215       </where>
216       </xml>";
218     if($this->connect()){
219       $this->o_sock->write($xml_msg);
220       $str = trim($this->o_sock->read());
221       $entries = $this->xml_to_array($str);
222       if(isset($entries['XML']) && is_array($entries['XML'])){
223         foreach($entries['XML'] as $entry){
224           if(isset($entry['ID'])){
225             $ret[] = $entry['ID'];
226           }
227         }
228       }
229     }
230     return($ret);
231   }
234   /*! \brief  Returns an entry containing all requested ids.
235     @param  Array   The IDs of the entries we want to return.
236     @return Array   Of the requested entries. 
237    */
238   public function get_entries_by_id($ids)
239   {
240     if(!is_array($ids)){
241       trigger_error("Requires an array as parameter.");
242       return;
243     }
244     $this->b_error = FALSE;
245     $this->s_error = "";
247     $ret = array();
249     $xml_msg = "<xml>
250       <header>gosa_query_jobdb</header>
251       <target>GOSA</target>
252       <source>GOSA</source>
253       <where>
254       <clause>
255       <connector>or</connector>";
256     foreach($ids as $id){
257       $xml_msg .= "<phrase>
258         <operator>eq</operator>
259         <id>".$id."</id>
260         </phrase>";
261     }
262     $xml_msg .= "</clause>
263       </where>
264       </xml>";
266     if($this->connect()){
267       $this->o_sock->write($xml_msg);
268       $str = trim($this->o_sock->read());
269       $entries = $this->xml_to_array($str); 
270       if(isset($entries['XML'])){
271         foreach($entries['XML'] as $name => $entry){
272           if(preg_match("/^ANSWER[0-9]*$/",$name)){
273             $ret[$name] = $entry;
274           }
275         }
276       }
277     }
278     return($ret);
279   }
282   /*! \brief  Checks if the given id is in use.
283     @param  Integer The ID of the entry.
284     @return Boolean TRUE if entry exists. 
285    */
286   public function id_exists($id)
287   {
288     if(!is_numeric($id)){
289       trigger_error("Requires an integer as parameter.");
290       return;
291     }
293     $this->b_error = FALSE;
294     $this->s_error = "";
295     $xml_msg = "<xml>
296       <header>gosa_query_jobdb</header>
297       <target>GOSA</target>
298       <source>GOSA</source>
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       <target>GOSA</target>
340       <source>GOSA</source>
341       <where>
342       <clause>
343       <phrase>
344       <operator>eq</operator>
345       <id>".$id."</id>
346       </phrase>
347       </clause>
348       </where>
349       </xml>";
350     if($this->connect()){
351       $this->o_sock->write($xml_msg);
352       $str = trim($this->o_sock->read());
353       $entries = $this->xml_to_array($str); 
354       if( isset($entries['XML']['HEADER']) &&
355           $entries['XML']['HEADER']=="answer" &&
356           isset($entries['XML']['ANSWER1'])){
357         $ret = $entries['XML']['ANSWER1'];
358       }
359     }
360     return($ret);
361   }
364   /*! \brief  Removes a set of entries from the GOsa support queue. 
365     @param  Array The IDs to remove.
366     @return Boolean True on success.
367    */
368   public function remove_entries($ids)
369   {
370     if(!is_array($ids)){
371       trigger_error("Requires an array as parameter.");
372       return;
373     }
374     $this->b_error = FALSE;
375     $this->s_error = "";
377     $ret = array();
379     $xml_msg = "<xml>
380       <header>gosa_delete_jobdb_entry</header>
381       <target>GOSA</target>
382       <source>GOSA</source>
383       <where>
384       <clause>
385       <connector>or</connector>";
386     foreach($ids as $id){
387       $xml_msg .= "<phrase>
388         <operator>eq</operator>
389         <id>".$id."</id>
390         </phrase>";
391     }
392     $xml_msg .= "</clause>
393       </where>
394       </xml>";
395     $this->b_error = FALSE;
396     $this->s_error = "";
398     if($this->connect()){
399       $this->o_sock->write($xml_msg);
400       $str = $this->o_sock->read();
401       $entries = $this->xml_to_array($str);
402       if(isset($entries['XML'])){
403         return(TRUE);
404       }
405     }
406     return(FALSE);
407   }
411   /*! \brief  Removes an entry from the GOsa support queue. 
412     @param  Integer The ID of the entry we want to remove.
413     @return Boolean True on success.
414    */
415   public function remove_entry($id)
416   {
417     $this->b_error = FALSE;
418     $this->s_error = "";
420     $xml_msg = "<xml>
421       <header>gosa_delete_jobdb_entry</header>
422       <target>GOSA</target>
423       <source>GOSA</source>
424       <where>
425       <clause>
426       <phrase>
427       <operator>eq</operator>
428       <id>".$id."</id>
429       </phrase>
430       </clause>
431       </where>
432       </xml>";
433     if($this->connect()){
434       $this->o_sock->write($xml_msg);
435       $str = $this->o_sock->read();
436       $entries = $this->xml_to_array($str);
437       if(isset($entries['XML'])){
438         return(TRUE);
439       }
440     }
441     return(FALSE);
442   }
445   /*! \brief  Parses the given xml string into an array 
446     @param  String XML string  
447     @return Array Returns an array containing the xml structure. 
448    */
449   private function xml_to_array($xml)
450   {
451     $params = array();
452     $level = array();
453     $parser  = xml_parser_create_ns();
454     xml_parse_into_struct($parser, $xml, $vals, $index);
456     $err_id = xml_get_error_code($parser);
457     if($err_id){
458       xml_parser_free($parser);
459     }else{
460       xml_parser_free($parser);
462       foreach ($vals as $xml_elem) {
463         if ($xml_elem['type'] == 'open') {
464           if (array_key_exists('attributes',$xml_elem)) {
465             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
466           } else {
467             $level[$xml_elem['level']] = $xml_elem['tag'];
468           }
469         }
470         if ($xml_elem['type'] == 'complete') {
471           $start_level = 1;
472           $php_stmt = '$params';
473           while($start_level < $xml_elem['level']) {
474             $php_stmt .= '[$level['.$start_level.']]';
475             $start_level++;
476           }
477           $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
478           @eval($php_stmt);
479         }
480       }
481     }
483     if(!isset($params['XML'])){
484       if (!array_key_exists('XML', $params)){
485         $this->set_error(_("Could not parse XML."));
486       }
487       $params = array("COUNT" => 0);
488     }
490     return($params); 
491   }
494   /*! \brief  Updates an entry with a set of new values, 
495     @param  Integer The ID of the entry, we want to update.
496     @param  Array   The variables to update.   
497     @return Boolean Returns TRUE on success. 
498    */
499   public function update_entries($ids,$entry)
500   {
501     $this->b_error = FALSE;
502     $this->s_error = "";
503     if(!is_array($ids)){
504       trigger_error("Requires an array as first parameter.");
505       return;
506     }
508     if(!is_array($entry)){
509       trigger_error("Requires an array as second parameter.");
510       return;
511     }
513     $attr = "";
514     foreach($entry as $name => $entry){
515       $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
516     }
517     $xml_msg = "<xml>
518       <header>gosa_update_status_jobdb_entry</header>
519       <target>GOSA</target>
520       <source>GOSA</source>
521       <where>
522       <clause>
523       <connector>or</connector>";
524     foreach($ids as $id){
525       $xml_msg .= "<phrase>
526         <operator>eq</operator>
527         <id>".$id."</id>
528         </phrase>";
529     }
530     $xml_msg .= "</clause>
531       </where>
532       <update>
533       ".$attr." 
534       </update>
535       </xml>";
536     if($this->connect()){
537       $this->o_sock->write($xml_msg);
538       $str      = trim($this->o_sock->read());
539       $entries = $this->xml_to_array($str);
540       if(isset($entries['XML'])){
541         return(TRUE);
542       }
543     }
544     return(FALSE);
545   }
548   /*! \brief  Returns the number of currently queued objects.
549       @return Integer  
550    */
551   public function number_of_queued_entries()
552   {
553     $xml_msg ="<xml><header>gosa_count_jobdb</header><target>GOSA</target><source>GOSA</source></xml>";
554     $this->connect();
555     if($this->connect()){
556       $this->o_sock->write($xml_msg);
557       $str     = trim($this->o_sock->read());
558       $entries = $this->xml_to_array($str);
559       if(isset($entries['XML'])){
560         return($entries['XML']['COUNT']);
561       }
562     }
563     return(-1);
564   } 
567   /*! \brief  Returns an array containing all queued entries.
568     @return Array All queued entries as an array.
569    */
570   public function _send($data, $answer_expected= FALSE)
571   {
572     $this->b_error = FALSE;
573     $this->s_error = "";
574     $ret = array();
576     if($this->connect()){
577       $this->o_sock->write($data);
578       if ($answer_expected){
579         $str = trim($this->o_sock->read());
580         $entries = $this->xml_to_array($str);
581         if(isset($entries['XML']) && is_array($entries['XML'])){
582           $ret = $entries;
583           if(isset($entries['XML']['ERROR_STRING'])) {
584             $this->set_error($entries['XML']['ERROR_STRING']);
585           }
586         }
587       }
588     }
589     return($ret);
590   }
593   static function send($header, $to, $data= array(), $answer_expected = FALSE)
594   {
595     $xml_message= "";
597     /* Get communication object */
598     $d= new gosaSupportDaemon(TRUE,10);
600     /* Prepare data */
601     foreach ($data as $key => $value){
602       $xml_message.= "<$key>$value</$key>";
603     }
605     /* Multiple targets? */
606     if (!is_array($to)){
607       $to_targets= array($to);
608     } else {
609       $to_targets= $to;
610     }
612     /* Build target strings */
613     $target ="";
614     foreach($to_targets as $to){
615       $target.= "<target>$to</target>";
616     }
618     return $d->_send("<xml><header>$header</header><source>GOSA</source>$target".$xml_message."</xml>",$answer_expected);
619   }
622   static function ping($target)
623   {
624     if (tests::is_mac($target)){
625     /* Get communication object */
626         $d= new gosaSupportDaemon(TRUE,0.5);
627         $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
628         return (count($answer) ? TRUE:FALSE);
629     }
631     return (FALSE);
632   }
636 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
637 ?>