int ds_sds_session_register_component_with_dependencies(struct ds_sds_session *session, const char *container_name, const char *component_id, const char *target_filename) { xmlNode *datastream = ds_sds_session_get_selected_datastream(session); if (!datastream) { return -1; } xmlNodePtr container = node_get_child_element(datastream, container_name); if (!container) { if (ds_sds_session_get_datastream_id(session) == NULL) oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' container element found in file '%s' in the first datastream.", container_name, oscap_source_readable_origin(session->source)); else oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' container element found in file '%s' in datastream of id '%s'.", container_name, oscap_source_readable_origin(session->source), ds_sds_session_get_datastream_id(session)); return -1; } int res = -1; xmlNode *component_ref = containter_get_component_ref_by_id(container, component_id); if (component_ref != NULL) { if (target_filename == NULL) { res = ds_sds_dump_component_ref(component_ref, session); } else { res = ds_sds_dump_component_ref_as(component_ref, session, "." , target_filename); } } else { oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' component ref found in file '%s' in datastream of id '%s'.", component_id, oscap_source_readable_origin(session->source), ds_sds_session_get_datastream_id(session)); return -1; } return res; }
int ds_sds_dump_component_ref(const xmlNodePtr component_ref, struct ds_sds_session *session) { char* cref_id = (char*)xmlGetProp(component_ref, BAD_CAST "id"); if (!cref_id) { oscap_seterr(OSCAP_EFAMILY_XML, "No or invalid id attribute on given component-ref."); xmlFree(cref_id); return -1; } int result = ds_sds_dump_component_ref_as(component_ref, session, ".", cref_id); xmlFree(cref_id); // if result is -1, oscap_seterr was already called, no need to call it again return result; }
int ds_sds_dump_component_ref_as(const xmlNodePtr component_ref, struct ds_sds_session *session, const char* sub_dir, const char* relative_filepath) { char* cref_id = (char*)xmlGetProp(component_ref, BAD_CAST "id"); if (!cref_id) { oscap_seterr(OSCAP_EFAMILY_XML, "No or invalid id attribute on given component-ref."); xmlFree(cref_id); return -1; } char* xlink_href = (char*)xmlGetNsProp(component_ref, BAD_CAST "href", BAD_CAST xlink_ns_uri); if (!xlink_href || strlen(xlink_href) < 2) { oscap_seterr(OSCAP_EFAMILY_XML, "No or invalid xlink:href attribute on given component-ref."); xmlFree(cref_id); xmlFree(xlink_href); return -1; } assert(xlink_href[0] == '#'); const char* component_id = xlink_href + 1; char* filename_cpy = oscap_sprintf("./%s", relative_filepath); char* file_reldir = dirname(filename_cpy); const char* target_filename_dirname = oscap_sprintf("%s/%s",sub_dir, file_reldir); oscap_free(filename_cpy); ds_sds_dump_component(component_id, session, target_filename_dirname, relative_filepath); xmlNodePtr catalog = node_get_child_element(component_ref, "catalog"); if (catalog) { xmlNodePtr uri = catalog->children; for (; uri != NULL; uri = uri->next) { if (uri->type != XML_ELEMENT_NODE) continue; if (strcmp((const char*)(uri->name), "uri") != 0) continue; char* name = (char*)xmlGetProp(uri, BAD_CAST "name"); if (!name) { oscap_seterr(OSCAP_EFAMILY_XML, "No 'name' attribute for a component referenced in the catalog of component '%s'.", component_id); xmlFree(cref_id); xmlFree(xlink_href); oscap_free(target_filename_dirname); return -1; } char* str_uri = (char*)xmlGetProp(uri, BAD_CAST "uri"); if (!str_uri || strlen(str_uri) < 2) { oscap_seterr(OSCAP_EFAMILY_XML, "No or invalid 'uri' attribute for a component referenced in the catalog of component '%s'.", component_id); xmlFree(str_uri); xmlFree(name); xmlFree(cref_id); xmlFree(xlink_href); oscap_free(target_filename_dirname); return -1; } // the pointer arithmetics simply skips the first character which is '#' assert(str_uri[0] == '#'); xmlNodePtr cat_component_ref = ds_sds_find_component_ref(ds_sds_session_get_selected_datastream(session), str_uri + 1 * sizeof(char)); if (!cat_component_ref) { oscap_seterr(OSCAP_EFAMILY_XML, "component-ref with given id '%s' wasn't found in the document! We are looking for it because it's in the catalog of component '%s'.", str_uri + 1 * sizeof(char), component_id); xmlFree(str_uri); xmlFree(name); xmlFree(cref_id); xmlFree(xlink_href); oscap_free(target_filename_dirname); return -1; } xmlFree(str_uri); if (ds_sds_dump_component_ref_as(cat_component_ref, session, target_filename_dirname, name) != 0) { xmlFree(name); xmlFree(cref_id); xmlFree(xlink_href); oscap_free(target_filename_dirname); return -1; // no need to call oscap_seterr here, it's already set } xmlFree(name); } } oscap_free(target_filename_dirname); xmlFree(cref_id); xmlFree(xlink_href); return 0; }