51a7160a8ae6a19d2ac9a6a9491780c4a5bf8027
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>";
168 }
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"){
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 }
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 }
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 }
626 }
628 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
629 ?>