static void XMLCALL lr_start_handler(void *pdata, const char *element, const char **attr) { LrParserData *pd = pdata; LrStatesSwitch *sw; if (pd->err) return; // There was an error -> do nothing if (pd->depth != pd->statedepth) { // We are inside of unknown element pd->depth++; return; } pd->depth++; if (!pd->swtab[pd->state]) { // Current element should not have any sub elements return; } // Find current state by its name for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) if (!strcmp(element, sw->ename)) break; if (sw->from != pd->state) { // No state for current element (unknown element) lr_xml_parser_warning(pd, LR_XML_WARNING_UNKNOWNTAG, "Unknown element \"%s\"", element); return; } // Update parser data pd->state = sw->to; pd->docontent = sw->docontent; pd->statedepth = pd->depth; pd->lcontent = 0; pd->content[0] = '\0'; const char *val; switch(pd->state) { case STATE_START: break; case STATE_REPOMD: pd->repomdfound = TRUE; break; case STATE_REVISION: case STATE_TAGS: case STATE_REPO: case STATE_CONTENT: break; case STATE_REPOID: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("type", attr); if (val) pd->repomd->repoid_type = g_string_chunk_insert(pd->repomd->chunk, val); break; case STATE_DISTRO: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("cpeid", attr); if (val) pd->cpeid = g_strdup(val); break; case STATE_DATA: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of a data element"); val = "unknown"; } pd->repomdrecord = lr_yum_repomdrecord_init(val); lr_yum_repomd_set_record(pd->repomd, pd->repomdrecord); break; case STATE_LOCATION: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("href", attr); if (val) pd->repomdrecord->location_href = g_string_chunk_insert( pd->repomdrecord->chunk, val); else lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"href\" of a location element"); val = lr_find_attr("xml:base", attr); if (val) pd->repomdrecord->location_base = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_CHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of a checksum element"); break; } pd->repomdrecord->checksum_type = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_OPENCHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of an open checksum element"); break; } pd->repomdrecord->checksum_open_type = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_TIMESTAMP: case STATE_SIZE: case STATE_OPENSIZE: case STATE_DBVERSION: default: break; } }
static void XMLCALL lr_metalink_start_handler(void *pdata, const char *name, const char **attr) { ParserData *pd = pdata; lr_StatesSwitch *sw; if (pd->ret != LRE_OK) return; /* There was an error -> do nothing */ if (pd->depth != pd->statedepth) { /* There probably was an unknown element */ pd->depth++; return; } pd->depth++; if (!pd->swtab[pd->state]) return; /* Current element should not have any sub elements */ /* Find current state by its name */ for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) if (!strcmp(name, sw->ename)) break; if (sw->from != pd->state) return; /* There is no state for the name -> skip */ /* Update parser data */ pd->state = sw->to; pd->docontent = sw->docontent; pd->statedepth = pd->depth; pd->lcontent = 0; pd->content[0] = '\0'; if (pd->ignore && pd->state != STATE_FILE) return; /* Ignore all subelements of the current file element */ switch (pd->state) { case STATE_START: case STATE_METALINK: case STATE_FILES: break; case STATE_FILE: { const char *name = lr_find_attr("name", attr); if (!name) { DPRINTF("%s: file element doesn't have name attribute\n", __func__); pd->ret = LRE_MLXML; break; } if (pd->found || strcmp(name, pd->filename)) { pd->ignore = 1; break; } else { pd->ignore = 0; pd->found = 1; } pd->metalink->filename = lr_strdup(name); break; } case STATE_TIMESTAMP: case STATE_SIZE: case STATE_VERIFICATION: break; case STATE_HASH: { lr_MetalinkHash mh; const char *type = lr_find_attr("type", attr); if (!type) { DPRINTF("%s: hash element doesn't have type attribute\n", __func__); pd->ret = LRE_MLXML; break; } mh = lr_new_metalinkhash(pd->metalink); mh->type = lr_strdup(type); break; } case STATE_RESOURCES: break; case STATE_URL: { const char *val; lr_MetalinkUrl url = lr_new_metalinkurl(pd->metalink); if ((val = lr_find_attr("protocol", attr))) url->protocol = lr_strdup(val); if ((val = lr_find_attr("type", attr))) url->type = lr_strdup(val); if ((val = lr_find_attr("location", attr))) url->location = lr_strdup(val); if ((val = lr_find_attr("preference", attr))) url->preference = atol(val); break; } default: break; }; return; }