First part of support for getting packages information from repodata using librepo
This commit is contained in:
parent
10dbcdb8b2
commit
9a546f52b9
@ -6,6 +6,7 @@ pkg_check_modules(RPM REQUIRED rpm)
|
|||||||
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
|
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
|
||||||
pkg_check_modules(LIBUNWIND REQUIRED libunwind)
|
pkg_check_modules(LIBUNWIND REQUIRED libunwind)
|
||||||
pkg_check_modules(LIBDW REQUIRED libdw)
|
pkg_check_modules(LIBDW REQUIRED libdw)
|
||||||
|
pkg_check_modules(LIBXML2 REQUIRED libxml-2.0)
|
||||||
find_library(LIBIBERTY NAMES iberty)
|
find_library(LIBIBERTY NAMES iberty)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
@ -44,11 +45,19 @@ target_link_libraries(distromatic
|
|||||||
${RPM_LIBRARIES}
|
${RPM_LIBRARIES}
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
${SQLITE3_LIBRARIES}
|
${SQLITE3_LIBRARIES}
|
||||||
|
${LIBREPO_LIBRARIES}
|
||||||
|
${LIBXML2_LIBRARIES}
|
||||||
${LIBUNWIND_LIBRARIES}
|
${LIBUNWIND_LIBRARIES}
|
||||||
${LIBDW_LIBRARIES}
|
${LIBDW_LIBRARIES}
|
||||||
${LIBIBERTY}
|
${LIBIBERTY}
|
||||||
)
|
)
|
||||||
target_include_directories(distromatic PUBLIC ${RPM_INCLUDE_DIRS} ${LIBUNWIND_INCLUDE_DIRS})
|
target_include_directories(distromatic PUBLIC
|
||||||
|
${RPM_INCLUDE_DIRS}
|
||||||
|
${LIBREPO_INCLUDE_DIRS}
|
||||||
|
${LIBXML2_INCLUDE_DIRS}
|
||||||
|
${LIBUNWIND_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
# NOTE: -fno-toplevel-reorder required to prevent Sqlite3 weird problems
|
# NOTE: -fno-toplevel-reorder required to prevent Sqlite3 weird problems
|
||||||
#
|
#
|
||||||
@ -68,11 +77,18 @@ target_link_libraries(distroquery
|
|||||||
${RPM_LIBRARIES}
|
${RPM_LIBRARIES}
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
${SQLITE3_LIBRARIES}
|
${SQLITE3_LIBRARIES}
|
||||||
|
${LIBREPO_LIBRARIES}
|
||||||
|
${LIBXML2_LIBRARIES}
|
||||||
${LIBUNWIND_LIBRARIES}
|
${LIBUNWIND_LIBRARIES}
|
||||||
${LIBDW_LIBRARIES}
|
${LIBDW_LIBRARIES}
|
||||||
${LIBIBERTY}
|
${LIBIBERTY}
|
||||||
)
|
)
|
||||||
target_include_directories(distroquery PUBLIC ${RPM_INCLUDE_DIRS} ${LIBUNWIND_INCLUDE_DIRS})
|
target_include_directories(distroquery PUBLIC
|
||||||
|
${RPM_INCLUDE_DIRS}
|
||||||
|
${LIBREPO_INCLUDE_DIRS}
|
||||||
|
${LIBXML2_INCLUDE_DIRS}
|
||||||
|
${LIBUNWIND_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS distromatic
|
TARGETS distromatic
|
||||||
|
@ -244,10 +244,12 @@ struct configTag* read_configuration(const char *confFile)
|
|||||||
curraltrep++;
|
curraltrep++;
|
||||||
} else if (!strcmp(vartok, "HTML_DIR")) {
|
} else if (!strcmp(vartok, "HTML_DIR")) {
|
||||||
currconfigtag->html_dir = (char *) strdup(valuetok);
|
currconfigtag->html_dir = (char *) strdup(valuetok);
|
||||||
} else if (!strcmp(vartok, "DOWNLOAD_PREFIX")) {
|
} else if (!strcmp(vartok, "DOWNLOAD_PREFIX")) {
|
||||||
currconfigtag->download_prefix = (char *) strdup(valuetok);
|
currconfigtag->download_prefix = (char *) strdup(valuetok);
|
||||||
} else if (!strcmp(vartok, "DOWNLOAD_DIR")) {
|
} else if (!strcmp(vartok, "DOWNLOAD_DIR")) {
|
||||||
currconfigtag->download_dir = (char *) strdup(valuetok);
|
currconfigtag->download_dir = (char *) strdup(valuetok);
|
||||||
|
} else if (!strcmp(vartok, "REPODATA_URL")) {
|
||||||
|
currconfigtag->repodata_url = (char *) strdup(valuetok);
|
||||||
} else if (!strcmp(vartok, "SHOWFILE_PREFIX")) {
|
} else if (!strcmp(vartok, "SHOWFILE_PREFIX")) {
|
||||||
currconfigtag->showfile_prefix = (char *) strdup(valuetok);
|
currconfigtag->showfile_prefix = (char *) strdup(valuetok);
|
||||||
} else if (!strcmp(vartok, "REPOSITORY_SOURCE_DIR")) {
|
} else if (!strcmp(vartok, "REPOSITORY_SOURCE_DIR")) {
|
||||||
|
655
src/headerlist.c
655
src/headerlist.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* distromatic - tool for RPM based repositories
|
* distromatic - tool for RPM based repositories
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2020 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
* Copyright (C) 2004-2021 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||||
* Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
|
* Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
@ -21,6 +21,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include <librepo/librepo.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
|
||||||
#ifndef H_RPMLIB
|
#ifndef H_RPMLIB
|
||||||
# include <rpm/rpmlib.h>
|
# include <rpm/rpmlib.h>
|
||||||
#endif
|
#endif
|
||||||
@ -607,20 +611,350 @@ findOrCreateFileGroupListEntry(struct fileGroupList* *first,char* name, int arch
|
|||||||
return newf;
|
return newf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct repoData {
|
||||||
|
char *dir;
|
||||||
|
char *primary;
|
||||||
|
xmlDoc *primary_doc;
|
||||||
|
long primary_size;
|
||||||
|
char *filelists;
|
||||||
|
xmlDoc *filelists_doc;
|
||||||
|
long filelists_size;
|
||||||
|
char *other;
|
||||||
|
xmlDoc *other_doc;
|
||||||
|
long other_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
xmlDoc* parseRepodataXmlGz(char* filename, long size_open) {
|
||||||
|
xmlDoc *doc = NULL;
|
||||||
|
gzFile gzIn;
|
||||||
|
|
||||||
|
gzIn = gzopen(filename, "r");
|
||||||
|
if (gzIn == NULL) {
|
||||||
|
logmsg(LOG_ERROR, "error opening file: %", filename);
|
||||||
|
} else {
|
||||||
|
char *buffer = malloc(size_open);
|
||||||
|
gzread(gzIn, buffer, size_open);
|
||||||
|
gzclose(gzIn);
|
||||||
|
doc = xmlReadMemory(buffer, size_open, "noname.xml", NULL, 0);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct repoData* getRepodata(char *repodata_url, char *arch) {
|
||||||
|
gboolean ret;
|
||||||
|
LrHandle *h;
|
||||||
|
LrResult *r;
|
||||||
|
LrYumRepoMd *repomd;
|
||||||
|
char *download_list[] = LR_RPMMD_BASEXML;
|
||||||
|
char *urls[] = { NULL, NULL };
|
||||||
|
GError *tmp_err = NULL;
|
||||||
|
struct repoData *repodata;
|
||||||
|
|
||||||
|
urls[0] = malloc(PATH_MAX);
|
||||||
|
if (!arch)
|
||||||
|
snprintf(urls[0], PATH_MAX, "%s/SRPMS.base/", repodata_url);
|
||||||
|
else
|
||||||
|
snprintf(urls[0], PATH_MAX, "%s/RPMS.%s/", repodata_url, arch);
|
||||||
|
|
||||||
|
h = lr_handle_init();
|
||||||
|
r = lr_result_init();
|
||||||
|
|
||||||
|
lr_handle_setopt(h, NULL, LRO_URLS, urls);
|
||||||
|
lr_handle_setopt(h, NULL, LRO_REPOTYPE, LR_YUMREPO);
|
||||||
|
lr_handle_setopt(h, NULL, LRO_YUMDLIST, download_list);
|
||||||
|
|
||||||
|
// Create temporary directory
|
||||||
|
char template[] = "/tmp/distromatic.tmp.XXXXXX";
|
||||||
|
char *dir_name = mkdtemp(template);
|
||||||
|
if(dir_name == NULL)
|
||||||
|
{
|
||||||
|
perror("mkdtemp failed: ");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
repodata = malloc(sizeof(struct repoData));
|
||||||
|
repodata->dir = strdup(dir_name);
|
||||||
|
lr_handle_setopt(h, NULL, LRO_DESTDIR, dir_name);
|
||||||
|
|
||||||
|
ret = lr_handle_perform(h, r, &tmp_err);
|
||||||
|
if (!ret) {
|
||||||
|
logmsg(LOG_ERROR, "cannot get repodata: %d: %s\n",
|
||||||
|
tmp_err->code, tmp_err->message);
|
||||||
|
g_error_free(tmp_err);
|
||||||
|
lr_result_free(r);
|
||||||
|
lr_handle_free(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lr_result_getinfo(r, &tmp_err, LRR_YUM_REPOMD, &repomd);
|
||||||
|
|
||||||
|
if (!tmp_err) {
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
for (GSList *elem = repomd->records; elem; elem = g_slist_next(elem)) {
|
||||||
|
LrYumRepoMdRecord *rec = (LrYumRepoMdRecord *) elem->data;
|
||||||
|
if (!strcmp(rec->type, "primary")) {
|
||||||
|
repodata->primary = strdup(rec->location_href);
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->primary);
|
||||||
|
repodata->primary_doc = parseRepodataXmlGz(filename,
|
||||||
|
rec->size_open);
|
||||||
|
} else if (!strcmp(rec->type, "filelists")) {
|
||||||
|
repodata->filelists = strdup(rec->location_href);
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->filelists);
|
||||||
|
repodata->filelists_doc = parseRepodataXmlGz(filename,
|
||||||
|
rec->size_open);
|
||||||
|
} else if (!strcmp(rec->type, "other")) {
|
||||||
|
repodata->other = strdup(rec->location_href);
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->other);
|
||||||
|
repodata->other_doc = parseRepodataXmlGz(filename,
|
||||||
|
rec->size_open);
|
||||||
|
}
|
||||||
|
/*printf(" Type: %s\n", rec->type);
|
||||||
|
printf(" Location href: %s\n", rec->location_href);
|
||||||
|
if (rec->location_base)
|
||||||
|
printf(" Location base: %s\n", rec->location_base);
|
||||||
|
if (rec->checksum)
|
||||||
|
printf(" Checksum: %s\n", rec->checksum);
|
||||||
|
if (rec->checksum_type)
|
||||||
|
printf(" Checksum type: %s\n", rec->checksum_type);
|
||||||
|
if (rec->checksum_open)
|
||||||
|
printf(" Checksum open: %s\n", rec->checksum_open);
|
||||||
|
if (rec->checksum_open_type)
|
||||||
|
printf(" Checksum open type: %s\n", rec->checksum_open_type);
|
||||||
|
if (rec->timestamp > 0)
|
||||||
|
printf(" Timestamp: %"G_GINT64_FORMAT"\n", rec->timestamp);
|
||||||
|
if (rec->size > 0)
|
||||||
|
printf(" Size: %"G_GINT64_FORMAT"\n", rec->size);
|
||||||
|
if (rec->size_open > 0)
|
||||||
|
printf(" Size open: %"G_GINT64_FORMAT"\n", rec->size_open);
|
||||||
|
if (rec->db_version > 0)
|
||||||
|
printf(" Db version: %d\n", rec->db_version);
|
||||||
|
printf("------------------------------------------------\n");*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lr_result_free(r);
|
||||||
|
lr_handle_free(h);
|
||||||
|
|
||||||
|
return repodata;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanRepodata(struct repoData *repodata) {
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
|
||||||
|
if (!repodata) return;
|
||||||
|
|
||||||
|
if (repodata->dir) {
|
||||||
|
if (repodata->primary) {
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->primary);
|
||||||
|
unlink(filename);
|
||||||
|
free(repodata->primary);
|
||||||
|
xmlFreeDoc(repodata->primary_doc);
|
||||||
|
}
|
||||||
|
if (repodata->filelists) {
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->filelists);
|
||||||
|
unlink(filename);
|
||||||
|
free(repodata->filelists);
|
||||||
|
xmlFreeDoc(repodata->filelists_doc);
|
||||||
|
}
|
||||||
|
if (repodata->other) {
|
||||||
|
snprintf(filename, PATH_MAX, "%s/%s", repodata->dir,
|
||||||
|
repodata->other);
|
||||||
|
unlink(filename);
|
||||||
|
free(repodata->other);
|
||||||
|
xmlFreeDoc(repodata->other_doc);
|
||||||
|
}
|
||||||
|
snprintf(filename, PATH_MAX, "%s/repodata/repomd.xml", repodata->dir);
|
||||||
|
unlink(filename);
|
||||||
|
snprintf(filename, PATH_MAX, "%s/repodata", repodata->dir);
|
||||||
|
rmdir(filename);
|
||||||
|
rmdir(repodata->dir);
|
||||||
|
free(repodata->dir);
|
||||||
|
}
|
||||||
|
free(repodata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print_element_names:
|
||||||
|
* @a_node: the initial xml node to consider.
|
||||||
|
*
|
||||||
|
* Prints the names of the all the xml elements
|
||||||
|
* that are siblings or children of a given xml node.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
print_element_names(xmlNode * a_node, int level)
|
||||||
|
{
|
||||||
|
xmlNode *cur_node = NULL;
|
||||||
|
char *str = malloc(level + 1);
|
||||||
|
char *ptr = str;
|
||||||
|
|
||||||
|
for (int i=0; i < level; i++) {
|
||||||
|
*ptr ++ = ' ';
|
||||||
|
}
|
||||||
|
*ptr = 0;
|
||||||
|
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
|
||||||
|
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||||
|
if (cur_node->children && cur_node->children->content)
|
||||||
|
printf("%snode type: Element, name: %s, content: %s\n", str,
|
||||||
|
cur_node->name, XML_GET_CONTENT(cur_node->children));
|
||||||
|
else
|
||||||
|
printf("%snode type: Element, name: %s\n", str, cur_node->name);
|
||||||
|
if (cur_node->properties) {
|
||||||
|
xmlAttr* attribute = cur_node->properties;
|
||||||
|
while(attribute && attribute->name && attribute->children)
|
||||||
|
{
|
||||||
|
xmlChar* value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||||
|
printf ("%s | attribute %s: %s\n", str, attribute->name, value);
|
||||||
|
xmlFree(value);
|
||||||
|
attribute = attribute->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_element_names(cur_node->children, level + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlChar* findXMLAttributeByName(xmlNode *node, char* name) {
|
||||||
|
xmlAttr* attribute = node->properties;
|
||||||
|
while(attribute && attribute->name && attribute->children)
|
||||||
|
{
|
||||||
|
if (!strcmp((char*)attribute->name, name)) {
|
||||||
|
xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
attribute = attribute->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlNode* findXMLPropertyByName(xmlNode *node, char* name) {
|
||||||
|
xmlNode *props_node = NULL;
|
||||||
|
|
||||||
|
for (props_node = node->children; props_node; props_node = props_node->next) {
|
||||||
|
if (props_node->type == XML_ELEMENT_NODE && !strcmp((char*)props_node->name, name))
|
||||||
|
return props_node;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlNode* findXMLPackageByName(xmlNode *root_node, char* name) {
|
||||||
|
xmlNode *package_node = NULL;
|
||||||
|
xmlNode *props_node = NULL;
|
||||||
|
for (package_node = root_node->children; package_node; package_node = package_node->next) {
|
||||||
|
if (!strcmp((char*)package_node->name, "package")) {
|
||||||
|
for (props_node = package_node->children; props_node; props_node = props_node->next) {
|
||||||
|
if (props_node->type == XML_ELEMENT_NODE && !strcmp((char*)props_node->name, "name")) {
|
||||||
|
if (props_node->children && !strcmp((char*)props_node->children, name))
|
||||||
|
return package_node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlChar* value = findXMLAttributeByName(package_node, "name");
|
||||||
|
if (value) {
|
||||||
|
if (!strcmp((char*)value, name)) {
|
||||||
|
xmlFree(value);
|
||||||
|
return package_node;
|
||||||
|
}
|
||||||
|
xmlFree(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static long sourceid = 0;
|
static long sourceid = 0;
|
||||||
|
|
||||||
|
void addNewToSourceHeaderList(struct headerSourceList **headersourcelist,
|
||||||
|
struct headerSourceList *newheadersourcelist, struct configTag *ct,
|
||||||
|
int altrepository) {
|
||||||
|
|
||||||
|
struct headerSourceList *currheadersourcelist = NULL;
|
||||||
|
struct headerSourceList *prevheadersourcelist;
|
||||||
|
char warning[PATH_MAX];
|
||||||
|
|
||||||
|
/* if main repository (altrepository=0) packages are inserted sequentially
|
||||||
|
* otherwise the list is scanned and packages are inserted alphabetically */
|
||||||
|
if (!altrepository) {
|
||||||
|
if (currheadersourcelist) {
|
||||||
|
currheadersourcelist->next = newheadersourcelist;
|
||||||
|
}
|
||||||
|
currheadersourcelist = newheadersourcelist;
|
||||||
|
} else { /* altrepository */
|
||||||
|
currheadersourcelist = *headersourcelist;
|
||||||
|
prevheadersourcelist = NULL;
|
||||||
|
while ((currheadersourcelist) &&
|
||||||
|
(strcasecmp(currheadersourcelist->name,newheadersourcelist->name) < 0)) {
|
||||||
|
prevheadersourcelist = currheadersourcelist;
|
||||||
|
currheadersourcelist = currheadersourcelist->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((currheadersourcelist) &&
|
||||||
|
(!strcmp(currheadersourcelist->name,newheadersourcelist->name))) {
|
||||||
|
/* the package is both in main and alternate repositories.
|
||||||
|
override main repository package */
|
||||||
|
if ((currheadersourcelist->epoch > newheadersourcelist->epoch) ||
|
||||||
|
((currheadersourcelist->epoch == newheadersourcelist->epoch) &&
|
||||||
|
(rpmvercmp(currheadersourcelist->version,
|
||||||
|
newheadersourcelist->version) > 0)) ||
|
||||||
|
((currheadersourcelist->epoch == newheadersourcelist->epoch) &&
|
||||||
|
(rpmvercmp(currheadersourcelist->version,
|
||||||
|
newheadersourcelist->version) == 0) &&
|
||||||
|
(rpmvercmp(currheadersourcelist->release,
|
||||||
|
newheadersourcelist->release) >= 0))) {
|
||||||
|
if (ct->repository_level == altrepository) {
|
||||||
|
snprintf(warning, PATH_MAX, "is older or same release of upstream package in %s (%ld:%s-%s <= %ld:%s-%s)",
|
||||||
|
ct->repository[currheadersourcelist->altrepository]->tag,
|
||||||
|
newheadersourcelist->epoch,
|
||||||
|
newheadersourcelist->version,
|
||||||
|
newheadersourcelist->release,
|
||||||
|
currheadersourcelist->epoch,
|
||||||
|
currheadersourcelist->version,
|
||||||
|
currheadersourcelist->release);
|
||||||
|
logmsg(LOG_WARNING,
|
||||||
|
"%s(source,%s): %s",
|
||||||
|
newheadersourcelist->name,
|
||||||
|
ct->repository[newheadersourcelist->altrepository]->tag,
|
||||||
|
warning);
|
||||||
|
addWarning(newheadersourcelist, warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newheadersourcelist->next = currheadersourcelist->next;
|
||||||
|
/* overriden package is not deallocated but referenced with currheadersourcelist->old */
|
||||||
|
newheadersourcelist->old=currheadersourcelist;
|
||||||
|
newheadersourcelist->old->updatingparent=newheadersourcelist;
|
||||||
|
} else {
|
||||||
|
/* add the new package to the list */
|
||||||
|
newheadersourcelist->next = currheadersourcelist;
|
||||||
|
}
|
||||||
|
if (prevheadersourcelist) {
|
||||||
|
prevheadersourcelist->next = newheadersourcelist;
|
||||||
|
} else {
|
||||||
|
*headersourcelist = newheadersourcelist;
|
||||||
|
}
|
||||||
|
} /* altrepository */
|
||||||
|
|
||||||
|
if (!*headersourcelist) {
|
||||||
|
/* set first pointer of the list */
|
||||||
|
*headersourcelist = newheadersourcelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configTag *ct,
|
addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configTag *ct,
|
||||||
int mode, int altrepository)
|
int mode, int altrepository)
|
||||||
{
|
{
|
||||||
char *scanpath;
|
char *scanpath;
|
||||||
struct headerSourceList *currheadersourcelist = NULL, *newheadersourcelist,
|
struct headerSourceList *newheadersourcelist;
|
||||||
*prevheadersourcelist;
|
|
||||||
struct dirent **namelist;
|
struct dirent **namelist;
|
||||||
struct changeLog *changelog;
|
struct changeLog *changelog;
|
||||||
Header h;
|
Header h;
|
||||||
char filepath[bufsize + 1];
|
char filepath[bufsize + 1];
|
||||||
int n, j, arch, filenamescount, dirnamescount;
|
int n = 0, j, arch, filenamescount, dirnamescount;
|
||||||
int_16 *fileflags;
|
int_16 *fileflags;
|
||||||
char **basenames, **dirnames, **usernames, **groupnames;
|
char **basenames, **dirnames, **usernames, **groupnames;
|
||||||
const char* errstr;
|
const char* errstr;
|
||||||
@ -628,188 +962,196 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
|
|||||||
char **requireversion, **requirename;
|
char **requireversion, **requirename;
|
||||||
uint_32 *requireflags, *dirindexes;
|
uint_32 *requireflags, *dirindexes;
|
||||||
char warning[PATH_MAX];
|
char warning[PATH_MAX];
|
||||||
rpmts ts = rpmtsCreate();
|
rpmts ts;
|
||||||
|
struct repoData* repodata = NULL;
|
||||||
|
|
||||||
if (altrepository == ct->repository_level) {
|
if (altrepository == ct->repository_level) {
|
||||||
scanpath = ct->repository_source_dir;
|
scanpath = ct->repository_source_dir;
|
||||||
|
if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
|
||||||
} else if (altrepository == -1) {
|
} else if (altrepository == -1) {
|
||||||
// non-incremental mode
|
// non-incremental mode
|
||||||
scanpath = ct->repository_source_dir;
|
scanpath = ct->repository_source_dir;
|
||||||
altrepository = 0;
|
altrepository = 0;
|
||||||
|
if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
|
||||||
} else {
|
} else {
|
||||||
scanpath = ct->repository[altrepository]->repository_source_dir;
|
scanpath = ct->repository[altrepository]->repository_source_dir;
|
||||||
|
if (ct->repodata_url) repodata = getRepodata(ct->repository[altrepository]->repodata_url, NULL);
|
||||||
}
|
}
|
||||||
assert(scanpath != NULL);
|
if (repodata) {
|
||||||
memcpy(filepath, scanpath, strlen(scanpath) + 1);
|
// Use repodata
|
||||||
|
//n = atoi((char*)findXMLPropertyByName(xmlDocGetRootElement(repodata->primary_doc), "packages"));
|
||||||
|
//xmlNode* packageNode = findXMLPackageByName(xmlDocGetRootElement(repodata->other_doc), "firefox");
|
||||||
|
//print_element_names(packageNode->children, 0);
|
||||||
|
xmlNode *package_node;
|
||||||
|
for (package_node = xmlDocGetRootElement(repodata->primary_doc)->children;
|
||||||
|
package_node; package_node = package_node->next) {
|
||||||
|
if (!strcmp((char*)package_node->name, "package")) {
|
||||||
|
newheadersourcelist = malloc(sizeof(struct headerSourceList));
|
||||||
|
if (newheadersourcelist == NULL) return 1;
|
||||||
|
|
||||||
logmsg(LOG_DEBUG, "scanning source directory '%s' (%d)", scanpath, altrepository);
|
newheadersourcelist->next = NULL;
|
||||||
n = scansdir(scanpath, &namelist, sourcerpmselector, scanrpmnamecmp);
|
for (arch = 0; arch < ARCHS_MAX; arch++) {
|
||||||
if (n < 0) {
|
newheadersourcelist->firstchild[arch] = NULL;
|
||||||
errstr = strerror(errno);
|
}
|
||||||
logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", scanpath, errstr);
|
newheadersourcelist->updatingparent = NULL;
|
||||||
return 1;
|
newheadersourcelist->altrepository = altrepository;
|
||||||
}
|
newheadersourcelist->firstwarning = NULL;
|
||||||
|
newheadersourcelist->firstrebuild = NULL;
|
||||||
|
newheadersourcelist->old = NULL;
|
||||||
|
newheadersourcelist->id = ++sourceid;
|
||||||
|
|
||||||
int cnt;
|
newheadersourcelist->name = strdup((char*)
|
||||||
for (cnt = 0; cnt < n; ++cnt) {
|
findXMLPropertyByName(package_node, "name")->children->content);
|
||||||
/* check for duplicates */
|
xmlNode *version = findXMLPropertyByName(package_node, "version");
|
||||||
if ((cnt < n - 1) &&
|
newheadersourcelist->epoch = atoi((char*)findXMLAttributeByName(version, "epoch"));
|
||||||
(!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) {
|
newheadersourcelist->version = strdup((char*)findXMLAttributeByName(version, "ver"));
|
||||||
|
newheadersourcelist->release = strdup((char*)findXMLAttributeByName(version, "rel"));
|
||||||
|
newheadersourcelist->summary = strdup((char*)
|
||||||
|
findXMLPropertyByName(package_node, "summary")->children->content);
|
||||||
|
newheadersourcelist->arch = strdup((char*)
|
||||||
|
findXMLPropertyByName(package_node, "arch")->children->content);
|
||||||
|
// hl->buildarchs = headerGetStringEntry(h, RPMTAG_BUILDARCHS);
|
||||||
|
// hl->excludearch = headerGetStringEntry(h, RPMTAG_EXCLUDEARCH);
|
||||||
|
if (findXMLPropertyByName(package_node, "description")->children) {
|
||||||
|
newheadersourcelist->description = strdup((char*)
|
||||||
|
findXMLPropertyByName(package_node, "description")->children->content);
|
||||||
|
}
|
||||||
|
char* packager = strdup((char*)
|
||||||
|
findXMLPropertyByName(package_node, "packager")->children->content);
|
||||||
|
if (!packager) {
|
||||||
|
logmsg(LOG_WARNING,"missing packager definition in package %s.",newheadersourcelist->name);
|
||||||
|
newheadersourcelist->packager = NULL;
|
||||||
|
} else {
|
||||||
|
newheadersourcelist->packager = getPackagerByName(packager,1);
|
||||||
|
if (!newheadersourcelist->packager) {
|
||||||
|
logmsg(LOG_WARNING,"cannot create '%s' packager for package %s.",
|
||||||
|
packager, newheadersourcelist->name);
|
||||||
|
}
|
||||||
|
free(packager);
|
||||||
|
}
|
||||||
|
xmlNode *format = findXMLPropertyByName(package_node, "format");
|
||||||
|
newheadersourcelist->group = strdup((char*)
|
||||||
|
findXMLPropertyByName(format, "group")->children->content);
|
||||||
|
newheadersourcelist->license = strdup((char*)
|
||||||
|
findXMLPropertyByName(format, "license")->children->content);
|
||||||
|
//newheadersourcelist->source = strdup((char*)
|
||||||
|
newheadersourcelist->url = strdup((char*)
|
||||||
|
findXMLPropertyByName(package_node, "url")->children->content);
|
||||||
|
if (!newheadersourcelist->url)
|
||||||
|
logmsg(LOG_WARNING,"missing URL definition for package %s.",
|
||||||
|
newheadersourcelist->name);
|
||||||
|
xmlNode *ptime = findXMLPropertyByName(package_node, "time");
|
||||||
|
newheadersourcelist->buildtime = atoi(
|
||||||
|
(char*)findXMLAttributeByName(ptime, "build"));
|
||||||
|
xmlNode *psize = findXMLPropertyByName(package_node, "size");
|
||||||
|
newheadersourcelist->buildtime = atoi(
|
||||||
|
(char*)findXMLAttributeByName(psize, "package"));
|
||||||
|
//hl->patch = headerGetStringArrayEntry(h, RPMTAG_PATCH, &count);
|
||||||
|
|
||||||
|
addNewToSourceHeaderList(headersourcelist,
|
||||||
|
newheadersourcelist, ct, altrepository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanRepodata(repodata);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Scan local repository dir
|
||||||
|
ts = rpmtsCreate();
|
||||||
|
assert(scanpath != NULL);
|
||||||
|
memcpy(filepath, scanpath, strlen(scanpath) + 1);
|
||||||
|
logmsg(LOG_DEBUG, "scanning source directory '%s' (%d)", scanpath, altrepository);
|
||||||
|
n = scansdir(scanpath, &namelist, sourcerpmselector, scanrpmnamecmp);
|
||||||
|
if (n < 0) {
|
||||||
|
errstr = strerror(errno);
|
||||||
|
logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", scanpath, errstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int cnt;
|
||||||
|
for (cnt = 0; cnt < n; ++cnt) {
|
||||||
|
/* check for duplicates */
|
||||||
|
if ((cnt < n - 1) &&
|
||||||
|
(!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) {
|
||||||
logmsg(LOG_WARNING,"skipping old SRPM package %s",namelist[cnt]->d_name);
|
logmsg(LOG_WARNING,"skipping old SRPM package %s",namelist[cnt]->d_name);
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
strcpy(&filepath[strlen(scanpath)], namelist[cnt]->d_name);
|
strcpy(&filepath[strlen(scanpath)], namelist[cnt]->d_name);
|
||||||
|
logmsg(LOG_DEBUG, "getting header for %s", filepath);
|
||||||
|
|
||||||
logmsg(LOG_DEBUG, "getting header for %s", filepath);
|
if (getHeader(&ts, filepath, &h)) {
|
||||||
|
errstr = strerror(errno);
|
||||||
|
logmsg(LOG_WARNING, "%s: unable to read header (%s); skipping.",
|
||||||
|
namelist[cnt]->d_name, errstr);
|
||||||
|
} else {
|
||||||
|
getPackageFiles(h, &dirindexes, &dirnames, &dirnamescount,
|
||||||
|
&basenames, &filenamescount, &usernames, &groupnames, &fileflags);
|
||||||
|
|
||||||
if (getHeader(&ts, filepath, &h)) {
|
newheadersourcelist = malloc(sizeof(struct headerSourceList));
|
||||||
errstr = strerror(errno);
|
if (newheadersourcelist == NULL) return 1;
|
||||||
logmsg(LOG_WARNING,
|
|
||||||
"%s: unable to read header (%s); skipping.",namelist[cnt]->d_name, errstr);
|
|
||||||
} else {
|
|
||||||
getPackageFiles(h, &dirindexes, &dirnames, &dirnamescount,
|
|
||||||
&basenames, &filenamescount,
|
|
||||||
&usernames, &groupnames, &fileflags);
|
|
||||||
|
|
||||||
newheadersourcelist =
|
newheadersourcelist->next = NULL;
|
||||||
malloc(sizeof(struct headerSourceList));
|
for (arch = 0; arch < ARCHS_MAX; arch++) {
|
||||||
if (newheadersourcelist == NULL) {
|
newheadersourcelist->firstchild[arch] = NULL;
|
||||||
return 1;
|
}
|
||||||
}
|
newheadersourcelist->updatingparent = NULL;
|
||||||
|
newheadersourcelist->altrepository = altrepository;
|
||||||
|
newheadersourcelist->firstwarning = NULL;
|
||||||
|
newheadersourcelist->firstrebuild = NULL;
|
||||||
|
newheadersourcelist->old = NULL;
|
||||||
|
newheadersourcelist->id = ++sourceid;
|
||||||
|
|
||||||
newheadersourcelist->next = NULL;
|
getPackageInfoIntoHeaderSourceList(h, newheadersourcelist);
|
||||||
for (arch = 0; arch < ARCHS_MAX; arch++) {
|
|
||||||
newheadersourcelist->firstchild[arch] = NULL;
|
|
||||||
}
|
|
||||||
newheadersourcelist->updatingparent = NULL;
|
|
||||||
newheadersourcelist->altrepository = altrepository;
|
|
||||||
newheadersourcelist->firstwarning = NULL;
|
|
||||||
newheadersourcelist->firstrebuild = NULL;
|
|
||||||
newheadersourcelist->old = NULL;
|
|
||||||
newheadersourcelist->id = ++sourceid;
|
|
||||||
|
|
||||||
getPackageInfoIntoHeaderSourceList(h, newheadersourcelist);
|
getPackageRequires(h, &requirename, &requireflags, &requireversion,
|
||||||
|
&requirecount);
|
||||||
|
|
||||||
|
newheadersourcelist->dirindex = malloc(sizeof(int) * filenamescount);
|
||||||
|
if (!newheadersourcelist->dirindex) return 1;
|
||||||
|
|
||||||
getPackageRequires(h, &requirename, &requireflags,
|
memcpy(newheadersourcelist->dirindex, dirindexes,
|
||||||
&requireversion, &requirecount);
|
sizeof(int) * filenamescount);
|
||||||
|
newheadersourcelist->dirname =
|
||||||
|
(char **) dupnargv(dirnames, dirnamescount);
|
||||||
|
newheadersourcelist->basename =
|
||||||
|
(char **) dupnargv(basenames, filenamescount);
|
||||||
|
newheadersourcelist->filenamecount = filenamescount;
|
||||||
|
newheadersourcelist->require = malloc(requirecount *
|
||||||
|
sizeof(struct Require *));
|
||||||
|
for (j=0; j < requirecount; j++) {
|
||||||
|
newheadersourcelist->require[j] = malloc(sizeof(struct Require));
|
||||||
|
newheadersourcelist->require[j]->name = requirename[j];
|
||||||
|
newheadersourcelist->require[j]->flags = requireflags[j];
|
||||||
|
newheadersourcelist->require[j]->version = requireversion[j];
|
||||||
|
newheadersourcelist->require[j]->resolved = NULL;
|
||||||
|
}
|
||||||
|
newheadersourcelist->requirecount = requirecount;
|
||||||
|
|
||||||
newheadersourcelist->dirindex =
|
if (mode & GENHEADER_CHANGELOG) {
|
||||||
malloc(sizeof(int) * filenamescount);
|
|
||||||
if (!newheadersourcelist->dirindex) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
memcpy(newheadersourcelist->dirindex, dirindexes,
|
|
||||||
sizeof(int) * filenamescount);
|
|
||||||
newheadersourcelist->dirname =
|
|
||||||
(char **) dupnargv(dirnames, dirnamescount);
|
|
||||||
newheadersourcelist->basename =
|
|
||||||
(char **) dupnargv(basenames, filenamescount);
|
|
||||||
newheadersourcelist->filenamecount = filenamescount;
|
|
||||||
|
|
||||||
newheadersourcelist->require = malloc(requirecount * sizeof(struct Require *));
|
|
||||||
for (j=0; j < requirecount; j++) {
|
|
||||||
newheadersourcelist->require[j] = malloc(sizeof(struct Require));
|
|
||||||
newheadersourcelist->require[j]->name = requirename[j];
|
|
||||||
newheadersourcelist->require[j]->flags = requireflags[j];
|
|
||||||
newheadersourcelist->require[j]->version = requireversion[j];
|
|
||||||
newheadersourcelist->require[j]->resolved = NULL;
|
|
||||||
}
|
|
||||||
newheadersourcelist->requirecount = requirecount;
|
|
||||||
|
|
||||||
if (mode & GENHEADER_CHANGELOG) {
|
|
||||||
changelog = getPackageChangelog(h, newheadersourcelist);
|
changelog = getPackageChangelog(h, newheadersourcelist);
|
||||||
while (changelog) {
|
while (changelog) {
|
||||||
if ((!changelog->pkg) || (!changelog->text)) {
|
if ((!changelog->pkg) || (!changelog->text)) {
|
||||||
snprintf(warning, PATH_MAX, "missing changelog name and/or text");
|
snprintf(warning, PATH_MAX, "missing changelog name and/or text");
|
||||||
logmsg(LOG_WARNING,
|
logmsg(LOG_WARNING,
|
||||||
"%s: missing changelog name and/or text",
|
"%s: missing changelog name and/or text",
|
||||||
newheadersourcelist->name);
|
newheadersourcelist->name);
|
||||||
addWarning(newheadersourcelist, warning);
|
addWarning(newheadersourcelist, warning);
|
||||||
}
|
}
|
||||||
changelog = changelog->next;
|
changelog = changelog->next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newheadersourcelist->changelog = NULL;
|
newheadersourcelist->changelog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if main repository (altrepository=0) packages are inserted sequentially
|
addNewToSourceHeaderList(headersourcelist,
|
||||||
* otherwise the list is scanned and packages are inserted alphabetically */
|
newheadersourcelist, ct, altrepository);
|
||||||
if (!altrepository) {
|
|
||||||
if (currheadersourcelist) {
|
|
||||||
currheadersourcelist->next = newheadersourcelist;
|
|
||||||
}
|
|
||||||
currheadersourcelist = newheadersourcelist;
|
|
||||||
} else { /* altrepository */
|
|
||||||
currheadersourcelist = *headersourcelist;
|
|
||||||
prevheadersourcelist = NULL;
|
|
||||||
|
|
||||||
while ((currheadersourcelist) &&
|
(void) headerFree(h);
|
||||||
(strcasecmp(currheadersourcelist->name,newheadersourcelist->name) < 0)) {
|
} // if getHeader()
|
||||||
prevheadersourcelist = currheadersourcelist;
|
free(namelist[cnt]);
|
||||||
currheadersourcelist = currheadersourcelist->next;
|
} // for
|
||||||
}
|
free(namelist);
|
||||||
|
rpmtsFree(ts);
|
||||||
if ((currheadersourcelist) &&
|
}
|
||||||
(!strcmp(currheadersourcelist->name,newheadersourcelist->name))) {
|
|
||||||
/* the package is both in main and alternate repositories.
|
|
||||||
override main repository package */
|
|
||||||
if ((currheadersourcelist->epoch > newheadersourcelist->epoch) ||
|
|
||||||
((currheadersourcelist->epoch == newheadersourcelist->epoch) &&
|
|
||||||
(rpmvercmp
|
|
||||||
(currheadersourcelist->version,
|
|
||||||
newheadersourcelist->version) > 0)) ||
|
|
||||||
((currheadersourcelist->epoch == newheadersourcelist->epoch) &&
|
|
||||||
(rpmvercmp
|
|
||||||
(currheadersourcelist->version,
|
|
||||||
newheadersourcelist->version) == 0) &&
|
|
||||||
(rpmvercmp
|
|
||||||
(currheadersourcelist->release,
|
|
||||||
newheadersourcelist->release) >= 0))
|
|
||||||
) {
|
|
||||||
if (ct->repository_level == altrepository) {
|
|
||||||
snprintf(warning, PATH_MAX, "is older or same release of upstream package in %s (%ld:%s-%s <= %ld:%s-%s)",
|
|
||||||
ct->repository[currheadersourcelist->altrepository]->tag,
|
|
||||||
newheadersourcelist->epoch,
|
|
||||||
newheadersourcelist->version,
|
|
||||||
newheadersourcelist->release,
|
|
||||||
currheadersourcelist->epoch,
|
|
||||||
currheadersourcelist->version,
|
|
||||||
currheadersourcelist->release);
|
|
||||||
logmsg(LOG_WARNING,
|
|
||||||
"%s(source,%s): %s",
|
|
||||||
newheadersourcelist->name,
|
|
||||||
ct->repository[newheadersourcelist->altrepository]->tag,
|
|
||||||
warning);
|
|
||||||
addWarning(newheadersourcelist, warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newheadersourcelist->next = currheadersourcelist->next;
|
|
||||||
/* overriden package is not deallocated but referenced with currheadersourcelist->old */
|
|
||||||
newheadersourcelist->old=currheadersourcelist;
|
|
||||||
newheadersourcelist->old->updatingparent=newheadersourcelist;
|
|
||||||
} else {
|
|
||||||
/* add the new package to the list */
|
|
||||||
newheadersourcelist->next = currheadersourcelist;
|
|
||||||
}
|
|
||||||
if (prevheadersourcelist) {
|
|
||||||
prevheadersourcelist->next = newheadersourcelist;
|
|
||||||
} else {
|
|
||||||
*headersourcelist = newheadersourcelist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*headersourcelist) {
|
|
||||||
/* set first pointer of the list */
|
|
||||||
*headersourcelist = newheadersourcelist;
|
|
||||||
} /* altrepository */
|
|
||||||
(void) headerFree(h);
|
|
||||||
} // if getHeader()
|
|
||||||
free(namelist[cnt]);
|
|
||||||
} // for
|
|
||||||
|
|
||||||
free(namelist);
|
|
||||||
rpmtsFree(ts);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +1165,7 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
|
|||||||
for (i = 0; i <= ct->repository_level; i++) {
|
for (i = 0; i <= ct->repository_level; i++) {
|
||||||
if (ct->repository[i]) {
|
if (ct->repository[i]) {
|
||||||
if (addToSourceHeaderList(headersourcelist, ct, mode, i)) {
|
if (addToSourceHeaderList(headersourcelist, ct, mode, i)) {
|
||||||
logmsg(LOG_ERROR,"Error scanning alternate SRPMs repository");
|
logmsg(LOG_ERROR,"Error scanning SRPMs repository");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -832,11 +1174,10 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (addToSourceHeaderList(headersourcelist, ct, mode, -1)) {
|
if (addToSourceHeaderList(headersourcelist, ct, mode, -1)) {
|
||||||
logmsg(LOG_ERROR,"Error scanning alternate SRPMs repository");
|
logmsg(LOG_ERROR,"Error scanning SRPMs repository");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ struct configTag {
|
|||||||
char *html_dir;
|
char *html_dir;
|
||||||
char *download_prefix;
|
char *download_prefix;
|
||||||
char *download_dir;
|
char *download_dir;
|
||||||
|
char *repodata_url;
|
||||||
char *showfile_prefix;
|
char *showfile_prefix;
|
||||||
char *arch[ARCHS_MAX];
|
char *arch[ARCHS_MAX];
|
||||||
struct headerList *headerlist[ARCHS_MAX];
|
struct headerList *headerlist[ARCHS_MAX];
|
||||||
|
Loading…
Reference in New Issue
Block a user