static void render_page(ImpRenderCtx *ctx, void *drw_data) { iks *x; char *element; int i; i = _imp_fill_back(ctx, drw_data, ctx->page->page); element = iks_find_attrib(ctx->page->page, "draw:master-page-name"); if (element) { x = iks_find_with_attrib( iks_find(ctx->page->doc->styles, "office:master-styles"), "style:master-page", "style:name", element ); if (x) { if (i == 0) _imp_fill_back(ctx, drw_data, x); for (x = iks_first_tag(x); x; x = iks_next_tag(x)) { if (iks_find_attrib(x, "presentation:class")) continue; render_object(ctx, drw_data, x); } } } for (x = iks_first_tag(ctx->page->page); x; x = iks_next_tag(x)) { render_object(ctx, drw_data, x); } }
static void add_groups(iks *tag, int class_no, int level, struct acl_class *ac) { iks *x; // global permissions for (x = iks_find(tag, "group"); x; x = iks_next_tag(x)) { if (iks_strcmp(iks_name(x), "group") == 0) add_group(x, level, ac); } // class permissions x = iks_find_with_attrib(tag, "class", "name", model_get_path(class_no)); for (x = iks_find(x, "group"); x; x = iks_next_tag(x)) { if (iks_strcmp(iks_name(x), "group") == 0) add_group(x, level, ac); } }
int _imp_oasis_load(ImpDoc *doc) { ImpPage *page; iks *x, *pres; int i; pres = iks_find(iks_find(doc->content, "office:body"), "office:presentation"); if (!pres) return IMP_NOTIMP; x = iks_find(pres, "draw:page"); if (!x) return IMP_NOTIMP; i = 0; for (; x; x = iks_next_tag(x)) { if (strcmp(iks_name(x), "draw:page") == 0) { page = iks_stack_alloc(doc->stack, sizeof(ImpPage)); if (!page) return IMP_NOMEM; memset(page, 0, sizeof(ImpPage)); page->page = x; page->nr = ++i; page->name = iks_find_attrib(x, "draw:name"); page->doc = doc; if (!doc->pages) doc->pages = page; page->prev = doc->last_page; if (doc->last_page) doc->last_page->next = page; doc->last_page = page; } } doc->nr_pages = i; doc->get_geometry = get_geometry; doc->render_page = render_page; return 0; }
static int count_groups(iks *tag, int class_no) { iks *x; unsigned int nr = 0; // global permissions for (x = iks_find(tag, "group"); x; x = iks_next_tag(x)) { if (iks_strcmp(iks_name(x), "group") == 0) ++nr; } // class permissions x = iks_find_with_attrib(tag, "class", "name", model_get_path(class_no)); for (x = iks_find(x, "group"); x; x = iks_next_tag(x)) { if (iks_strcmp(iks_name(x), "group") == 0) ++nr; } return nr; }
static int iks_sasl_mechanisms (iks *x) { int sasl_mech = 0; while (x) { if (!iks_strcmp(iks_cdata(iks_child(x)), "DIGEST-MD5")) sasl_mech |= IKS_STREAM_SASL_MD5; else if (!iks_strcmp(iks_cdata(iks_child(x)), "PLAIN")) sasl_mech |= IKS_STREAM_SASL_PLAIN; x = iks_next_tag(x); } return sasl_mech; }
int iks_stream_features (iks *x) { int features = 0; if (iks_strcmp(iks_name(x), "stream:features")) return 0; for (x = iks_child(x); x; x = iks_next_tag(x)) if (!iks_strcmp(iks_name(x), "starttls")) features |= IKS_STREAM_STARTTLS; else if (!iks_strcmp(iks_name(x), "bind")) features |= IKS_STREAM_BIND; else if (!iks_strcmp(iks_name(x), "session")) features |= IKS_STREAM_SESSION; else if (!iks_strcmp(iks_name(x), "mechanisms")) features |= iks_sasl_mechanisms(iks_child(x)); return features; }
/** * Create new output component */ static struct rayo_component *create_output_component(struct rayo_actor *actor, const char *type, iks *output, const char *client_jid) { switch_memory_pool_t *pool; struct output_component *output_component = NULL; switch_core_new_memory_pool(&pool); output_component = switch_core_alloc(pool, sizeof(*output_component)); output_component = OUTPUT_COMPONENT(rayo_component_init((struct rayo_component *)output_component, pool, type, "output", NULL, actor, client_jid)); if (output_component) { output_component->document = iks_copy(output); output_component->start_offset_ms = iks_find_int_attrib(output, "start-offset"); output_component->repeat_interval_ms = iks_find_int_attrib(output, "repeat-interval"); output_component->repeat_times = iks_find_int_attrib(output, "repeat-times"); output_component->max_time_ms = iks_find_int_attrib(output, "max-time"); output_component->start_paused = iks_find_bool_attrib(output, "start-paused"); output_component->renderer = switch_core_strdup(RAYO_POOL(output_component), iks_find_attrib_soft(output, "renderer")); /* get custom headers */ { switch_stream_handle_t headers = { 0 }; iks *header = NULL; int first = 1; SWITCH_STANDARD_STREAM(headers); for (header = iks_find(output, "header"); header; header = iks_next_tag(header)) { if (!strcmp("header", iks_name(header))) { const char *name = iks_find_attrib_soft(header, "name"); const char *value = iks_find_attrib_soft(header, "value"); if (!zstr(name) && !zstr(value)) { headers.write_function(&headers, "%s%s=%s", first ? "{" : ",", name, value); first = 0; } } } if (headers.data) { headers.write_function(&headers, "}"); output_component->headers = switch_core_strdup(RAYO_POOL(output_component), (char *)headers.data); free(headers.data); } } } else { switch_core_destroy_memory_pool(&pool); } return RAYO_COMPONENT(output_component); }
/** * open next file for reading * @param handle the file handle */ static switch_status_t next_file(switch_file_handle_t *handle) { int loops = 0; struct rayo_file_context *context = handle->private_info; struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL; top: if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { /* unsupported */ return SWITCH_STATUS_FALSE; } if (!context->cur_doc) { context->cur_doc = iks_find(output->document, "document"); if (!context->cur_doc) { iks_delete(output->document); output->document = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document>\n"); return SWITCH_STATUS_FALSE; } } else { context->cur_doc = iks_next_tag(context->cur_doc); } /* done? */ if (!context->cur_doc) { if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) { /* repeat all document(s) */ if (!output->repeat_interval_ms) { goto top; } } else { /* no more files to play */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n"); return SWITCH_STATUS_FALSE; } } if (!context->cur_doc) { /* play silence between repeats */ switch_safe_free(context->ssml); context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms); } else { /* play next document */ iks *speak = NULL; switch_safe_free(context->ssml); context->ssml = NULL; speak = iks_find(context->cur_doc, "speak"); if (speak) { /* <speak> is child node */ char *ssml_str = iks_string(NULL, speak); if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } iks_free(ssml_str); } else if (iks_has_children(context->cur_doc)) { /* check if <speak> is in CDATA */ const char *ssml_str = NULL; iks *ssml = iks_child(context->cur_doc); if (ssml && iks_type(ssml) == IKS_CDATA) { ssml_str = iks_cdata(ssml); } if (zstr(ssml_str)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document> CDATA\n"); return SWITCH_STATUS_FALSE; } if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <speak>\n"); return SWITCH_STATUS_FALSE; } } if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml); goto top; } else { context->could_open = 1; } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->vol = context->fh.vol; handle->offset_pos = context->fh.offset_pos; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } return SWITCH_STATUS_SUCCESS; }
/** * Start CPA */ iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data) { iks *iq = msg->payload; switch_core_session_t *session = (switch_core_session_t *)session_data; iks *input = iks_find(iq, "input"); switch_memory_pool_t *pool = NULL; struct cpa_component *component = NULL; int have_grammar = 0; iks *grammar = NULL; /* create CPA component */ switch_core_new_memory_pool(&pool); component = switch_core_alloc(pool, sizeof(*component)); component = CPA_COMPONENT(rayo_component_init((struct rayo_component *)component, pool, RAT_CALL_COMPONENT, "cpa", NULL, call, iks_find_attrib(iq, "from"))); if (!component) { switch_core_destroy_memory_pool(&pool); return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create CPA entity"); } switch_core_hash_init(&component->signals); /* start CPA detectors */ for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) { if (!strcmp("grammar", iks_name(grammar))) { const char *error_str = ""; const char *url = iks_find_attrib_soft(grammar, "url"); char *url_dup; char *url_params; if (zstr(url)) { stop_cpa_detectors(component); RAYO_UNLOCK(component); RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing grammar URL"); } have_grammar = 1; url_dup = strdup(url); if ((url_params = strchr(url_dup, '?'))) { *url_params = '\0'; url_params++; } if (switch_core_hash_find(component->signals, url)) { free(url_dup); stop_cpa_detectors(component); RAYO_UNLOCK(component); RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Duplicate URL"); } /* start detector */ /* TODO return better reasons... */ if (rayo_cpa_detector_start(switch_core_session_get_uuid(session), url_dup, &error_str)) { struct cpa_signal *cpa_signal = switch_core_alloc(pool, sizeof(*cpa_signal)); cpa_signal->terminate = !zstr(url_params) && strstr(url_params, "terminate=true"); cpa_signal->name = switch_core_strdup(pool, url_dup); switch_core_hash_insert(component->signals, cpa_signal->name, cpa_signal); subscribe(switch_core_session_get_uuid(session), cpa_signal->name, RAYO_JID(component)); } else { free(url_dup); stop_cpa_detectors(component); RAYO_UNLOCK(component); RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, error_str); } free(url_dup); } } if (!have_grammar) { stop_cpa_detectors(component); RAYO_UNLOCK(component); RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "No grammar defined"); } /* acknowledge command */ rayo_component_send_start(RAYO_COMPONENT(component), iq); /* TODO hangup race condition */ subscribe(switch_core_session_get_uuid(session), "hangup", RAYO_JID(component)); /* ready to forward detector events */ component->ready = 1; return NULL; }
//! Imports model file static int model_import(const char *model_file) { /*! * Imports model file to node table. * * @model_file File to import * @return 0 on success, -1 on error */ iks *obj, *met; size_t size = 0; size_t obj_size, met_size; int obj_no; int count = 0; int e; e = iks_load(model_file, &model_xml); if (e != 0) { log_error("XML load error.\n"); return -1; } if (iks_strcmp(iks_name(model_xml), "comarModel") != 0) { log_error("Bad XML: not a Comar model.\n"); return -1; } // scan the model for (obj = iks_first_tag(model_xml); obj; obj = iks_next_tag(obj)) { if (iks_strcmp(iks_name(obj), "interface") == 0) { obj_size = iks_strlen(iks_find_attrib(obj, "name")); if (!obj_size) { log_error("Bad XML: interface has no name.\n"); return -1; } size += obj_size + 1; ++count; for (met = iks_first_tag(obj); met; met = iks_next_tag(met)) { if (iks_strcmp(iks_name(met), "method") == 0 || iks_strcmp(iks_name(met), "signal") == 0) { met_size = iks_strlen(iks_find_attrib(met, "name")); if (!met_size) { log_error("Bad XML: method/signal has no name.\n"); return -1; } size += obj_size + 1 + met_size + 1; ++count; iks *arg; for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "arg") != 0 && iks_strcmp(iks_name(arg), "annotation") != 0) { log_error("Bad XML: method/signal may contain <arg> or <annotation> only\n"); return -1; } } } else { log_error("Bad XML: interface may contain <method> or <signal> only\n"); return -1; } } } else { log_error("Bad XML: root node may contain <interface> only\n"); return -1; } } // size is counted to alloc mem for paths // prepare data structures if (prepare_tables(count, size) != 0) return -1; // load model for (obj = iks_first_tag(model_xml); obj; obj = iks_next_tag(obj)) { if (iks_strcmp(iks_find_attrib(obj, "name"), "Comar") == 0) { continue; } obj_no = add_node(-1, build_path(obj, NULL), "", N_INTERFACE); for (met = iks_first_tag(obj); met; met = iks_next_tag(met)) { if (iks_strcmp(iks_name(met), "method") == 0) { char *label = iks_find_attrib(met, "access_label"); if (label) { iks_insert_attrib(met, "access_label", NULL); } else { label = iks_find_attrib(met, "name"); } add_node(obj_no, build_path(obj, met), label, N_METHOD); } else if (iks_strcmp(iks_name(met), "signal") == 0) { add_node(obj_no, build_path(obj, met), "", N_SIGNAL); } } } return 0; }
static void render_object(ImpRenderCtx *ctx, void *drw_data, iks *node) { char *tag, *t; ImpColor fg; tag = iks_name(node); if (strcmp(tag, "draw:g") == 0) { iks *x; for (x = iks_first_tag(node); x; x = iks_next_tag(x)) { render_object(ctx, drw_data, x); } } else if (strcmp(tag, "draw:frame") == 0) { iks *x; for (x = iks_first_tag(node); x; x = iks_next_tag(x)) { render_object(ctx, drw_data, x); } } else if (strcmp(tag, "draw:line") == 0) { r_get_color(ctx, node, "svg:stroke-color", &fg); ctx->drw->set_fg_color(drw_data, &fg); ctx->drw->draw_line(drw_data, r_get_x(ctx, node, "svg:x1"), r_get_y(ctx, node, "svg:y1"), r_get_x(ctx, node, "svg:x2"), r_get_y(ctx, node, "svg:y2") ); } else if (strcmp(tag, "draw:rect") == 0) { int x, y, w, h, r = 0; char *t; x = r_get_x(ctx, node, "svg:x"); y = r_get_y(ctx, node, "svg:y"); w = r_get_x(ctx, node, "svg:width"); h = r_get_y(ctx, node, "svg:height"); t = r_get_style(ctx, node, "draw:corner-radius"); if (t) r = atof(t) * ctx->fact_x; if (r_get_style(ctx, node, "draw:fill")) { r_get_color(ctx, node, "draw:fill-color", &fg); ctx->drw->set_fg_color(drw_data, &fg); _imp_draw_rect(ctx, drw_data, 1, x, y, w, h, r); } r_get_color(ctx, node, "svg:stroke-color", &fg); ctx->drw->set_fg_color(drw_data, &fg); _imp_draw_rect(ctx, drw_data, 0, x, y, w, h, r); r_text(ctx, drw_data, node); } else if (strcmp(tag, "draw:ellipse") == 0 || strcmp(tag, "draw:circle") == 0) { int sa, ea, fill = 0; r_get_color(ctx, node, "svg:stroke-color", &fg); sa = r_get_angle(node, "draw:start-angle", 0); ea = r_get_angle(node, "draw:end-angle", 360); if (ea > sa) ea = ea - sa; else ea = 360 + ea - sa; t = r_get_style(ctx, node, "draw:fill"); if (t) fill = 1; ctx->drw->set_fg_color(drw_data, &fg); ctx->drw->draw_arc(drw_data, fill, r_get_x(ctx, node, "svg:x"), r_get_y(ctx, node, "svg:y"), r_get_x(ctx, node, "svg:width"), r_get_y(ctx, node, "svg:height"), sa, ea ); } else if (strcmp(tag, "draw:polygon") == 0) { // FIXME: r_polygon(ctx, drw_data, node); } else if (strcmp(tag, "draw:text-box") == 0) { // FIXME: r_text(ctx, drw_data, node); } else if (strcmp(tag, "draw:image") == 0) { char *name; name = iks_find_attrib(node, "xlink:href"); if (!name) return; if (name[0] == '#') ++name; _imp_draw_image(ctx, drw_data, name, r_get_x(ctx, node, "svg:x"), r_get_y(ctx, node, "svg:y"), r_get_x(ctx, node, "svg:width"), r_get_y(ctx, node, "svg:height") ); } else { printf("Unknown element: %s\n", tag); } }
int model_init(void) { iks *model; iks *grp, *obj, *met; int count = 0; size_t size = 0; size_t grp_size, obj_size, met_size; int grp_no, obj_no; int e; // parse model file e = iks_load(cfg_model_file, &model); if (e) { log_error("Cannot process model file '%s'\n", cfg_model_file); return -1; } if (iks_strcmp(iks_name(model), "comarModel") != 0) { log_error("Not a COMAR model file '%s'\n", cfg_model_file); return -1; } // FIXME: ugly code ahead, split into functions and simplify // scan the model for (grp = iks_first_tag(model); grp; grp = iks_next_tag(grp)) { if (iks_strcmp(iks_name(grp), "group") == 0) { grp_size = iks_strlen(iks_find_attrib(grp, "name")); if (!grp_size) { log_error("Broken COMAR model file '%s'\n", cfg_model_file); return -1; } size += grp_size + 1; ++count; for (obj = iks_first_tag(grp); obj; obj = iks_next_tag(obj)) { if (iks_strcmp(iks_name(obj), "class") == 0) { obj_size = iks_strlen(iks_find_attrib(obj, "name")); if (!obj_size) { log_error("Broken COMAR model file '%s'\n", cfg_model_file); return -1; } size += grp_size + obj_size + 2; ++count; for (met = iks_first_tag(obj); met; met = iks_next_tag(met)) { if (iks_strcmp(iks_name(met), "method") == 0 || iks_strcmp(iks_name(met), "notify") == 0) { met_size = iks_strlen(iks_find_attrib(met, "name")); if (!met_size) { log_error("Broken COMAR model file '%s'\n", cfg_model_file); return -1; } size += grp_size + obj_size + met_size + 3; ++count; } if (iks_strcmp(iks_name(met), "method") == 0) { iks *arg; for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "argument") == 0 || iks_strcmp(iks_name(arg), "instance") == 0) { size += iks_cdata_size(iks_child(arg)) + 1; } } } } } } } } // prepare data structures if (prepare_tables(count, size)) return -1; // load the model for (grp = iks_first_tag(model); grp; grp = iks_next_tag(grp)) { if (iks_strcmp(iks_name(grp), "group") == 0) { grp_no = add_node(-1, build_path(grp, NULL, NULL), N_GROUP); for (obj = iks_first_tag(grp); obj; obj = iks_next_tag(obj)) { if (iks_strcmp(iks_name(obj), "class") == 0) { obj_no = add_node(grp_no, build_path(grp, obj, NULL), N_CLASS); for (met = iks_first_tag(obj); met; met = iks_next_tag(met)) { int no; if (iks_strcmp(iks_name(met), "method") == 0) { iks *arg; char *prof; no = add_node(obj_no, build_path(grp, obj, met), N_METHOD); prof = iks_find_attrib(met, "access"); if (prof) { if (strcmp(prof, "user") == 0) nodes[no].level = ACL_USER; if (strcmp(prof, "guest") == 0) nodes[no].level = ACL_GUEST; } prof = iks_find_attrib(met, "profile"); if (prof) { if (strcmp(prof, "global") == 0) nodes[no].flags |= P_GLOBAL; if (strcmp(prof, "package") == 0) nodes[no].flags |= P_PACKAGE; } prof = iks_find_attrib(met, "profileOp"); if (prof) { if (strcmp(prof, "delete") == 0) nodes[no].flags |= P_DELETE; if (strcmp(prof, "startup") == 0) nodes[no].flags |= P_STARTUP; } for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "instance") == 0) { build_arg(no, 1, iks_cdata(iks_child(arg))); } } for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "argument") == 0) { char *argname; argname = iks_cdata(iks_child(arg)); if (argname) { build_arg(no, 0, argname); } else { log_error("Argument name needed in <argument> tag of model.xml\n"); } } } } else if (iks_strcmp(iks_name(met), "notify") == 0) { no = add_node(obj_no, build_path(grp, obj, met), N_NOTIFY); if (no >= model_max_notifications) model_max_notifications = no + 1; } } } } } } // no need to keep dom tree in memory iks_delete(model); return 0; }
//! Validates model file int db_validate_model(iks *xml, char *filename) { /*! * Validates model file. * * @xml Iksemel document * @return 0 on success, -1 on error * */ iks *iface, *met, *arg; DBusError bus_error; dbus_error_init(&bus_error); // Check root tag if (iks_strcmp(iks_name(xml), "comarModel") != 0) { log_error("Not a valid model XML: %s\n", filename); return -1; } for (iface = iks_first_tag(xml); iface; iface = iks_next_tag(iface)) { // Only "interface" tag is allowed if (iks_strcmp(iks_name(iface), "interface") != 0) { log_error("Unknown tag '%s' in XML: %s\n", iks_name(iface), filename); return -1; } // Interfaces must have a "name" attribute if (!iks_strlen(iks_find_attrib(iface, "name"))) { log_error("Model with no name in XML: %s\n", filename); return -1; } for (met = iks_first_tag(iface); met; met = iks_next_tag(met)) { // Only "method" and "signal" tags are allowed if (iks_strcmp(iks_name(met), "method") == 0 || iks_strcmp(iks_name(met), "signal") == 0) { // Tags must have a "name" attribute if (!iks_strlen(iks_find_attrib(met, "name"))) { log_error("Method/Signal tag without name under '%s' in XML: %s\n", iks_find_attrib(iface, "name"), filename); return -1; } for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "arg") == 0) { // Arguments must have a "name" attribute if (!iks_strlen(iks_find_attrib(arg, "name"))) { log_error("Argument tag with no name under '%s/%s' in XML: %s\n", iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), filename); return -1; } // Arguments must have a "type" attribute if (!iks_strlen(iks_find_attrib(arg, "type"))) { log_error("Argument tag without type under '%s/%s' in XML: %s\n", iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), filename); return -1; } // Types must be a valid DBus signature if (!dbus_signature_validate(iks_find_attrib(arg, "type"), &bus_error)) { dbus_error_free(&bus_error); log_error("Argument tag with invalid type (%s/%s/%s) in XML: %s\n", iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), iks_find_attrib(arg, "name"), filename); return -1; } // Types must be single type object if (!dbus_signature_validate_single(iks_find_attrib(arg, "type"), &bus_error)) { dbus_error_free(&bus_error); log_error("Argument tag with a non-single element type (%s/%s/%s) in XML: %s\n", iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), iks_find_attrib(arg, "name"), filename); return -1; } } else if (iks_strcmp(iks_name(arg), "annotation") == 0) { // Attributes must have a "name" attribute if (!iks_strlen(iks_find_attrib(arg, "name"))) { log_error("Annotation tag without name under '%s' in XML: %s\n", iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), filename); return -1; } } else { log_error("Unknown tag '%s' under '%s/%s' in XML: %s\n", iks_name(arg), iks_find_attrib(iface, "name"), iks_find_attrib(met, "name"), filename); return -1; } } } else { log_error("Unknown tag '%s' under '%s' in XML: %s\n", iks_name(met), iks_find_attrib(iface, "name"), filename); return -1; } } } return 0; }
//! Loads model to database void db_load_model(iks *xml, PyObject **py_models) { /*! * Loads models to database * * @xml Iksemel document * @py_models Pointer to models dictionary * */ iks *iface, *met, *arg; for (iface = iks_first_tag(xml); iface; iface = iks_next_tag(iface)) { PyObject *py_methods = PyDict_New(); char *iface_name = iks_find_attrib(iface, "name"); for (met = iks_first_tag(iface); met; met = iks_next_tag(met)) { PyObject *py_tuple = PyTuple_New(4); // First argument is type. 0 for methods, 1 for signals if (iks_strcmp(iks_name(met), "method") == 0) { PyTuple_SetItem(py_tuple, 0, PyInt_FromLong((long) 0)); } else { PyTuple_SetItem(py_tuple, 0, PyInt_FromLong((long) 1)); } // Second argument is PolicyKit action ID char *action_id = db_action_id(iface_name, met); PyTuple_SetItem(py_tuple, 1, PyString_FromString(action_id)); // Build argument lists PyObject *py_args_in = PyList_New(0); PyObject *py_args_out = PyList_New(0); int noreply = 0; for (arg = iks_first_tag(met); arg; arg = iks_next_tag(arg)) { if (iks_strcmp(iks_name(arg), "attribute") == 0) { if (iks_strcmp(iks_find_attrib(arg, "name"), "org.freedesktop.DBus.Method.NoReply") == 0) { if (iks_strcmp(iks_find_attrib(arg, "value"), "true") == 0) { noreply = 1; } } } else if (iks_strcmp(iks_name(arg), "arg") == 0) { if (iks_strcmp(iks_name(met), "method") == 0) { if (iks_strcmp(iks_find_attrib(arg, "direction"), "out") == 0) { PyList_Append(py_args_out, PyString_FromString(iks_find_attrib(arg, "type"))); } else { PyList_Append(py_args_in, PyString_FromString(iks_find_attrib(arg, "type"))); } } else if (iks_strcmp(iks_name(met), "signal") == 0) { PyList_Append(py_args_out, PyString_FromString(iks_find_attrib(arg, "type"))); } } } if (noreply) { py_args_out = PyList_New(0); } // Third argument is input arguments PyTuple_SetItem(py_tuple, 2, py_args_in); // Fourth argument is output arguments PyTuple_SetItem(py_tuple, 3, py_args_out); PyDict_SetItemString(py_methods, iks_find_attrib(met, "name"), py_tuple); } PyDict_SetItemString(*py_models, iface_name, py_methods); } }