adb819baec9112fee9670bc1b007050ae992095a
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>";
166 }
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"){
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 }
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 }
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())
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>");
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 }
610 }
612 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
613 ?>