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(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
|
||||
|
@ -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")) {
|
||||
|
655
src/headerlist.c
655
src/headerlist.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user