From e0e4fb676dc75903d8bbcc125aaf5f043c873a52 Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Wed, 28 Mar 2012 09:24:58 +0200 Subject: [PATCH] split load_metadata module into load_metadata and locate_metadata modules --- src/CMakeLists.txt | 3 +- src/createrepo_c.c | 1 + src/load_metadata.c | 375 +++++--------------------------------------------- src/load_metadata.h | 19 --- src/locate_metadata.c | 308 +++++++++++++++++++++++++++++++++++++++++ src/locate_metadata.h | 21 +++ 6 files changed, 369 insertions(+), 358 deletions(-) create mode 100644 src/locate_metadata.c create mode 100644 src/locate_metadata.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4dfef3d..aadc30b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ SET (createrepo_c_SRCS compression_wrapper.c load_metadata.c misc.c package.c parsehdr.c parsepkg.c - repomd.c xml_dump.c xml_dump_filelists.c xml_dump_other.c xml_dump_primary.c) + repomd.c xml_dump.c xml_dump_filelists.c xml_dump_other.c xml_dump_primary.c + locate_metadata.c) #ADD_LIBRARY(libcreaterepo_c SHARED ${createrepo_c_SRCS}) ADD_LIBRARY(libcreaterepo_c ${createrepo_c_SRCS}) diff --git a/src/createrepo_c.c b/src/createrepo_c.c index 40091bd..a4bd791 100644 --- a/src/createrepo_c.c +++ b/src/createrepo_c.c @@ -9,6 +9,7 @@ #include "constants.h" #include "parsepkg.h" #include +#include "locate_metadata.h" #include "load_metadata.h" #include "repomd.h" #include "compression_wrapper.h" diff --git a/src/load_metadata.c b/src/load_metadata.c index 1ed9208..ed504f8 100644 --- a/src/load_metadata.c +++ b/src/load_metadata.c @@ -1,24 +1,20 @@ #include -#include #include #include #include #include #include #include -#include #include "package.h" #include "logging.h" #include "misc.h" #include "load_metadata.h" #include "compression_wrapper.h" +#include "locate_metadata.h" #undef MODULE #define MODULE "load_metadata: " -#define FORMAT_XML 1 -#define FORMAT_LEVEL 0 - #define CHUNK_SIZE 8192 #define PKGS_REALLOC_STEP 2000 @@ -41,7 +37,8 @@ typedef enum { FILE_DIR_ELEM, FILE_GHOST_ELEM, CHANGELOG_ELEM -} PrimaryTextElement; +} TextElement; + typedef enum { @@ -57,11 +54,11 @@ typedef enum { FILELISTS, // other OTHERDATA -} PrimaryParserContext; +} ParserContext; -struct PrimaryParserData { +struct ParserData { int total_pkgs; int actual_pkg; int pkgs_size; @@ -70,8 +67,8 @@ struct PrimaryParserData { GString *current_string; GHashTable *hashtable; Package *pkg; - PrimaryParserContext context; - PrimaryTextElement last_elem; + ParserContext context; + TextElement last_elem; }; @@ -100,30 +97,10 @@ void destroy_metadata_hashtable(GHashTable *hashtable) -void free_metadata_location(struct MetadataLocation *ml) -{ - if (!ml) { - return; - } - - g_free(ml->pri_xml_href); - g_free(ml->fil_xml_href); - g_free(ml->oth_xml_href); - g_free(ml->pri_sqlite_href); - g_free(ml->fil_sqlite_href); - g_free(ml->oth_sqlite_href); - g_free(ml->groupfile_href); - g_free(ml->cgroupfile_href); - g_free(ml->repomd); - g_free(ml); -} - - - // primary.xml parser handlers void pri_start_handler(void *data, const char *el, const char **attr) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; int i; @@ -349,7 +326,7 @@ void pri_start_handler(void *data, const char *el, const char **attr) { void pri_char_handler(void *data, const char *txt, int txtlen) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; if (!pkg || ppd->last_elem == NONE_ELEM) { @@ -385,7 +362,7 @@ void pri_char_handler(void *data, const char *txt, int txtlen) { void pri_end_handler(void *data, const char *el) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; @@ -459,7 +436,7 @@ void pri_end_handler(void *data, const char *el) { g_warning(MODULE"%s: Empty hashtable key!", __func__); } - // Update PrimaryParserData + // Update ParserData ppd->pkg = NULL; /* ppd->total_pkgs++; if (ppd->total_pkgs > ppd->pkgs_size) { @@ -500,7 +477,7 @@ void pri_end_handler(void *data, const char *el) { void fil_start_handler(void *data, const char *el, const char **attr) { int i; - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; @@ -572,7 +549,7 @@ void fil_start_handler(void *data, const char *el, const char **attr) { void fil_char_handler(void *data, const char *txt, int txtlen) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; if (!pkg || ppd->last_elem == NONE_ELEM) { @@ -608,7 +585,7 @@ void fil_char_handler(void *data, const char *txt, int txtlen) { void fil_end_handler(void *data, const char *el) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; @@ -687,7 +664,7 @@ void fil_end_handler(void *data, const char *el) { void oth_start_handler(void *data, const char *el, const char **attr) { int i; - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; @@ -762,7 +739,7 @@ void oth_start_handler(void *data, const char *el, const char **attr) { void oth_char_handler(void *data, const char *txt, int txtlen) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; if (!pkg || ppd->last_elem == NONE_ELEM) { @@ -799,7 +776,7 @@ void oth_char_handler(void *data, const char *txt, int txtlen) { void oth_end_handler(void *data, const char *el) { - struct PrimaryParserData *ppd = (struct PrimaryParserData *) data; + struct ParserData *ppd = (struct ParserData *) data; Package *pkg = ppd->pkg; @@ -861,7 +838,7 @@ int load_xml_metadata(GHashTable *hashtable, const char *primary_xml_path, const CompressionType compression_type; CW_FILE *pri_xml_cwfile, *fil_xml_cwfile, *oth_xml_cwfile; XML_Parser pri_p, fil_p, oth_p; - struct PrimaryParserData pri_pd; + struct ParserData parser_data; // Detect compression type @@ -894,30 +871,30 @@ int load_xml_metadata(GHashTable *hashtable, const char *primary_xml_path, const // Prepare parsers // XXX: Maybe try rely on package order and do not use hashtable -/* pri_pd.total_pkgs = 0; - pri_pd.actual_pkg = 0; - pri_pd.pkgs_size = 0; - pri_pd.pkgs = 0; */ +/* parser_data.total_pkgs = 0; + parser_data.actual_pkg = 0; + parser_data.pkgs_size = 0; + parser_data.pkgs = 0; */ // XXX - pri_pd.current_string = g_string_sized_new(1024); - pri_pd.hashtable = hashtable; - pri_pd.pkg = NULL; - pri_pd.context = ROOT; - pri_pd.last_elem = NONE_ELEM; + parser_data.current_string = g_string_sized_new(1024); + parser_data.hashtable = hashtable; + parser_data.pkg = NULL; + parser_data.context = ROOT; + parser_data.last_elem = NONE_ELEM; pri_p = XML_ParserCreate(NULL); - XML_SetUserData(pri_p, (void *) &pri_pd); + XML_SetUserData(pri_p, (void *) &parser_data); XML_SetElementHandler(pri_p, pri_start_handler, pri_end_handler); XML_SetCharacterDataHandler(pri_p, pri_char_handler); fil_p = XML_ParserCreate(NULL); - XML_SetUserData(fil_p, (void *) &pri_pd); + XML_SetUserData(fil_p, (void *) &parser_data); XML_SetElementHandler(fil_p, fil_start_handler, fil_end_handler); XML_SetCharacterDataHandler(fil_p, fil_char_handler); oth_p = XML_ParserCreate(NULL); - XML_SetUserData(oth_p, (void *) &pri_pd); + XML_SetUserData(oth_p, (void *) &parser_data); XML_SetElementHandler(oth_p, oth_start_handler, oth_end_handler); XML_SetCharacterDataHandler(oth_p, oth_char_handler); @@ -953,9 +930,9 @@ int load_xml_metadata(GHashTable *hashtable, const char *primary_xml_path, const } } - assert(!pri_pd.pkg); - pri_pd.context = ROOT; - pri_pd.last_elem = NONE_ELEM; + assert(!parser_data.pkg); + parser_data.context = ROOT; + parser_data.last_elem = NONE_ELEM; // This loop should iterate over package chunks in filelists.xml for (;;) { @@ -986,9 +963,9 @@ int load_xml_metadata(GHashTable *hashtable, const char *primary_xml_path, const } } - assert(!pri_pd.pkg); - pri_pd.context = ROOT; - pri_pd.last_elem = NONE_ELEM; + assert(!parser_data.pkg); + parser_data.context = ROOT; + parser_data.last_elem = NONE_ELEM; // This loop should iterate over package chunks in other.xml for (;;) { @@ -1029,7 +1006,7 @@ int load_xml_metadata(GHashTable *hashtable, const char *primary_xml_path, const cw_close(fil_xml_cwfile); cw_close(oth_xml_cwfile); - g_string_free(pri_pd.current_string, TRUE); + g_string_free(parser_data.current_string, TRUE); return 1; } @@ -1111,281 +1088,3 @@ int locate_and_load_xml_metadata(GHashTable *hashtable, const char *repopath, Ha return result; } - - - -struct MetadataLocation *locate_metadata_via_repomd(const char *repopath) { - - if (!repopath || !g_file_test(repopath, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR)) { - return NULL; - } - - - // Check if repopath ends with slash - - gboolean repopath_ends_with_slash = FALSE; - - if (g_str_has_suffix(repopath, "/")) { - repopath_ends_with_slash = TRUE; - } - - - // Create path to repomd.xml and check if it exists - - gchar *repomd; - - if (repopath_ends_with_slash) { - repomd = g_strconcat(repopath, "repodata/repomd.xml", NULL); - } else { - repomd = g_strconcat(repopath, "/repodata/repomd.xml", NULL); - } - - if (!g_file_test(repomd, G_FILE_TEST_EXISTS)) { - g_debug(MODULE"%s: %s doesn't exists", __func__, repomd); - g_free(repomd); - return NULL; - } - - - // Parse repomd.xml - - int ret; - xmlChar *name; - xmlTextReaderPtr reader; - reader = xmlReaderForFile(repomd, NULL, XML_PARSE_NOBLANKS); - - ret = xmlTextReaderRead(reader); - name = xmlTextReaderName(reader); - if (g_strcmp0((char *) name, "repomd")) { - g_warning(MODULE"%s: Bad xml - missing repomd element? (%s)", __func__, name); - xmlFree(name); - xmlFreeTextReader(reader); - g_free(repomd); - return NULL; - } - xmlFree(name); - - ret = xmlTextReaderRead(reader); - name = xmlTextReaderName(reader); - if (g_strcmp0((char *) name, "revision")) { - g_warning(MODULE"%s: Bad xml - missing revision element? (%s)", __func__, name); - xmlFree(name); - xmlFreeTextReader(reader); - g_free(repomd); - return NULL; - } - xmlFree(name); - - - // Parse data elements - - while (ret) { - // Find first data element - ret = xmlTextReaderRead(reader); - name = xmlTextReaderName(reader); - if (!g_strcmp0((char *) name, "data")) { - xmlFree(name); - break; - } - xmlFree(name); - } - - if (!ret) { - // No elements left -> Bad xml - g_warning(MODULE"%s: Bad xml - missing data elements?", __func__); - xmlFreeTextReader(reader); - g_free(repomd); - return NULL; - } - - struct MetadataLocation *mdloc; - mdloc = g_malloc0(sizeof(struct MetadataLocation)); - mdloc->repomd = repomd; - - xmlChar *data_type = NULL; - xmlChar *location_href = NULL; - - while (ret) { - if (xmlTextReaderNodeType(reader) != 1) { - ret = xmlTextReaderNext(reader); - continue; - } - - xmlNodePtr data_node = xmlTextReaderExpand(reader); - data_type = xmlGetProp(data_node, (xmlChar *) "type"); - xmlNodePtr sub_node = data_node->children; - - while (sub_node) { - if (sub_node->type != XML_ELEMENT_NODE) { - sub_node = xmlNextElementSibling(sub_node); - continue; - } - - if (!g_strcmp0((char *) sub_node->name, "location")) { - location_href = xmlGetProp(sub_node, (xmlChar *) "href"); - } - - // TODO: Check repodata validity checksum? mtime? size? - - sub_node = xmlNextElementSibling(sub_node); - } - - - // Build absolute path - - gchar *full_location_href; - if (repopath_ends_with_slash) { - full_location_href = g_strconcat(repopath, (char *) location_href, NULL); - } else { - full_location_href = g_strconcat(repopath, "/", (char *) location_href, NULL); - } - - - // Store the path - - if (!g_strcmp0((char *) data_type, "primary")) { - mdloc->pri_xml_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "filelists")) { - mdloc->fil_xml_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "other")) { - mdloc->oth_xml_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "primary_db")) { - mdloc->pri_sqlite_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "filelists_db")) { - mdloc->fil_sqlite_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "other_db")) { - mdloc->oth_sqlite_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "group")) { - mdloc->groupfile_href = full_location_href; - } else if (!g_strcmp0((char *) data_type, "group_gz")) { // even with a createrepo param --xz this name has a _gz suffix - mdloc->cgroupfile_href = full_location_href; - } - - - // Memory cleanup - - xmlFree(data_type); - xmlFree(location_href); - location_href = NULL; - - ret = xmlTextReaderNext(reader); - } - - xmlFreeTextReader(reader); - - // Note: Do not free repomd! It is pointed from mdloc structure! - - return mdloc; -} - - -// Return list of non-null pointers on strings in the passed structure -GSList *get_list_of_md_locations (struct MetadataLocation *ml) -{ - GSList *list = NULL; - - if (!ml) { - return list; - } - - if (ml->pri_xml_href) list = g_slist_prepend(list, (gpointer) ml->pri_xml_href); - if (ml->fil_xml_href) list = g_slist_prepend(list, (gpointer) ml->fil_xml_href); - if (ml->oth_xml_href) list = g_slist_prepend(list, (gpointer) ml->oth_xml_href); - if (ml->pri_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->pri_sqlite_href); - if (ml->fil_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->fil_sqlite_href); - if (ml->oth_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->oth_sqlite_href); - if (ml->groupfile_href) list = g_slist_prepend(list, (gpointer) ml->groupfile_href); - if (ml->cgroupfile_href) list = g_slist_prepend(list, (gpointer) ml->cgroupfile_href); - if (ml->repomd) list = g_slist_prepend(list, (gpointer) ml->repomd); - - return list; -} - - - -void free_list_of_md_locations(GSList *list) -{ - if (list) { - g_slist_free(list); - } -} - - - -int remove_old_metadata(const char *repopath) -{ - if (!repopath || !g_file_test(repopath, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR)) { - return -1; - } - - gchar *full_repopath; - full_repopath = g_strconcat(repopath, "/repodata/", NULL); - - GDir *repodir; - repodir = g_dir_open(full_repopath, 0, NULL); - if (!repodir) { - g_debug(MODULE"%s: Path %s doesn't exists", __func__, repopath); - return -1; - } - - - // Remove all metadata listed in repomd.xml - - int removed_files = 0; - - struct MetadataLocation *ml; - ml = locate_metadata_via_repomd(repopath); - if (ml) { - GSList *list = get_list_of_md_locations(ml); - GSList *element; - - for (element=list; element; element=element->next) { - gchar *path = (char *) element->data; - - g_debug("%s: Removing: %s (path obtained from repomd.xml)", __func__, path); - if (g_remove(path) == -1) { - g_warning("%s: remove_old_metadata: Cannot remove %s", __func__, path); - } else { - removed_files++; - } - } - - free_list_of_md_locations(list); - free_metadata_location(ml); - } - - - // (Just for sure) List dir and remove all files which could be related to an old metadata - - const gchar *file; - while ((file = g_dir_read_name (repodir))) { - if (g_str_has_suffix(file, "primary.xml.gz") || - g_str_has_suffix(file, "filelists.xml.gz") || - g_str_has_suffix(file, "other.xml.gz") || - g_str_has_suffix(file, "primary.xml.bz2") || - g_str_has_suffix(file, "filelists.xml.bz2") || - g_str_has_suffix(file, "other.xml.bz2") || - g_str_has_suffix(file, "primary.xml") || - g_str_has_suffix(file, "filelists.xml") || - g_str_has_suffix(file, "other.xml") || - !g_strcmp0(file, "repomd.xml")) - { - gchar *path; - path = g_strconcat(full_repopath, file, NULL); - - g_debug(MODULE"%s: Removing: %s", __func__, path); - if (g_remove(path) == -1) { - g_warning(MODULE"%s: Cannot remove %s", __func__, path); - } else { - removed_files++; - } - - g_free(path); - } - } - - g_dir_close(repodir); - g_free(full_repopath); - - return removed_files; -} diff --git a/src/load_metadata.h b/src/load_metadata.h index 262ac22..87f8bac 100644 --- a/src/load_metadata.h +++ b/src/load_metadata.h @@ -2,20 +2,6 @@ #define __C_CREATEREPOLIB_LOAD_METADATA_H__ #include -#include "constants.h" - -struct MetadataLocation { - char *pri_xml_href; - char *fil_xml_href; - char *oth_xml_href; - char *pri_sqlite_href; - char *fil_sqlite_href; - char *oth_sqlite_href; - char *groupfile_href; - char *cgroupfile_href; // compressed groupfile location - char *repomd; -}; - typedef enum { HT_KEY_DEFAULT, @@ -29,9 +15,4 @@ GHashTable *new_metadata_hashtable(); void destroy_metadata_hashtable(GHashTable *hashtable); int locate_and_load_xml_metadata(GHashTable *hashtable, const char *repopath, HashTableKey key); -struct MetadataLocation *locate_metadata_via_repomd(const char *); -void free_metadata_location(struct MetadataLocation *); - -int remove_old_metadata(const char *repopath); - #endif /* __C_CREATEREPOLIB_LOAD_METADATA_H__ */ diff --git a/src/locate_metadata.c b/src/locate_metadata.c new file mode 100644 index 0000000..e85294c --- /dev/null +++ b/src/locate_metadata.c @@ -0,0 +1,308 @@ +#include +#include +#include +#include "locate_metadata.h" + +#undef MODULE +#define MODULE "locate_metadata: " + +#define FORMAT_XML 1 +#define FORMAT_LEVEL 0 + + + +void free_metadata_location(struct MetadataLocation *ml) +{ + if (!ml) { + return; + } + + g_free(ml->pri_xml_href); + g_free(ml->fil_xml_href); + g_free(ml->oth_xml_href); + g_free(ml->pri_sqlite_href); + g_free(ml->fil_sqlite_href); + g_free(ml->oth_sqlite_href); + g_free(ml->groupfile_href); + g_free(ml->cgroupfile_href); + g_free(ml->repomd); + g_free(ml); +} + + + +struct MetadataLocation *locate_metadata_via_repomd(const char *repopath) { + + if (!repopath || !g_file_test(repopath, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR)) { + return NULL; + } + + + // Check if repopath ends with slash + + gboolean repopath_ends_with_slash = FALSE; + + if (g_str_has_suffix(repopath, "/")) { + repopath_ends_with_slash = TRUE; + } + + + // Create path to repomd.xml and check if it exists + + gchar *repomd; + + if (repopath_ends_with_slash) { + repomd = g_strconcat(repopath, "repodata/repomd.xml", NULL); + } else { + repomd = g_strconcat(repopath, "/repodata/repomd.xml", NULL); + } + + if (!g_file_test(repomd, G_FILE_TEST_EXISTS)) { + g_debug(MODULE"%s: %s doesn't exists", __func__, repomd); + g_free(repomd); + return NULL; + } + + + // Parse repomd.xml + + int ret; + xmlChar *name; + xmlTextReaderPtr reader; + reader = xmlReaderForFile(repomd, NULL, XML_PARSE_NOBLANKS); + + ret = xmlTextReaderRead(reader); + name = xmlTextReaderName(reader); + if (g_strcmp0((char *) name, "repomd")) { + g_warning(MODULE"%s: Bad xml - missing repomd element? (%s)", __func__, name); + xmlFree(name); + xmlFreeTextReader(reader); + g_free(repomd); + return NULL; + } + xmlFree(name); + + ret = xmlTextReaderRead(reader); + name = xmlTextReaderName(reader); + if (g_strcmp0((char *) name, "revision")) { + g_warning(MODULE"%s: Bad xml - missing revision element? (%s)", __func__, name); + xmlFree(name); + xmlFreeTextReader(reader); + g_free(repomd); + return NULL; + } + xmlFree(name); + + + // Parse data elements + + while (ret) { + // Find first data element + ret = xmlTextReaderRead(reader); + name = xmlTextReaderName(reader); + if (!g_strcmp0((char *) name, "data")) { + xmlFree(name); + break; + } + xmlFree(name); + } + + if (!ret) { + // No elements left -> Bad xml + g_warning(MODULE"%s: Bad xml - missing data elements?", __func__); + xmlFreeTextReader(reader); + g_free(repomd); + return NULL; + } + + struct MetadataLocation *mdloc; + mdloc = g_malloc0(sizeof(struct MetadataLocation)); + mdloc->repomd = repomd; + + xmlChar *data_type = NULL; + xmlChar *location_href = NULL; + + while (ret) { + if (xmlTextReaderNodeType(reader) != 1) { + ret = xmlTextReaderNext(reader); + continue; + } + + xmlNodePtr data_node = xmlTextReaderExpand(reader); + data_type = xmlGetProp(data_node, (xmlChar *) "type"); + xmlNodePtr sub_node = data_node->children; + + while (sub_node) { + if (sub_node->type != XML_ELEMENT_NODE) { + sub_node = xmlNextElementSibling(sub_node); + continue; + } + + if (!g_strcmp0((char *) sub_node->name, "location")) { + location_href = xmlGetProp(sub_node, (xmlChar *) "href"); + } + + // TODO: Check repodata validity checksum? mtime? size? + + sub_node = xmlNextElementSibling(sub_node); + } + + + // Build absolute path + + gchar *full_location_href; + if (repopath_ends_with_slash) { + full_location_href = g_strconcat(repopath, (char *) location_href, NULL); + } else { + full_location_href = g_strconcat(repopath, "/", (char *) location_href, NULL); + } + + + // Store the path + + if (!g_strcmp0((char *) data_type, "primary")) { + mdloc->pri_xml_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "filelists")) { + mdloc->fil_xml_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "other")) { + mdloc->oth_xml_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "primary_db")) { + mdloc->pri_sqlite_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "filelists_db")) { + mdloc->fil_sqlite_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "other_db")) { + mdloc->oth_sqlite_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "group")) { + mdloc->groupfile_href = full_location_href; + } else if (!g_strcmp0((char *) data_type, "group_gz")) { // even with a createrepo param --xz this name has a _gz suffix + mdloc->cgroupfile_href = full_location_href; + } + + + // Memory cleanup + + xmlFree(data_type); + xmlFree(location_href); + location_href = NULL; + + ret = xmlTextReaderNext(reader); + } + + xmlFreeTextReader(reader); + + // Note: Do not free repomd! It is pointed from mdloc structure! + + return mdloc; +} + + +// Return list of non-null pointers on strings in the passed structure +GSList *get_list_of_md_locations (struct MetadataLocation *ml) +{ + GSList *list = NULL; + + if (!ml) { + return list; + } + + if (ml->pri_xml_href) list = g_slist_prepend(list, (gpointer) ml->pri_xml_href); + if (ml->fil_xml_href) list = g_slist_prepend(list, (gpointer) ml->fil_xml_href); + if (ml->oth_xml_href) list = g_slist_prepend(list, (gpointer) ml->oth_xml_href); + if (ml->pri_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->pri_sqlite_href); + if (ml->fil_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->fil_sqlite_href); + if (ml->oth_sqlite_href) list = g_slist_prepend(list, (gpointer) ml->oth_sqlite_href); + if (ml->groupfile_href) list = g_slist_prepend(list, (gpointer) ml->groupfile_href); + if (ml->cgroupfile_href) list = g_slist_prepend(list, (gpointer) ml->cgroupfile_href); + if (ml->repomd) list = g_slist_prepend(list, (gpointer) ml->repomd); + + return list; +} + + + +void free_list_of_md_locations(GSList *list) +{ + if (list) { + g_slist_free(list); + } +} + + + +int remove_old_metadata(const char *repopath) +{ + if (!repopath || !g_file_test(repopath, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR)) { + return -1; + } + + gchar *full_repopath; + full_repopath = g_strconcat(repopath, "/repodata/", NULL); + + GDir *repodir; + repodir = g_dir_open(full_repopath, 0, NULL); + if (!repodir) { + g_debug(MODULE"%s: Path %s doesn't exists", __func__, repopath); + return -1; + } + + + // Remove all metadata listed in repomd.xml + + int removed_files = 0; + + struct MetadataLocation *ml; + ml = locate_metadata_via_repomd(repopath); + if (ml) { + GSList *list = get_list_of_md_locations(ml); + GSList *element; + + for (element=list; element; element=element->next) { + gchar *path = (char *) element->data; + + g_debug("%s: Removing: %s (path obtained from repomd.xml)", __func__, path); + if (g_remove(path) == -1) { + g_warning("%s: remove_old_metadata: Cannot remove %s", __func__, path); + } else { + removed_files++; + } + } + + free_list_of_md_locations(list); + free_metadata_location(ml); + } + + + // (Just for sure) List dir and remove all files which could be related to an old metadata + + const gchar *file; + while ((file = g_dir_read_name (repodir))) { + if (g_str_has_suffix(file, "primary.xml.gz") || + g_str_has_suffix(file, "filelists.xml.gz") || + g_str_has_suffix(file, "other.xml.gz") || + g_str_has_suffix(file, "primary.xml.bz2") || + g_str_has_suffix(file, "filelists.xml.bz2") || + g_str_has_suffix(file, "other.xml.bz2") || + g_str_has_suffix(file, "primary.xml") || + g_str_has_suffix(file, "filelists.xml") || + g_str_has_suffix(file, "other.xml") || + !g_strcmp0(file, "repomd.xml")) + { + gchar *path; + path = g_strconcat(full_repopath, file, NULL); + + g_debug(MODULE"%s: Removing: %s", __func__, path); + if (g_remove(path) == -1) { + g_warning(MODULE"%s: Cannot remove %s", __func__, path); + } else { + removed_files++; + } + + g_free(path); + } + } + + g_dir_close(repodir); + g_free(full_repopath); + + return removed_files; +} diff --git a/src/locate_metadata.h b/src/locate_metadata.h new file mode 100644 index 0000000..8d835f6 --- /dev/null +++ b/src/locate_metadata.h @@ -0,0 +1,21 @@ +#ifndef __C_CREATEREPOLIB_LOCATE_METADATA_H__ +#define __C_CREATEREPOLIB_LOCATE_METADATA_H__ + +struct MetadataLocation { + char *pri_xml_href; + char *fil_xml_href; + char *oth_xml_href; + char *pri_sqlite_href; + char *fil_sqlite_href; + char *oth_sqlite_href; + char *groupfile_href; + char *cgroupfile_href; // compressed groupfile location + char *repomd; +}; + +struct MetadataLocation *locate_metadata_via_repomd(const char *); +void free_metadata_location(struct MetadataLocation *); + +int remove_old_metadata(const char *repopath); + +#endif /* __C_CREATEREPOLIB_LOCATE_METADATA_H__ */ -- 2.7.4