First part of support for getting packages information from repodata using librepo

This commit is contained in:
Silvan Calarco 2021-02-14 22:02:35 +01:00
parent 10dbcdb8b2
commit 9a546f52b9
4 changed files with 520 additions and 160 deletions

View File

@ -6,6 +6,7 @@ pkg_check_modules(RPM REQUIRED rpm)
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
pkg_check_modules(LIBUNWIND REQUIRED libunwind)
pkg_check_modules(LIBDW REQUIRED libdw)
pkg_check_modules(LIBXML2 REQUIRED libxml-2.0)
find_library(LIBIBERTY NAMES iberty)
include_directories(include)
@ -44,11 +45,19 @@ target_link_libraries(distromatic
${RPM_LIBRARIES}
${ZLIB_LIBRARIES}
${SQLITE3_LIBRARIES}
${LIBREPO_LIBRARIES}
${LIBXML2_LIBRARIES}
${LIBUNWIND_LIBRARIES}
${LIBDW_LIBRARIES}
${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
#
@ -68,11 +77,18 @@ target_link_libraries(distroquery
${RPM_LIBRARIES}
${ZLIB_LIBRARIES}
${SQLITE3_LIBRARIES}
${LIBREPO_LIBRARIES}
${LIBXML2_LIBRARIES}
${LIBUNWIND_LIBRARIES}
${LIBDW_LIBRARIES}
${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(
TARGETS distromatic

View File

@ -244,10 +244,12 @@ struct configTag* read_configuration(const char *confFile)
curraltrep++;
} else if (!strcmp(vartok, "HTML_DIR")) {
currconfigtag->html_dir = (char *) strdup(valuetok);
} else if (!strcmp(vartok, "DOWNLOAD_PREFIX")) {
} else if (!strcmp(vartok, "DOWNLOAD_PREFIX")) {
currconfigtag->download_prefix = (char *) strdup(valuetok);
} else if (!strcmp(vartok, "DOWNLOAD_DIR")) {
currconfigtag->download_dir = (char *) strdup(valuetok);
} else if (!strcmp(vartok, "REPODATA_URL")) {
currconfigtag->repodata_url = (char *) strdup(valuetok);
} else if (!strcmp(vartok, "SHOWFILE_PREFIX")) {
currconfigtag->showfile_prefix = (char *) strdup(valuetok);
} else if (!strcmp(vartok, "REPOSITORY_SOURCE_DIR")) {

View File

@ -1,7 +1,7 @@
/*
* 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>
*
* This program is free software; you can redistribute it and/or modify it under
@ -21,6 +21,10 @@
#include <assert.h>
#include <dirent.h>
#include <librepo/librepo.h>
#include <zlib.h>
#include <libxml/parser.h>
#ifndef H_RPMLIB
# include <rpm/rpmlib.h>
#endif
@ -607,20 +611,350 @@ findOrCreateFileGroupListEntry(struct fileGroupList* *first,char* name, int arch
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;
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
addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configTag *ct,
int mode, int altrepository)
{
char *scanpath;
struct headerSourceList *currheadersourcelist = NULL, *newheadersourcelist,
*prevheadersourcelist;
struct headerSourceList *newheadersourcelist;
struct dirent **namelist;
struct changeLog *changelog;
Header h;
char filepath[bufsize + 1];
int n, j, arch, filenamescount, dirnamescount;
int n = 0, j, arch, filenamescount, dirnamescount;
int_16 *fileflags;
char **basenames, **dirnames, **usernames, **groupnames;
const char* errstr;
@ -628,188 +962,196 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
char **requireversion, **requirename;
uint_32 *requireflags, *dirindexes;
char warning[PATH_MAX];
rpmts ts = rpmtsCreate();
rpmts ts;
struct repoData* repodata = NULL;
if (altrepository == ct->repository_level) {
scanpath = ct->repository_source_dir;
if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
} else if (altrepository == -1) {
// non-incremental mode
scanpath = ct->repository_source_dir;
altrepository = 0;
if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
} else {
scanpath = ct->repository[altrepository]->repository_source_dir;
if (ct->repodata_url) repodata = getRepodata(ct->repository[altrepository]->repodata_url, NULL);
}
assert(scanpath != NULL);
memcpy(filepath, scanpath, strlen(scanpath) + 1);
if (repodata) {
// 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);
n = scansdir(scanpath, &namelist, sourcerpmselector, scanrpmnamecmp);
if (n < 0) {
errstr = strerror(errno);
logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", scanpath, errstr);
return 1;
}
newheadersourcelist->next = NULL;
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;
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))) {
newheadersourcelist->name = strdup((char*)
findXMLPropertyByName(package_node, "name")->children->content);
xmlNode *version = findXMLPropertyByName(package_node, "version");
newheadersourcelist->epoch = atoi((char*)findXMLAttributeByName(version, "epoch"));
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);
cnt++;
}
strcpy(&filepath[strlen(scanpath)], namelist[cnt]->d_name);
cnt++;
}
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)) {
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);
newheadersourcelist = malloc(sizeof(struct headerSourceList));
if (newheadersourcelist == NULL) return 1;
newheadersourcelist =
malloc(sizeof(struct headerSourceList));
if (newheadersourcelist == NULL) {
return 1;
}
newheadersourcelist->next = NULL;
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;
newheadersourcelist->next = NULL;
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);
getPackageInfoIntoHeaderSourceList(h, newheadersourcelist);
getPackageRequires(h, &requirename, &requireflags, &requireversion,
&requirecount);
newheadersourcelist->dirindex = malloc(sizeof(int) * filenamescount);
if (!newheadersourcelist->dirindex) return 1;
getPackageRequires(h, &requirename, &requireflags,
&requireversion, &requirecount);
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;
newheadersourcelist->dirindex =
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) {
if (mode & GENHEADER_CHANGELOG) {
changelog = getPackageChangelog(h, newheadersourcelist);
while (changelog) {
if ((!changelog->pkg) || (!changelog->text)) {
snprintf(warning, PATH_MAX, "missing changelog name and/or text");
logmsg(LOG_WARNING,
"%s: missing changelog name and/or text",
newheadersourcelist->name);
"%s: missing changelog name and/or text",
newheadersourcelist->name);
addWarning(newheadersourcelist, warning);
}
changelog = changelog->next;
}
} else {
newheadersourcelist->changelog = NULL;
}
} else {
newheadersourcelist->changelog = NULL;
}
/* 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;
addNewToSourceHeaderList(headersourcelist,
newheadersourcelist, ct, altrepository);
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;
}
}
if (!*headersourcelist) {
/* set first pointer of the list */
*headersourcelist = newheadersourcelist;
} /* altrepository */
(void) headerFree(h);
} // if getHeader()
free(namelist[cnt]);
} // for
free(namelist);
rpmtsFree(ts);
(void) headerFree(h);
} // if getHeader()
free(namelist[cnt]);
} // for
free(namelist);
rpmtsFree(ts);
}
return 0;
}
@ -823,7 +1165,7 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
for (i = 0; i <= ct->repository_level; i++) {
if (ct->repository[i]) {
if (addToSourceHeaderList(headersourcelist, ct, mode, i)) {
logmsg(LOG_ERROR,"Error scanning alternate SRPMs repository");
logmsg(LOG_ERROR,"Error scanning SRPMs repository");
return 1;
}
} else {
@ -832,11 +1174,10 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
}
} else {
if (addToSourceHeaderList(headersourcelist, ct, mode, -1)) {
logmsg(LOG_ERROR,"Error scanning alternate SRPMs repository");
logmsg(LOG_ERROR,"Error scanning SRPMs repository");
return 1;
}
}
return 0;
}

View File

@ -32,6 +32,7 @@ struct configTag {
char *html_dir;
char *download_prefix;
char *download_dir;
char *repodata_url;
char *showfile_prefix;
char *arch[ARCHS_MAX];
struct headerList *headerlist[ARCHS_MAX];