00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <stdarg.h>
00047
00048 #include "easydbus-core.h"
00049 #include "debug.h"
00050 #include "introspect_internal.h"
00051 #include "reply_internal.h"
00052 #include "utils.h"
00053
00054
00055
00066 introspect_objs_tree *
00067 easydbus_introspect_obj_tree_create (char *leaf_name,
00068 struct EasyDbus_object_box *obj)
00069 {
00070 introspect_objs_tree *o = NULL;
00071 int n;
00072
00073 if (!leaf_name) return NULL;
00074
00075 o = (introspect_objs_tree *)
00076 malloc (sizeof (introspect_objs_tree));
00077 if (!o) goto error;
00078
00079 memset (o, 0, sizeof (introspect_objs_tree));
00080 n = strlen (leaf_name) + 1;
00081 o->leaf_name = (char *) malloc (n);
00082 EASYDBUS_MEMCOPY (o->leaf_name, leaf_name, n);
00083 o->n_leafs = 0;
00084 o->obj = obj;
00085 o->leafs = NULL;
00086
00087 return o;
00088
00089 error:
00090 if (o) {
00091 if (o->leaf_name)
00092 free (o->leaf_name);
00093 free (o);
00094 }
00095 return NULL;
00096 }
00097
00103 void
00104 easydbus_introspect_obj_tree_free (introspect_objs_tree *o)
00105 {
00106 if (!o) return;
00107
00108 if (o->leaf_name)
00109 free (o->leaf_name);
00110
00111 if (o->leafs)
00112 free (o->leafs);
00113
00114 o->leaf_name = NULL;
00115 o->obj = NULL;
00116 o->leafs = NULL;
00117
00118 free (o);
00119 }
00120
00127 introspect_objs_tree *
00128 easydbus_introspect_objs_tree_build (struct EasyDbus_object_box *object)
00129 {
00130 introspect_objs_tree *tree = NULL;
00131 struct EasyDbus_object_box *obj = NULL;
00132 int i, length, n_token = 0;
00133 char *tmp , *token, *saveptr;
00134 char **l_tokens;
00135
00136 if (!object)
00137 return NULL;
00138
00139 tmp = token = saveptr = NULL;
00140 l_tokens = NULL;
00141
00142 for (obj = object; obj; obj = obj->next) {
00143 length = strlen (obj->core.path);
00144 n_token =
00145 easydbus_introspect_get_ntoken (obj->core.path,
00146 length);
00147 EasyDbusDebug ("Service %s has %d token", obj->core.path,
00148 n_token);
00149 if (n_token <= 0) goto error;
00150
00151 l_tokens = (char **) malloc (sizeof (char *[n_token]));
00152 if (!l_tokens) goto error;
00153
00154 tmp = (char *) malloc (++length);
00155 if (!tmp) goto error;
00156
00157 EASYDBUS_MEMCOPY (tmp, obj->core.path, length);
00158
00159 for (i = 0, token = strtok_r (tmp, "/", &saveptr); token;
00160 token = strtok_r (saveptr, "/", &saveptr), i++)
00161 l_tokens[i] = token;
00162 if (easydbus_introspect_objs_tree_add_leafs (&tree, l_tokens,
00163 n_token, obj))
00164 goto error;
00165 free (l_tokens);
00166 free (tmp);
00167 l_tokens = NULL;
00168 tmp = NULL;
00169 }
00170
00171 return tree;
00172 error:
00173 if (tmp) free (tmp);
00174 if (l_tokens) free (l_tokens);
00175 if (tree)
00176 easydbus_introspect_objs_tree_destroy (tree);
00177 EasyDbusDebug ("Error on create introspect tree");
00178 return NULL;
00179 }
00180
00194 int
00195 easydbus_introspect_objs_tree_add_leafs (introspect_objs_tree **tt,
00196 char **l_tokens, unsigned int n,
00197 struct EasyDbus_object_box *obj)
00198 {
00199 unsigned int i, j, hastoken = 0;
00200 introspect_objs_tree *t, *leaf, *next;
00201 introspect_objs_tree **temp_tt, **temp2_tt;
00202
00203 if (!l_tokens) return -1;
00204
00205 leaf = next = t = NULL;
00206 temp_tt = temp2_tt = NULL;
00207
00208
00209 if (!*tt) {
00210 *tt = easydbus_introspect_obj_tree_create ("/", NULL);
00211 if (!*tt) return -1;
00212 }
00213 t = *tt;
00214 for (i = 0; i < n; i++, t = next) {
00215
00216 if (t->n_leafs) {
00217 leaf = easydbus_introspect_obj_tree_hastoken (t, l_tokens[i]);
00218 if (leaf) hastoken = 1;
00219 }
00220 if (!leaf) {
00221
00222 if (i < (n-1))
00223 leaf = easydbus_introspect_obj_tree_create (l_tokens[i], NULL);
00224 else
00225 leaf = easydbus_introspect_obj_tree_create (l_tokens[i], obj);
00226 if (!leaf) return -1;
00227 }
00228 if (t->n_leafs && !hastoken) {
00229 temp_tt = (introspect_objs_tree **)
00230 malloc (sizeof (introspect_objs_tree [t->n_leafs+1]));
00231 if (!temp_tt) goto error;
00232 for (j = 0; j < t->n_leafs; j++)
00233 temp_tt[j] = t->leafs[j];
00234 temp_tt[t->n_leafs++] = leaf;
00235 temp2_tt = t->leafs;
00236 t->leafs = temp_tt;
00237 free (temp2_tt);
00238 } else if (!hastoken) {
00239 t->n_leafs = 1;
00240 t->leafs = (introspect_objs_tree **)
00241 malloc (sizeof (introspect_objs_tree [t->n_leafs]));
00242 if (!t->leafs) goto error;
00243 t->leafs[0] = leaf;
00244 }
00245 next = leaf;
00246 leaf = NULL;
00247 hastoken = 0;
00248 }
00249 return 0;
00250 error:
00251 if (leaf)
00252 easydbus_introspect_obj_tree_free (leaf);
00253 return -1;
00254 }
00255
00263 int
00264 easydbus_introspect_objs_tree_destroy (introspect_objs_tree *tree)
00265 {
00266 unsigned int i;
00267
00268 if (!tree) return -1;
00269
00270 for (i = 0; i < tree->n_leafs; i++)
00271 easydbus_introspect_objs_tree_destroy (tree->leafs[i]);
00272
00273 easydbus_introspect_obj_tree_free (tree);
00274 return 0;
00275 }
00276
00285 inline introspect_objs_tree *
00286 easydbus_introspect_obj_tree_hastoken (introspect_objs_tree *tree,
00287 char *token)
00288 {
00289 unsigned int i;
00290
00291 if (tree && token)
00292 for (i = 0; i < tree->n_leafs; i++)
00293 if (!strcmp (tree->leafs[i]->leaf_name, token))
00294 return tree->leafs[i];
00295
00296 return NULL;
00297 }
00298
00299
00300
00306 void inline
00307 easydbus_free_introspect_info_arg (struct easydbus_introspect_arg_info *arg)
00308 {
00309 if (!arg)
00310 return;
00311
00312 if (arg->name)
00313 free (arg->name);
00314
00315 if (arg->signature)
00316 free (arg->signature);
00317
00318 free (arg);
00319 }
00320
00330 int
00331 easydbus_add_new_field_to_list (struct easydbus_introspect_arg_info *el,
00332 struct easydbus_introspect_arg_info **list)
00333 {
00334 struct easydbus_introspect_arg_info *prev, *current;
00335
00336 if (el == NULL || list == NULL)
00337 return -1;
00338
00339 if (*list == NULL) {
00340
00341 *list = el;
00342 return 0;
00343 }
00344
00345 prev = NULL;
00346 current = *list;
00347 while (current != NULL) {
00348 if (el->offset < current->offset) {
00349 el->next = current;
00350 if (prev != NULL)
00351 prev->next = el;
00352 else
00353 *list = el;
00354 return 0;
00355 }
00356 prev = current;
00357 current = current->next;
00358 }
00359
00360 prev->next = el;
00361 return 0;
00362 }
00363
00374 inline int
00375 easydbus_introspect_get_ntoken (char *name, int l)
00376 {
00377 int i, n;
00378
00379 for (i = 0, n = 0; name[i] != '\0'; i++)
00380 if ((i != (l-1)) && name[i] == '/')
00381 n++;
00382 return n;
00383 }
00384
00396 int
00397 easydbus_introspect_set_object_buffer (struct EasyDbus_object_box * obj,
00398 char *istring, int *offset)
00399 {
00400 EasyDbus_obj_interface *interface = NULL;
00401 int i_string_l = 0;
00402
00403
00404 for (interface = obj->core.handled_interfaces;
00405 interface; interface = interface->next)
00406 if (easydbus_introspect_set_interface_buffer (interface,
00407 istring, offset))
00408 return -1;
00409 i_string_l = *offset;
00410
00411
00412 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00413 EASYDBUS_INTROSPECT_XML_INTERFACE_DATA,
00414 strlen (EASYDBUS_INTROSPECT_XML_INTERFACE_DATA));
00415
00416 *offset = i_string_l;
00417
00418 return 0;
00419 }
00420
00434 int
00435 easydbus_introspect_set_reply_buffer (char *istring,
00436 char *req_path,
00437 introspect_objs_tree *t,
00438 struct EasyDbus_object_box * obj,
00439 unsigned int obj_path)
00440 {
00441 int offset = 0, ntoken = 0;
00442 unsigned int i;
00443 char *token = NULL, *saveptr, *tmp_path;
00444 introspect_objs_tree *i_t;
00445
00446 EasyDbusDebug ("Insert data on buffer (%p) for request %s (%d)",
00447 istring, req_path, obj_path);
00448
00449
00450 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00451 EASYDBUS_INTROSPECT_MSG,
00452 strlen (EASYDBUS_INTROSPECT_MSG));
00453
00454
00455 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00456 EASYDBUS_INTROSPECT_MSG_COMMENT,
00457 strlen (EASYDBUS_INTROSPECT_MSG_COMMENT));
00458
00459
00460 if (!strcmp ("/", req_path)) {
00461
00462 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00463 EASYDBUS_INTROSPECT_NODE_TAG_O,
00464 EASYDBUS_INTROSPECT_NODE_TAG_O_L);
00465
00466
00467 for (i = 0; i < t->n_leafs; i++) {
00468 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00469 EASYDBUS_INTROSPECT_NODE_TAG_INIT,
00470 EASYDBUS_INTROSPECT_NODE_TAG_INIT_L);
00471 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00472 t->leafs[i]->leaf_name,
00473 strlen(t->leafs[i]->leaf_name));
00474
00475 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00476 EASYDBUS_INTROSPECT_TAG_END,
00477 EASYDBUS_INTROSPECT_TAG_END_L);
00478 }
00479
00480 } else {
00481 if (obj_path) {
00482
00483 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00484 EASYDBUS_INTROSPECT_NODE_TAG_INIT2,
00485 EASYDBUS_INTROSPECT_NODE_TAG_INIT2_L);
00486
00487 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00488 req_path, strlen (req_path));
00489
00490 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00491 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C,
00492 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L);
00493 } else {
00494
00495 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00496 EASYDBUS_INTROSPECT_NODE_TAG_O,
00497 EASYDBUS_INTROSPECT_NODE_TAG_O_L);
00498 }
00499
00500 ntoken = easydbus_introspect_get_ntoken (req_path,
00501 strlen (req_path));
00502 tmp_path = (char *) malloc (strlen (req_path) + 1);
00503 if (!tmp_path) return -1;
00504 EASYDBUS_MEMCOPY (tmp_path, req_path, strlen (req_path) + 1);
00505
00506
00507 for (i = 0, token = strtok_r (tmp_path, "/", &saveptr),
00508 i_t = t; (int) i < ntoken; i++,
00509 token = strtok_r (saveptr, "/", &saveptr)) {
00510 EasyDbusDebug ("token[%d] = %s, leafs = %d",
00511 i, token, i_t->n_leafs);
00512 i_t = easydbus_introspect_obj_tree_hastoken (i_t, token);
00513 }
00514 free (tmp_path);
00515
00516
00517 if (obj_path)
00518 if (easydbus_introspect_set_object_buffer (i_t->obj, istring,
00519 &offset))
00520 return -1;
00521
00522
00523 for (i = 0; i < i_t->n_leafs; i++) {
00524 EasyDbusDebug ("insert leaf[%d] %s",i,
00525 i_t->leafs[i]->leaf_name);
00526 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00527 EASYDBUS_INTROSPECT_NODE_TAG_INIT,
00528 EASYDBUS_INTROSPECT_NODE_TAG_INIT_L);
00529 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00530 i_t->leafs[i]->leaf_name,
00531 strlen (i_t->leafs[i]->leaf_name));
00532 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00533 EASYDBUS_INTROSPECT_TAG_END,
00534 EASYDBUS_INTROSPECT_TAG_END_L);
00535 }
00536
00537 }
00538
00539 EASYDBUS_INTROSPECT_MEMCOPY (istring, offset,
00540 EASYDBUS_INTROSPECT_NODE_TAG_C,
00541 EASYDBUS_INTROSPECT_NODE_TAG_C_L);
00542
00543
00544 memset (&istring[offset++], 0, 1);
00545 EasyDbusDebug ("Created introspect string (offset %d) %s\n",
00546 offset, istring);
00547 return 0;
00548 }
00549
00563 int
00564 easydbus_introspect_set_interface_buffer (EasyDbus_obj_interface *interface,
00565 char *istring, int *offset)
00566 {
00567 EasyDbus_obj_method *method = NULL;
00568 EasyDbus_obj_signal *signal = NULL;
00569 struct easydbus_introspect_arg_info *el = NULL;
00570 int i_string_l = *offset;
00571
00572 if (!istring || !offset || !interface)
00573 return -1;
00574
00575
00576 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00577 EASYDBUS_INTROSPECT_INTERFACE_TAG_O,
00578 EASYDBUS_INTROSPECT_INTERFACE_TAG_O_L);
00579 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00580 interface->name, strlen (interface->name));
00581 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00582 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C,
00583 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L);
00584
00585 for (method = interface->handled_methods; method;
00586 method = method->next)
00587
00588 if (method->input_info || method->output_info) {
00589
00590 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00591 EASYDBUS_INTROSPECT_METHOD_TAG_O,
00592 EASYDBUS_INTROSPECT_METHOD_TAG_O_L);
00593 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00594 method->name, strlen (method->name));
00595 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00596 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C,
00597 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L);
00598
00599
00600 for (el = method->input_info; el; el = el->next) {
00601 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00602 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O,
00603 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L);
00604 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00605 el->name, strlen (el->name));
00606 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00607 EASYDBUS_INTROSPECT_ARG_SPACE,
00608 EASYDBUS_INTROSPECT_ARG_SPACE_L);
00609 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00610 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O,
00611 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L);
00612 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00613 el->signature, strlen (el->signature));
00614 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00615 EASYDBUS_INTROSPECT_ARG_SPACE,
00616 EASYDBUS_INTROSPECT_ARG_SPACE_L);
00617 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00618 EASYDBUS_INTROSPECT_ARG_DIRECTION_O,
00619 EASYDBUS_INTROSPECT_ARG_DIRECTION_O_L);
00620 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00621 EASYDBUS_INTROSPECT_DIRECTION_IN,
00622 EASYDBUS_INTROSPECT_DIRECTION_IN_L);
00623 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00624 EASYDBUS_INTROSPECT_TAG_END,
00625 EASYDBUS_INTROSPECT_TAG_END_L);
00626 }
00627
00628
00629 for (el = method->output_info; el; el = el->next) {
00630 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00631 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O,
00632 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L);
00633 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00634 el->name, strlen (el->name));
00635 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00636 EASYDBUS_INTROSPECT_ARG_SPACE,
00637 EASYDBUS_INTROSPECT_ARG_SPACE_L);
00638 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00639 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O,
00640 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L);
00641 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00642 el->signature, strlen (el->signature));
00643 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00644 EASYDBUS_INTROSPECT_ARG_SPACE,
00645 EASYDBUS_INTROSPECT_ARG_SPACE_L);
00646 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00647 EASYDBUS_INTROSPECT_ARG_DIRECTION_O,
00648 EASYDBUS_INTROSPECT_ARG_DIRECTION_O_L);
00649 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00650 EASYDBUS_INTROSPECT_DIRECTION_OUT,
00651 EASYDBUS_INTROSPECT_DIRECTION_OUT_L);
00652 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00653 EASYDBUS_INTROSPECT_TAG_END,
00654 EASYDBUS_INTROSPECT_TAG_END_L);
00655 }
00656
00657 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00658 EASYDBUS_INTROSPECT_METHOD_TAG_C,
00659 EASYDBUS_INTROSPECT_METHOD_TAG_C_L);
00660 }
00661
00662 for (signal = interface->handled_signals; signal;
00663 signal = signal->next)
00664
00665 if (signal->output_info) {
00666
00667 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00668 EASYDBUS_INTROSPECT_SIGNAL_TAG_O,
00669 EASYDBUS_INTROSPECT_SIGNAL_TAG_O_L);
00670 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00671 signal->name, strlen (signal->name));
00672 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00673 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C,
00674 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L);
00675
00676
00677 for (el = signal->output_info; el; el = el->next) {
00678 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00679 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O,
00680 EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L);
00681 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00682 el->name, strlen (el->name));
00683 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00684 EASYDBUS_INTROSPECT_ARG_SPACE,
00685 EASYDBUS_INTROSPECT_ARG_SPACE_L);
00686 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00687 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O,
00688 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L);
00689 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00690 el->signature, strlen (el->signature));
00691 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00692 EASYDBUS_INTROSPECT_TAG_END,
00693 EASYDBUS_INTROSPECT_TAG_END_L);
00694 }
00695
00696
00697 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00698 EASYDBUS_INTROSPECT_SIGNAL_TAG_C,
00699 EASYDBUS_INTROSPECT_SIGNAL_TAG_C_L);
00700 }
00701
00702
00703 EASYDBUS_INTROSPECT_MEMCOPY (istring, i_string_l,
00704 EASYDBUS_INTROSPECT_INTERFACE_TAG_C,
00705 EASYDBUS_INTROSPECT_INTERFACE_TAG_C_L);
00706
00707 *offset = i_string_l;
00708 return 0;
00709 }
00710
00722 char *
00723 easydbus_introspect_create_reply_string (char *req_path,
00724 introspect_objs_tree *t,
00725 struct EasyDbus_object_box *obj)
00726 {
00727 int istring_length = 0;
00728 unsigned int obj_dest_path = 0;
00729 char *buffer = NULL;
00730
00731 if (!req_path || !t || !obj)
00732 return NULL;
00733
00734 istring_length = easydbus_introspect_get_reply_length (req_path,
00735 t, obj,
00736 &obj_dest_path);
00737 if (istring_length <= 0)
00738 return NULL;
00739 EasyDbusDebug ("Introspect reply string length = %d\n", istring_length);
00740
00741 buffer = (char *) malloc (istring_length);
00742 if (!buffer) return NULL;
00743 memset (buffer, 0, istring_length);
00744
00745 if (easydbus_introspect_set_reply_buffer (buffer, req_path, t,
00746 obj, obj_dest_path))
00747 goto error;
00748
00749 return buffer;
00750 error:
00751 if (buffer)
00752 free (buffer);
00753 return NULL;
00754 }
00755
00764 inline char *
00765 easydbus_create_arg_signature
00766 (struct easydbus_signature_elem_stack *list)
00767 {
00768 char *signature = NULL;
00769 struct easydbus_signature_elem_stack *tmp_elem = NULL;
00770
00771 while (list != NULL) {
00772 if (easydbus_manage_list_signature (list,
00773 &signature,
00774 EASYDBUS_SIGNATURE_NORMAL))
00775 goto error;
00776 tmp_elem = list->next;
00777 easydbus_free_elem_from_stack (list);
00778 list = tmp_elem;
00779 }
00780
00781 EasyDbusDebug ("signature created for arg = %s", signature);
00782 return signature;
00783 error:
00784 if (signature != NULL)
00785 free (signature);
00786 return NULL;
00787 }
00788
00798 DBusHandlerResult
00799 easydbus_introspect_filter_func (DBusConnection * conn,
00800 DBusMessage * msg,
00801 void *user_data)
00802 {
00803 struct EasyDbus_core *core = (struct EasyDbus_core *) user_data;
00804 struct EasyDbus_object_box *objects = NULL;
00805 const char *msg_member = NULL;
00806 const char *msg_interface = NULL;
00807 const char *msg_path = NULL;
00808 const char *msg_sender = NULL;
00809 introspect_objs_tree *tree = NULL;
00810 char *introspect_string = NULL;
00811 struct EasyDbus_reply *reply = NULL;
00812
00813 if (conn == NULL || msg == NULL || user_data == NULL) {
00814 EasyDbusDebug ("Error");
00815 return DBUS_HANDLER_RESULT_HANDLED;
00816 }
00817
00818 objects = core->objects;
00819 EasyDbusDebug ("Message under filter analysis");
00820
00821
00822
00823 if (!dbus_message_is_method_call (msg,
00824 EASYDBUS_INTROSPECT_INTERFACE,
00825 EASYDBUS_INTROSPECT_METHOD))
00826 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00827
00828
00829
00830 msg_member = dbus_message_get_member (msg);
00831
00832 msg_interface = dbus_message_get_interface (msg);
00833
00834 msg_path = dbus_message_get_path (msg);
00835
00836 msg_sender = dbus_message_get_sender (msg);
00837
00838 EasyDbusDebug ("Introspect Request:\n"
00839 "Message %s with \n"
00840 "path = %s\n"
00841 "interface = %s\n"
00842 "member = %s\n",
00843 dbus_message_type_to_string (dbus_message_get_type (msg)),
00844 msg_path, msg_interface, msg_member);
00845
00846
00847 tree = easydbus_introspect_objs_tree_build (objects);
00848 if (!tree)
00849 goto error;
00850
00851 reply = easydbus_reply_create_skeleton ();
00852 if (reply == NULL)
00853 goto error;
00854
00855 introspect_string =
00856 easydbus_introspect_create_reply_string ((char *) msg_path,
00857 tree, objects);
00858
00859 if (!introspect_string) {
00860 EasyDbusDebug ("instrospect string null");
00861 goto error;
00862 }
00863
00864 reply->type = EASYDBUS_ET_REPLY;
00865 easydbus_add_string_param_to_skeleton (EASYDBUS_ET_REPLY,
00866 reply, introspect_string);
00867
00868 easydbus_reply_send (core, msg, reply);
00869 easydbus_reply_free_skeleton (reply);
00870 free (introspect_string);
00871 easydbus_introspect_objs_tree_destroy (tree);
00872 return DBUS_HANDLER_RESULT_HANDLED;
00873
00874 error:
00875 if (tree) easydbus_introspect_objs_tree_destroy (tree);
00876 if (introspect_string) free (introspect_string);
00877
00878 if (reply) easydbus_reply_free_skeleton (reply);
00879
00880 else
00881 return DBUS_HANDLER_RESULT_NEED_MEMORY;
00882
00883 if (easydbus_reply_send_error (core, msg,
00884 "Object Not Found",
00885 "Object request not founded"))
00886 return DBUS_HANDLER_RESULT_NEED_MEMORY;
00887
00888 return DBUS_HANDLER_RESULT_HANDLED;
00889 }
00890
00903 int
00904 easydbus_introspect_get_reply_length (char *path,
00905 introspect_objs_tree *t,
00906 struct EasyDbus_object_box *obj,
00907 unsigned int *obj_dest_path)
00908 {
00909 int istring_l = 0, ntoken = 0;
00910 char *tmp_path = NULL;
00911 char *token = NULL, *saveptr;
00912 unsigned int i, j;
00913 introspect_objs_tree *i_t;
00914
00915 if (!path || !t || !obj)
00916 return -1;
00917
00918
00919 istring_l = strlen (EASYDBUS_INTROSPECT_MSG) +
00920 strlen (EASYDBUS_INTROSPECT_MSG_COMMENT) + 1;
00921
00922 if (!strcmp ("/", path)) {
00923 istring_l += EASYDBUS_INTROSPECT_NODE_TAG_O_L;
00924 for (i = 0; i < t->n_leafs; i++)
00925
00926 istring_l += EASYDBUS_INTROSPECT_NODE_TAG_INIT_L +
00927 strlen(t->leafs[i]->leaf_name) +
00928 EASYDBUS_INTROSPECT_TAG_END_L;
00929 } else {
00930
00931 ntoken = easydbus_introspect_get_ntoken (path,
00932 strlen (path));
00933
00934 tmp_path = (char *) malloc (strlen (path)+1);
00935 if (!tmp_path)
00936 return -1;
00937 EASYDBUS_MEMCOPY (tmp_path, path, strlen (path) + 1);
00938
00939 for (i = 0, token = strtok_r(tmp_path, "/", &saveptr),
00940 i_t = t; (int) i < ntoken;
00941 token = strtok_r (saveptr, "/", &saveptr), i++) {
00942 i_t = easydbus_introspect_obj_tree_hastoken (i_t, token);
00943 if (!i_t)
00944 goto error;
00945 }
00946 if (i_t->obj) {
00947 *obj_dest_path = 1;
00948
00949 istring_l += easydbus_introspect_get_obj_string_length (i_t->obj) +
00950 EASYDBUS_INTROSPECT_NODE_TAG_INIT2_L +
00951 strlen (path) +
00952 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L;
00953 } else
00954 istring_l += EASYDBUS_INTROSPECT_NODE_TAG_O_L;
00955
00956 for (j = 0; j < i_t->n_leafs; j++)
00957 istring_l += strlen (i_t->leafs[j]->leaf_name) +
00958 EASYDBUS_INTROSPECT_NODE_TAG_INIT_L +
00959 EASYDBUS_INTROSPECT_TAG_END_L;
00960 free (tmp_path);
00961 }
00962
00963 istring_l += EASYDBUS_INTROSPECT_NODE_TAG_C_L;
00964 return istring_l;
00965
00966 error:
00967 if (tmp_path)
00968 free (tmp_path);
00969 return -1;
00970 }
00971
00980 int
00981 easydbus_introspect_get_obj_string_length (struct EasyDbus_object_box *obj)
00982 {
00983 int i_string_l = 0, i;
00984 EasyDbus_obj_interface *interface = NULL;
00985
00986
00987 for (i = 0, interface = obj->core.handled_interfaces;
00988 i < obj->core.n_interfaces && interface;
00989 i++, interface = interface->next)
00990 i_string_l +=
00991 easydbus_introspect_get_interface_string_length (interface);
00992
00993
00994 i_string_l += strlen(EASYDBUS_INTROSPECT_XML_INTERFACE_DATA);
00995
00996 return i_string_l;
00997 }
00998
01007 int
01008 easydbus_introspect_get_interface_string_length (EasyDbus_obj_interface *interface)
01009 {
01010 EasyDbus_obj_method *method = NULL;
01011 EasyDbus_obj_signal *signal = NULL;
01012 struct easydbus_introspect_arg_info *el = NULL;
01013 int i_string_l = 0;
01014
01015 if (!interface)
01016 return -1;
01017
01018
01019 i_string_l = EASYDBUS_INTROSPECT_INTERFACE_TAG_O_L +
01020 strlen (interface->name) +
01021 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L +
01022 EASYDBUS_INTROSPECT_INTERFACE_TAG_C_L;
01023
01024 for (method = interface->handled_methods; method;
01025 method = method->next)
01026 if (method->input_info || method->output_info) {
01027
01028 i_string_l += EASYDBUS_INTROSPECT_METHOD_TAG_O_L +
01029 strlen (method->name) +
01030 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L +
01031 EASYDBUS_INTROSPECT_METHOD_TAG_C_L;
01032 for (el = method->input_info; el; el = el->next)
01033
01034 i_string_l += EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L +
01035 strlen (el->name) +
01036 EASYDBUS_INTROSPECT_ARG_SPACE_L +
01037 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L +
01038 strlen (el->signature) +
01039 EASYDBUS_INTROSPECT_ARG_SPACE_L +
01040 EASYDBUS_INTROSPECT_ARG_DIRECTION_O_L +
01041 EASYDBUS_INTROSPECT_DIRECTION_IN_L +
01042 EASYDBUS_INTROSPECT_TAG_END_L;
01043 for (el = method->output_info; el; el = el->next)
01044
01045 i_string_l += EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L +
01046 strlen (el->name) +
01047 EASYDBUS_INTROSPECT_ARG_SPACE_L +
01048 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L +
01049 strlen (el->signature) +
01050 EASYDBUS_INTROSPECT_ARG_SPACE_L +
01051 EASYDBUS_INTROSPECT_ARG_DIRECTION_O_L +
01052 EASYDBUS_INTROSPECT_DIRECTION_OUT_L +
01053 EASYDBUS_INTROSPECT_TAG_END_L;
01054 }
01055
01056 for (signal = interface->handled_signals; signal;
01057 signal = signal->next)
01058 if (signal->output_info) {
01059
01060 i_string_l += EASYDBUS_INTROSPECT_SIGNAL_TAG_O_L +
01061 strlen (signal->name) +
01062 EASYDBUS_INTROSPECT_NODE_TAG_INIT_C_L +
01063 EASYDBUS_INTROSPECT_SIGNAL_TAG_C_L;
01064 for (el = signal->output_info; el; el = el->next)
01065
01066 i_string_l += EASYDBUS_INTROSPECT_ARG_NAME_TAG_O_L +
01067 strlen (el->name) +
01068 EASYDBUS_INTROSPECT_ARG_SPACE_L +
01069 EASYDBUS_INTROSPECT_ARG_TYPE_TAG_O_L +
01070 strlen (el->signature) +
01071 EASYDBUS_INTROSPECT_TAG_END_L;
01072 }
01073
01074 return i_string_l;
01075 }
01076
01077