Second part of support for getting info from repodata

This commit is contained in:
Silvan Calarco 2021-02-15 21:48:54 +01:00
parent 4f566ceec3
commit d24817d3a3
4 changed files with 462 additions and 386 deletions

View File

@ -142,21 +142,10 @@ findPackageByName(struct headerList *list, char *name)
int getPackageNameFromFile(char *name) int getPackageNameFromFile(char *name)
{ {
char *st1, *st2; int idx = rpmnameidx(name);
if (idx < 0 || idx+1 >= strlen(name)) return 1;
st2 = strrchr(name, '-'); name[idx + 1] = '\0';
if (st2) { return 0;
*st2 = '\0';
st1 = strrchr(name, '-');
if (st1) {
*st1 = '\0';
} else {
/* something wrong occurred: revert all */
*st2 = '-';
return 1;
}
}
return 0;
} }
struct headerSourceList * struct headerSourceList *
@ -657,6 +646,8 @@ struct repoData* getRepodata(char *repodata_url, char *arch) {
else else
snprintf(urls[0], PATH_MAX, "%s/RPMS.%s/", repodata_url, arch); snprintf(urls[0], PATH_MAX, "%s/RPMS.%s/", repodata_url, arch);
logmsg(LOG_DEBUG, "fetching repodata from %s...", urls[0]);
h = lr_handle_init(); h = lr_handle_init();
r = lr_result_init(); r = lr_result_init();
@ -711,27 +702,6 @@ struct repoData* getRepodata(char *repodata_url, char *arch) {
repodata->other_doc = parseRepodataXmlGz(filename, repodata->other_doc = parseRepodataXmlGz(filename,
rec->size_open); 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");*/
} }
} }
@ -867,13 +837,13 @@ xmlNode* findXMLPackageByName(xmlNode *root_node, char* name) {
} }
static long sourceid = 0; static long sourceid = 0;
struct headerSourceList *currheadersourcelist = NULL;
void addNewToSourceHeaderList(struct headerSourceList **headersourcelist, void addNewToSourceHeaderList(struct headerSourceList *newheadersourcelist,
struct headerSourceList *newheadersourcelist, struct configTag *ct, struct configTag *ct, int altrepository) {
int altrepository) {
struct headerSourceList *currheadersourcelist = NULL;
struct headerSourceList *prevheadersourcelist; struct headerSourceList *prevheadersourcelist;
char warning[PATH_MAX]; char warning[PATH_MAX];
/* if main repository (altrepository=0) packages are inserted sequentially /* if main repository (altrepository=0) packages are inserted sequentially
@ -882,9 +852,9 @@ void addNewToSourceHeaderList(struct headerSourceList **headersourcelist,
if (currheadersourcelist) { if (currheadersourcelist) {
currheadersourcelist->next = newheadersourcelist; currheadersourcelist->next = newheadersourcelist;
} }
currheadersourcelist = newheadersourcelist; currheadersourcelist = newheadersourcelist;
} else { /* altrepository */ } else { /* altrepository */
currheadersourcelist = *headersourcelist; currheadersourcelist = ct->headersourcelist;
prevheadersourcelist = NULL; prevheadersourcelist = NULL;
while ((currheadersourcelist) && while ((currheadersourcelist) &&
(strcasecmp(currheadersourcelist->name,newheadersourcelist->name) < 0)) { (strcasecmp(currheadersourcelist->name,newheadersourcelist->name) < 0)) {
@ -933,22 +903,22 @@ void addNewToSourceHeaderList(struct headerSourceList **headersourcelist,
if (prevheadersourcelist) { if (prevheadersourcelist) {
prevheadersourcelist->next = newheadersourcelist; prevheadersourcelist->next = newheadersourcelist;
} else { } else {
*headersourcelist = newheadersourcelist; ct->headersourcelist = newheadersourcelist;
} }
} /* altrepository */ } /* altrepository */
if (!*headersourcelist) { if (!ct->headersourcelist) {
/* set first pointer of the list */ /* set first pointer of the list */
*headersourcelist = newheadersourcelist; ct->headersourcelist = newheadersourcelist;
} }
} }
int int
addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configTag *ct, addToSourceHeaderList(struct configTag *ct, int mode, int altrepository)
int mode, int altrepository)
{ {
char *scanpath; char *scanpath;
struct repoData* repodata = NULL;
struct headerSourceList *newheadersourcelist; struct headerSourceList *newheadersourcelist;
struct dirent **namelist; struct dirent **namelist;
struct changeLog *changelog; struct changeLog *changelog;
@ -963,19 +933,23 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
uint_32 *requireflags, *dirindexes; uint_32 *requireflags, *dirindexes;
char warning[PATH_MAX]; char warning[PATH_MAX];
rpmts ts; rpmts ts;
struct repoData* repodata = NULL;
currheadersourcelist = 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); if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
logmsg(LOG_DEBUG,"Scanning source packages in repository %s...", ct->tag);
} 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); if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL);
logmsg(LOG_DEBUG,"Scanning source packages in repository %s...", ct->tag);
} 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); if (ct->repodata_url) repodata = getRepodata(ct->repository[altrepository]->repodata_url, NULL);
logmsg(LOG_DEBUG,"Scanning source packages in repository %s...", ct->repository[altrepository]->tag);
} }
if (repodata) { if (repodata) {
// Use repodata // Use repodata
@ -1044,17 +1018,19 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
newheadersourcelist->buildtime = atoi( newheadersourcelist->buildtime = atoi(
(char*)findXMLAttributeByName(ptime, "build")); (char*)findXMLAttributeByName(ptime, "build"));
xmlNode *psize = findXMLPropertyByName(package_node, "size"); xmlNode *psize = findXMLPropertyByName(package_node, "size");
newheadersourcelist->buildtime = atoi( newheadersourcelist->size = atoi(
(char*)findXMLAttributeByName(psize, "package")); (char*)findXMLAttributeByName(psize, "package"));
//hl->patch = headerGetStringArrayEntry(h, RPMTAG_PATCH, &count); //hl->patch = headerGetStringArrayEntry(h, RPMTAG_PATCH, &count);
addNewToSourceHeaderList(headersourcelist, // TODO
newheadersourcelist, ct, altrepository); newheadersourcelist->requirecount = 0;
newheadersourcelist->filenamecount = 0;
addNewToSourceHeaderList(newheadersourcelist, ct, altrepository);
} }
} }
cleanRepodata(repodata); cleanRepodata(repodata);
} else { } else {
// Scan local repository dir // Scan local repository dir
ts = rpmtsCreate(); ts = rpmtsCreate();
@ -1142,8 +1118,7 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
newheadersourcelist->changelog = NULL; newheadersourcelist->changelog = NULL;
} }
addNewToSourceHeaderList(headersourcelist, addNewToSourceHeaderList(newheadersourcelist, ct, altrepository);
newheadersourcelist, ct, altrepository);
(void) headerFree(h); (void) headerFree(h);
} // if getHeader() } // if getHeader()
@ -1158,13 +1133,12 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT
int int
generateSourceHeaderList(struct configTag *ct, int mode, int incremental) generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
{ {
struct headerSourceList **headersourcelist = &(ct->headersourcelist);
int i; int i;
if (incremental) { if (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(ct, mode, i)) {
logmsg(LOG_ERROR,"Error scanning SRPMs repository"); logmsg(LOG_ERROR,"Error scanning SRPMs repository");
return 1; return 1;
} }
@ -1173,7 +1147,7 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
} }
} }
} else { } else {
if (addToSourceHeaderList(headersourcelist, ct, mode, -1)) { if (addToSourceHeaderList(ct, mode, -1)) {
logmsg(LOG_ERROR,"Error scanning SRPMs repository"); logmsg(LOG_ERROR,"Error scanning SRPMs repository");
return 1; return 1;
} }
@ -1181,24 +1155,117 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental)
return 0; return 0;
} }
int addNewToHeaderList(struct headerList **currheaderlist,
struct headerList *newheaderlist, struct configTag *ct,
int altrepository, int arch) {
struct headerList *currbrother;
if (!newheaderlist->sourcename) {
logmsg(LOG_WARNING,
"sourcename undefined in RPM %s, it might be a source RPM with wrong filename; skipping package.",
newheaderlist->name);
newheaderlist->sourceheader = NULL;
free(newheaderlist);
return -1;
} else {
if (getPackageNameFromFile(newheaderlist->sourcename)) {
logmsg(LOG_WARNING,
"file %s doesn't have a standard format; skipping package.");
newheaderlist->sourceheader = NULL;
free(newheaderlist);
return -1;
} else {
newheaderlist->sourceheader =
findSourcePackage(ct->headersourcelist,
newheaderlist->sourcename,
newheaderlist->version,
newheaderlist->release,
altrepository);
}
}
if (newheaderlist->sourceheader) {
if (!newheaderlist->sourceheader->firstchild[arch]) {
newheaderlist->sourceheader->firstchild[arch] = newheaderlist;
} else {
currbrother =
newheaderlist->sourceheader->firstchild[arch];
while (currbrother->nextbrother) {
currbrother = currbrother->nextbrother;
}
currbrother->nextbrother = newheaderlist;
}
newheaderlist->recursed = 0;
if (*currheaderlist) {
(*currheaderlist)->next = newheaderlist;
}
*currheaderlist = newheaderlist;
if (!ct->headerlist[arch]) {
/* set first pointer of the list */
ct->headerlist[arch] = newheaderlist;
}
} else if (newheaderlist->sourcename) /* missing source header */ {
if ((!newheaderlist->sourceheader) ||
(newheaderlist->sourceheader->altrepository) <= altrepository) {
logmsg(LOG_WARNING,"%s(%s,%s): missing SRPM %s-%s-%s; skipping.",
newheaderlist->name,
ct->arch[arch],
ct->repository[altrepository]->tag,
newheaderlist->sourcename,
newheaderlist->version, newheaderlist->release);
free(newheaderlist);
return -1;
}
} // if newheaderlist->sourceheader
return 0;
}
char* advanceXMLPackageNode(char* prevname, xmlNode **package_node) {
char* currname;
// check if already currname > prevname
if (*package_node && !strcmp((char*)(*package_node)->name, "package")) {
currname = strdup((char*)
findXMLPropertyByName(*package_node, "name")->children->content);
// package_node is already advanced
if (strcmp(prevname, currname) < 0) return currname;
free(currname);
}
// nope: go to next package
if (*package_node) *package_node = (*package_node)->next;
while (*package_node && strcmp((char*)(*package_node)->name, "package"))
*package_node = (*package_node)->next;
if (*package_node) {
currname = strdup((char*)
findXMLPropertyByName(*package_node, "name")->children->content);
return currname;
}
return NULL;
}
/* /*
* Reads all headers and generates a structure based on struct headerList */ * Reads all headers and generates a structure based on struct headerList
int addToHeaderList(struct configTag *ct, */
const char *scanpath, /*int mode,*/ int generateHeaderList(struct configTag* ct, int arch, int incremental) {
const char *scantag,
const char *altscanpath[ALT_REPS_MAX], struct repoData* repodata[ALT_REPS_MAX + 1];
const char *altscantag[ALT_REPS_MAX], xmlNode *package_node[ALT_REPS_MAX + 1];
int arch) { char nextname[bufsize + 1];
struct headerList *currheaderlist, *newheaderlist, *currbrother;
char scanpath[bufsize + 1], *altscanpath[ALT_REPS_MAX];
char *scantag, *altscantag[ALT_REPS_MAX];
int cnt = 0, altcnt[ALT_REPS_MAX];
struct headerList *currheaderlist, *newheaderlist;
struct providedList *provided; struct providedList *provided;
struct headerList ** newprovider; struct headerList ** newprovider;
struct dirent **namelist, **altnamelist[ALT_REPS_MAX]; struct dirent **namelist, **altnamelist[ALT_REPS_MAX];
Header h; Header h;
char filepath[bufsize + 1], currname[bufsize + 1]; char filepath[bufsize + 1], currname[bufsize + 1];
char *filename=NULL; char *filename=NULL;
long i ,j , k, n, altn[ALT_REPS_MAX]; long i ,j , k, n=0, altn[ALT_REPS_MAX];
int altrepository=0, obsoletecount, providecount, requirecount, int altrepository=0, obsoletecount, providecount, requirecount,
filenamecount, dirnamecount; filenamecount, dirnamecount, alt_reps_num = 0;
int_16 *fileflags; int_16 *fileflags;
char **obsoletename, **obsoleteversion, char **obsoletename, **obsoleteversion,
**providename, **provideversion, **providename, **provideversion,
@ -1213,272 +1280,322 @@ int addToHeaderList(struct configTag *ct,
rpmts ts = NULL; rpmts ts = NULL;
#endif #endif
repodata[0] = NULL;
cleanProvidedListIndex(ct,arch);
if (incremental) {
if (ct->repository[0]) {
snprintf(scanpath,bufsize,"%sRPMS.%s/",ct->repository[0]->repository_dir,ct->arch[arch]);
scantag = ct->repository[0]->tag;
if (ct->repository[0]->repodata_url) repodata[0] = getRepodata(
ct->repository[0]->repodata_url, ct->arch[arch]);
for (i = 1; i <= ct->repository_level; i++) {
if (ct->repository[i]) {
altscanpath[i-1] = malloc(bufsize);
snprintf(altscanpath[i-1], bufsize, "%sRPMS.%s/",ct->repository[i]->repository_dir,ct->arch[arch]);
altscantag[i-1] = ct->repository[i]->tag;
if (ct->repository[i]->repodata_url) {
if (!repodata[0]) logmsg(LOG_ERROR,
"repodata_url must be defined in main and parent repositories; aborting.");
repodata[i] = getRepodata(
ct->repository[i]->repodata_url, ct->arch[arch]);
}
alt_reps_num++;
} else {
logmsg(LOG_ERROR,"repository[i] not defined; aborting.");
return 1;
}
}
} else {
logmsg(LOG_ERROR,"repository[0] is not defined; aborting.");
return 1;
}
} else {
snprintf(scanpath,bufsize,"%sRPMS.%s/",ct->repository_dir,ct->arch[arch]);
scantag = ct->tag;
if (ct->repodata_url) repodata[0] = getRepodata(ct->repodata_url,
ct->arch[arch]);
}
currheaderlist = ct->headerlist[arch]; currheaderlist = ct->headerlist[arch];
n = scansdir(scanpath, &namelist, rpmselector, scanrpmnamecmp); if (repodata[0]) {
if (n < 0) { for (i = 0; i <= alt_reps_num; i++) {
errstr = strerror(errno); package_node[i] = xmlDocGetRootElement(repodata[i]->primary_doc)->children;
logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", scantag, scanpath, errstr); }
return 1; } else {
} n = scansdir(scanpath, &namelist, rpmselector, scanrpmnamecmp);
logmsg(LOG_DEBUG, "%s scan directory is '%s'", scantag, scanpath); if (n < 0) {
for (i = 0; i < ALT_REPS_MAX; i++) { errstr = strerror(errno);
if (altscanpath[i]) { logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", scantag, scanpath, errstr);
altn[i] = scansdir(altscanpath[i], &altnamelist[i], rpmselector, scanrpmnamecmp); return 1;
logmsg(LOG_DEBUG, "%s scan directory is '%s'", altscantag[i], altscanpath[i]); }
if (altn[i] < 0) { for (i = 0; i < alt_reps_num; i++) {
errstr = strerror(errno); altn[i] = scansdir(altscanpath[i], &altnamelist[i], rpmselector, scanrpmnamecmp);
logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", altscantag[i], altscanpath[i], errstr); logmsg(LOG_DEBUG, "%s scan directory is '%s'", altscantag[i], altscanpath[i]);
return 1; if (altn[i] < 0) {
} errstr = strerror(errno);
} else { break; } logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", altscantag[i], altscanpath[i], errstr);
} return 1;
if (i < ALT_REPS_MAX) { }
altnamelist[i]=NULL; }
} logmsg(LOG_DEBUG, "%s scan directory is '%s'", scantag, scanpath);
for (i = 0; i < alt_reps_num; i++) {
int cnt = 0, altcnt[ALT_REPS_MAX]; altcnt[i]=0;
for (i = 0; i < ALT_REPS_MAX; i++) { }
altcnt[i]=0;
} }
while (1) { while (1) {
/* check for duplicates in main repository */ if (repodata[0]) {
if ((cnt < n - 1) && /* Use repodata */
(!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) { int altidx = -1;
logmsg(LOG_WARNING, "%s: duplicated RPM package in %s repository (skipped)",namelist[cnt]->d_name, scantag); char *newname = NULL;
cnt++; nextname[0] = '\0';
} for (i = 0; i <= alt_reps_num; i++) {
/* find next package in all repositories */ newname = advanceXMLPackageNode(currname, &(package_node[i]));
if (cnt < n) { if (newname) {
strncpy(currname, namelist[cnt]->d_name, bufsize); if (nextname[0] == '\0' || strcmp(nextname, newname) >= 0) {
} else { strncpy(nextname, newname, bufsize);
currname[0] = '\0'; altidx = i;
} }
for (i = 0; i < ALT_REPS_MAX; i++) { free(newname);
/* scan alternate repositories to find any package which comes first according to name sorting */ }
if (altscanpath[i] && (altcnt[i] < altn[i]) && }
((rpmnamecmp(currname, altnamelist[i][altcnt[i]]->d_name,0) >= 0) || (currname[0] == '\0'))) { if (altidx >=0) {
strncpy(currname, altnamelist[i][altcnt[i]]->d_name,bufsize); strncpy(currname, nextname, bufsize);
} //printf("alt%d %s\n", altidx, currname);
} }
/* clean repodata and break while loop when no more packages are found */
if (altidx == -1) {
for (i = 0; i <= alt_reps_num; i++) {
cleanRepodata(repodata[i]);
}
break;
}
/* process package */
newheaderlist = malloc(sizeof(struct headerList));
if (newheaderlist == NULL) {
logmsg(LOG_ERROR,"cannot allocate new memory; aborting.\n");
return 1;
}
memset(newheaderlist, 0, sizeof(struct headerList));
newheaderlist->name = strdup((char*)
findXMLPropertyByName(package_node[altidx], "name")->children->content);
xmlNode *version = findXMLPropertyByName(package_node[altidx], "version");
newheaderlist->epoch = atoi((char*)findXMLAttributeByName(version, "epoch"));
newheaderlist->version = strdup((char*)findXMLAttributeByName(version, "ver"));
newheaderlist->release = strdup((char*)findXMLAttributeByName(version, "rel"));
newheaderlist->summary = strdup((char*)
findXMLPropertyByName(package_node[altidx], "summary")->children->content);
newheaderlist->arch = strdup((char*)
findXMLPropertyByName(package_node[altidx], "arch")->children->content);
if (findXMLPropertyByName(package_node[altidx], "description")->children) {
newheaderlist->description = strdup((char*)
findXMLPropertyByName(package_node[altidx], "description")->children->content);
}
xmlNode *format = findXMLPropertyByName(package_node[altidx], "format");
newheaderlist->group = strdup((char*)
findXMLPropertyByName(format, "group")->children->content);
newheaderlist->sourcename = strdup((char*)
findXMLPropertyByName(format, "sourcerpm")->children->content);
xmlNode *psize = findXMLPropertyByName(package_node[altidx], "size");
newheaderlist->size = atoi(
(char*)findXMLAttributeByName(psize, "package"));
int ret = addNewToHeaderList(&currheaderlist, newheaderlist, ct,
altidx, arch);
if (ret == 0) {
newheaderlist->providecount = 0;
newheaderlist->requirecount = 0;
// TODO
}
if (cnt < n && (rpmnamecmp(currname, namelist[cnt]->d_name, 0) == 0)) {
/* selected package exists in base repository */
memcpy(filepath, scanpath, strlen(scanpath) + 1);
filename=&filepath[strlen(scanpath)];
strncpy(filename, namelist[cnt]->d_name,bufsize-strlen(scanpath));
altrepository=0;
cnt++;
} else { } else {
for (i = 0; i < ALT_REPS_MAX; i++) { /* Scan packages from local directories */
if (altscanpath[i] && (altcnt[i] < altn[i]) && /* check for duplicates in main repository */
(strncmp(currname, altnamelist[i][altcnt[i]]->d_name, bufsize) == 0)) { if ((cnt < n - 1) &&
/* selected package exists in this repository */ (!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) {
memcpy(filepath, altscanpath[i], strlen(altscanpath[i]) + 1); logmsg(LOG_WARNING, "%s: duplicated RPM package in %s repository (skipped)",namelist[cnt]->d_name, scantag);
filename=&filepath[strlen(altscanpath[i])]; cnt++;
strncpy(filename, (altnamelist[i])[altcnt[i]]->d_name, bufsize-strlen(altscanpath[i])); }
altrepository=i+1; /* find next package in all repositories */
altcnt[i]++; if (cnt < n) {
/* check for duplicates in alternate repository */ strncpy(currname, namelist[cnt]->d_name, bufsize);
if ((altcnt[i] < altn[i] - 1) && } else {
(!rpmnamecmp(altnamelist[i][altcnt[i]]->d_name,altnamelist[i][altcnt[i]+1]->d_name,0))) { currname[0] = '\0';
if (i == ct->repository_level-1) { }
logmsg(LOG_WARNING, "%s: duplicated RPM package (skipped)", for (i = 0; i < alt_reps_num; i++) {
altnamelist[i][altcnt[i]]->d_name, altscantag[i]); /* scan alternate repositories to find any package which comes first according to name sorting */
} if ((altcnt[i] < altn[i]) &&
} ((rpmnamecmp(currname, altnamelist[i][altcnt[i]]->d_name,0) >= 0) || (currname[0] == '\0'))) {
break; strncpy(currname, altnamelist[i][altcnt[i]]->d_name,bufsize);
} }
} }
if (cnt < n && (rpmnamecmp(currname, namelist[cnt]->d_name, 0) == 0)) {
/* selected package exists in base repository */
memcpy(filepath, scanpath, strlen(scanpath) + 1);
filename=&filepath[strlen(scanpath)];
strncpy(filename, namelist[cnt]->d_name,bufsize-strlen(scanpath));
altrepository=0;
cnt++;
} else {
for (i = 0; i < alt_reps_num; i++) {
if ((altcnt[i] < altn[i]) &&
(strncmp(currname, altnamelist[i][altcnt[i]]->d_name, bufsize) == 0)) {
/* selected package exists in this repository */
memcpy(filepath, altscanpath[i], strlen(altscanpath[i]) + 1);
filename=&filepath[strlen(altscanpath[i])];
strncpy(filename, (altnamelist[i])[altcnt[i]]->d_name, bufsize-strlen(altscanpath[i]));
altrepository=i+1;
altcnt[i]++;
/* check for duplicates in alternate repository */
if ((altcnt[i] < altn[i] - 1) &&
(!rpmnamecmp(altnamelist[i][altcnt[i]]->d_name,altnamelist[i][altcnt[i]+1]->d_name,0))) {
if (i == ct->repository_level-1) {
logmsg(LOG_WARNING, "%s: duplicated RPM package (skipped)",
altnamelist[i][altcnt[i]]->d_name, altscantag[i]);
}
}
break;
}
}
}
/* break while loop when no more packages are found */
if (currname[0] == '\0') { break; }
/* process package */
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.",filename, errstr);
} else {
getPackageObsoletes(h, &obsoletename, &obsoleteflags,
&obsoleteversion, &obsoletecount);
getPackageProvides(h, &providename, &provideflags,
&provideversion, &providecount);
getPackageRequires(h, &requirename, &requireflags,
&requireversion, &requirecount);
getPackageFiles(h, &dirindex, &dirname, &dirnamecount,
&basename, &filenamecount,
&fileusername, &filegroupname, &fileflags);
newheaderlist = malloc(sizeof(struct headerList));
if (newheaderlist == NULL) {
logmsg(LOG_ERROR,"cannot allocate new memory; aborting.\n");
return 1;
}
memset(newheaderlist, 0, sizeof(struct headerList));
getPackageInfoIntoHeaderList(h, newheaderlist);
int ret = addNewToHeaderList(&currheaderlist, newheaderlist, ct,
altrepository, arch);
if (ret == 0) {
newheaderlist->provided = malloc(sizeof(struct providedList*)*providecount);
for (i=0; i < providecount; i++) {
provided = findOrCreateProvidedListEntry(
(struct providedList **) &(ct->providedlist_idx[arch]),
providename[i],1,arch);
newheaderlist->provided[i]=provided;
if (provided && (provided->numproviders == 0)) {
provided->flags=provideflags[i];
provided->numproviders++;
provided->provider=malloc(sizeof(struct headerList*));
provided->provider[0]=newheaderlist;
provided->version=malloc(sizeof(char *));
provided->version[0]=strdup(provideversion[i]);
} else if (provided && (provided->numproviders > 0)) {
provided->numproviders++;
newprovider=malloc(sizeof(struct headerList*)*provided->numproviders);
for (j = 0; j < provided->numproviders-1; j++) {
newprovider[j]=provided->provider[j];
}
newprovider[provided->numproviders-1] = newheaderlist;
free(provided->provider);
provided->provider=newprovider;
newversion=malloc(sizeof(char *)*provided->numproviders);
for (j = 0; j < provided->numproviders-1; j++) {
newversion[j]=provided->version[j];
}
newversion[provided->numproviders-1] = strdup(provideversion[i]);
free(provided->version);
provided->version=newversion;
} else {
fprintf(stderr,"%s has %d providers but is ignored\n",provided->name,provided->numproviders);
}
}
newheaderlist->providename = providename;
newheaderlist->provideflags = provideflags;
newheaderlist->provideversion = provideversion;
newheaderlist->providecount = providecount;
newheaderlist->obsoletename = obsoletename;
newheaderlist->obsoleteflags = obsoleteflags;
newheaderlist->obsoleteversion = obsoleteversion;
newheaderlist->obsoletecount = obsoletecount;
newheaderlist->altrepository = altrepository;
newheaderlist->require = malloc(requirecount * sizeof(struct Require *));
for (j=0; j < requirecount; j++) {
newheaderlist->require[j] = malloc(sizeof(struct Require));
newheaderlist->require[j]->name = requirename[j];
newheaderlist->require[j]->flags = requireflags[j];
newheaderlist->require[j]->version = requireversion[j];
newheaderlist->require[j]->resolved = NULL;
}
newheaderlist->requirecount = requirecount;
newheaderlist->file =
malloc(sizeof(struct fileTree*) * filenamecount);
newheaderlist->fileflags =
malloc(sizeof(int_16 *) * filenamecount);
newheaderlist->fileuser =
malloc(sizeof(struct fileUserList *) * filenamecount);
newheaderlist->filegroup =
malloc(sizeof(char *) * filenamecount);
for (j=0; j<filenamecount; j++) {
snprintf(filename,bufsize,"%s%s",dirname[dirindex[j]],basename[j]);
newheaderlist->file[j] = findOrCreateFileTreeEntry(&ct->filetree[arch], filename, arch);
newheaderlist->fileflags[j] = fileflags[j];
newheaderlist->fileuser[j] = findOrCreateFileUserListEntry(&ct->fileuserlist[arch], fileusername[j], arch);
free(fileusername[j]);
newheaderlist->filegroup[j] = findOrCreateFileGroupListEntry(&ct->filegrouplist[arch], filegroupname[j], arch);
free(filegroupname[j]);
if (newheaderlist->file[j]->numproviders == 0) {
newheaderlist->file[j]->numproviders++;
newheaderlist->file[j]->provider=malloc(sizeof(struct headerList*));
newheaderlist->file[j]->provider[0]=newheaderlist;
} else {
/* check if the package is already providing it... */
for (k = 0; k < newheaderlist->file[j]->numproviders; k++) {
if (newheaderlist->file[j]->provider[k] == newheaderlist)
break;
}
/* if not add to the list of providers */
if (k == newheaderlist->file[j]->numproviders) {
newheaderlist->file[j]->numproviders++;
newprovider=malloc(
sizeof(struct headerList*)*newheaderlist->file[j]->numproviders);
for (k = 0; k < newheaderlist->file[j]->numproviders-1; k++) {
newprovider[k]=newheaderlist->file[j]->provider[k];
}
newprovider[newheaderlist->file[j]->numproviders-1] = newheaderlist;
free(newheaderlist->file[j]->provider);
newheaderlist->file[j]->provider=newprovider;
}
}
}
newheaderlist->filenamecount = filenamecount;
}
(void) headerFree(h);
} // if getHeader()
if (altrepository > 0)
free(altnamelist[altrepository-1][altcnt[altrepository-1]-1]);
else free(namelist[cnt-1]);
} }
/* break while loop when no more packages are found */
if (currname[0] == '\0') { break; }
/* process package */
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.",filename, errstr);
} else {
getPackageObsoletes(h, &obsoletename, &obsoleteflags,
&obsoleteversion, &obsoletecount);
getPackageProvides(h, &providename, &provideflags,
&provideversion, &providecount);
getPackageRequires(h, &requirename, &requireflags,
&requireversion, &requirecount);
getPackageFiles(h, &dirindex, &dirname, &dirnamecount,
&basename, &filenamecount,
&fileusername, &filegroupname, &fileflags);
newheaderlist = malloc(sizeof(struct headerList));
if (newheaderlist == NULL) {
logmsg(LOG_ERROR,"header in file %s is corrupted; aborting.\n",filepath);
return 1;
}
memset(newheaderlist, 0, sizeof(struct headerList));
getPackageInfoIntoHeaderList(h, newheaderlist);
if (!newheaderlist->sourcename) {
logmsg(LOG_WARNING,
"sourcename undefined in RPM file %s, it might be a source RPM with wrong filename; skipping package.",
filepath);
newheaderlist->sourceheader = NULL;
(void) headerFree(h);
free(newheaderlist);
continue;
} else {
if (getPackageNameFromFile(newheaderlist->sourcename)) {
logmsg(LOG_WARNING,
"file %s doesn't have a standard format; skipping package.");
newheaderlist->sourceheader = NULL;
(void) headerFree(h);
free(newheaderlist);
continue;
} else {
newheaderlist->sourceheader =
findSourcePackage(ct->headersourcelist,
newheaderlist->sourcename,
newheaderlist->version,
newheaderlist->release,
altrepository);
}
}
if (newheaderlist->sourceheader) {
if (!newheaderlist->sourceheader->firstchild[arch]) {
newheaderlist->sourceheader->firstchild[arch] = newheaderlist;
} else {
currbrother =
newheaderlist->sourceheader->firstchild[arch];
while (currbrother->nextbrother) {
currbrother = currbrother->nextbrother;
}
currbrother->nextbrother = newheaderlist;
}
newheaderlist->recursed = 0;
if (currheaderlist) {
currheaderlist->next = newheaderlist;
}
currheaderlist = newheaderlist;
if (!ct->headerlist[arch]) {
/* set first pointer of the list */
ct->headerlist[arch] = newheaderlist;
}
} else if (newheaderlist->sourcename) /* missing source header */ {
if ((!newheaderlist->sourceheader) ||
(newheaderlist->sourceheader->altrepository) <= altrepository) {
logmsg(LOG_WARNING,"%s(%s,%s): missing SRPM %s-%s-%s; skipping.",
newheaderlist->name,
ct->arch[arch],
ct->repository[altrepository]->tag,
newheaderlist->sourcename,
newheaderlist->version, newheaderlist->release);
(void) headerFree(h);
free(newheaderlist);
continue;
}
} // if newheaderlist->sourceheader
newheaderlist->provided = malloc(sizeof(struct providedList*)*providecount);
for (i=0; i < providecount; i++) {
provided = findOrCreateProvidedListEntry(
(struct providedList **) &(ct->providedlist_idx[arch]),
providename[i],1,arch);
newheaderlist->provided[i]=provided;
if (provided && (provided->numproviders == 0)) {
provided->flags=provideflags[i];
provided->numproviders++;
provided->provider=malloc(sizeof(struct headerList*));
provided->provider[0]=newheaderlist;
provided->version=malloc(sizeof(char *));
provided->version[0]=strdup(provideversion[i]);
} else if (provided && (provided->numproviders > 0)) {
provided->numproviders++;
newprovider=malloc(sizeof(struct headerList*)*provided->numproviders);
for (j = 0; j < provided->numproviders-1; j++) {
newprovider[j]=provided->provider[j];
}
newprovider[provided->numproviders-1] = newheaderlist;
free(provided->provider);
provided->provider=newprovider;
newversion=malloc(sizeof(char *)*provided->numproviders);
for (j = 0; j < provided->numproviders-1; j++) {
newversion[j]=provided->version[j];
}
newversion[provided->numproviders-1] = strdup(provideversion[i]);
free(provided->version);
provided->version=newversion;
} else {
fprintf(stderr,"%s has %d providers but is ignored\n",provided->name,provided->numproviders);
}
}
newheaderlist->providename = providename;
newheaderlist->provideflags = provideflags;
newheaderlist->provideversion = provideversion;
newheaderlist->providecount = providecount;
newheaderlist->obsoletename = obsoletename;
newheaderlist->obsoleteflags = obsoleteflags;
newheaderlist->obsoleteversion = obsoleteversion;
newheaderlist->obsoletecount = obsoletecount;
newheaderlist->altrepository = altrepository;
newheaderlist->require = malloc(requirecount * sizeof(struct Require *));
for (j=0; j < requirecount; j++) {
newheaderlist->require[j] = malloc(sizeof(struct Require));
newheaderlist->require[j]->name = requirename[j];
newheaderlist->require[j]->flags = requireflags[j];
newheaderlist->require[j]->version = requireversion[j];
newheaderlist->require[j]->resolved = NULL;
}
newheaderlist->requirecount = requirecount;
newheaderlist->file =
malloc(sizeof(struct fileTree*) * filenamecount);
newheaderlist->fileflags =
malloc(sizeof(int_16 *) * filenamecount);
newheaderlist->fileuser =
malloc(sizeof(struct fileUserList *) * filenamecount);
newheaderlist->filegroup =
malloc(sizeof(char *) * filenamecount);
for (j=0; j<filenamecount; j++) {
snprintf(filename,bufsize,"%s%s",dirname[dirindex[j]],basename[j]);
newheaderlist->file[j] = findOrCreateFileTreeEntry(&ct->filetree[arch], filename, arch);
newheaderlist->fileflags[j] = fileflags[j];
newheaderlist->fileuser[j] = findOrCreateFileUserListEntry(&ct->fileuserlist[arch], fileusername[j], arch);
free(fileusername[j]);
newheaderlist->filegroup[j] = findOrCreateFileGroupListEntry(&ct->filegrouplist[arch], filegroupname[j], arch);
free(filegroupname[j]);
if (newheaderlist->file[j]->numproviders == 0) {
newheaderlist->file[j]->numproviders++;
newheaderlist->file[j]->provider=malloc(sizeof(struct headerList*));
newheaderlist->file[j]->provider[0]=newheaderlist;
} else {
/* check if the package is already providing it... */
for (k = 0; k < newheaderlist->file[j]->numproviders; k++) {
if (newheaderlist->file[j]->provider[k] == newheaderlist)
break;
}
/* if not add to the list of providers */
if (k == newheaderlist->file[j]->numproviders) {
newheaderlist->file[j]->numproviders++;
newprovider=malloc(
sizeof(struct headerList*)*newheaderlist->file[j]->numproviders);
for (k = 0; k < newheaderlist->file[j]->numproviders-1; k++) {
newprovider[k]=newheaderlist->file[j]->provider[k];
}
newprovider[newheaderlist->file[j]->numproviders-1] = newheaderlist;
free(newheaderlist->file[j]->provider);
newheaderlist->file[j]->provider=newprovider;
}
}
}
newheaderlist->filenamecount = filenamecount;
(void) headerFree(h);
} // if getHeader()
if (altrepository > 0)
free(altnamelist[altrepository-1][altcnt[altrepository-1]-1]);
else free(namelist[cnt-1]);
} // main while } // main while
#if RPM_VERSION >= 0x050000 #if RPM_VERSION >= 0x050000
rpmtsFree(ts); rpmtsFree(ts);
@ -1487,44 +1604,3 @@ int addToHeaderList(struct configTag *ct,
createProvidedListIndex((struct providedList **)&(ct->providedlist_idx[arch]), arch); createProvidedListIndex((struct providedList **)&(ct->providedlist_idx[arch]), arch);
return 0; return 0;
} }
int
generateHeaderList(struct configTag* ct, int arch, int incremental)
{
char scanpath[bufsize + 1], *altscanpath[ALT_REPS_MAX];
char *scantag, *altscantag[ALT_REPS_MAX];
int i;
for (i = 0; i < ALT_REPS_MAX; i++)
altscanpath[i] = NULL;
cleanProvidedListIndex(ct,arch);
if (incremental) {
if (ct->repository[0]) {
snprintf(scanpath,bufsize,"%sRPMS.%s/",ct->repository[0]->repository_dir,ct->arch[arch]);
scantag = ct->repository[0]->tag;
for (i = 1; i <= ct->repository_level; i++) {
if (ct->repository[i]) {
altscanpath[i-1] = malloc(bufsize);
snprintf(altscanpath[i-1], bufsize, "%sRPMS.%s/",ct->repository[i]->repository_dir,ct->arch[arch]);
altscantag[i-1] = ct->repository[i]->tag;
} else {
logmsg(LOG_ERROR,"repository[i] not defined; aborting.");
return 1;
}
}
} else {
logmsg(LOG_ERROR,"repository[0] is not defined; aborting.");
return 1;
}
} else {
snprintf(scanpath,bufsize,"%sRPMS.%s/",ct->repository_dir,ct->arch[arch]);
scantag = ct->tag;
}
if (addToHeaderList(ct, scanpath, scantag, (const char**)altscanpath, (const char**)altscantag, arch)) {
logmsg(LOG_ERROR,"Error scanning RPMs repository");
return 1;
}
return 0;
}

View File

@ -205,7 +205,6 @@ int generateSourceHeaderList(struct configTag *ct, int mode, int incremental);
int int
addToSourceHeaderList( addToSourceHeaderList(
struct headerSourceList **headersourcelist,
struct configTag *ct, struct configTag *ct,
int mode, int mode,
int altrepository); int altrepository);

View File

@ -70,6 +70,8 @@ getPackageFiles(Header h, uint_32 **dirindexes,
char ***usernames, char ***groupnames, char ***usernames, char ***groupnames,
int_16 **fileflags); int_16 **fileflags);
int rpmnameidx(char *filename);
int rpmnamecmp(char *filename1, char *filename2, int checkver); int rpmnamecmp(char *filename1, char *filename2, int checkver);
int scanrpmnamecmp(const struct dirent **f1, const struct dirent **f2); int scanrpmnamecmp(const struct dirent **f1, const struct dirent **f2);

View File

@ -354,27 +354,26 @@ getPackageFiles(Header h, uint_32 **dirindexes,
return 0; return 0;
} }
/* find name end position assuming a "name-version-release" scheme */
int rpmnameidx(char *filename) {
int i, f=0, idx=0;
for (i = strlen(filename)-1; (i > 0) && (f < 2); i--) {
if (filename[i] == '-') {
f++;
idx=i-1;
}
}
return idx;
}
/* compare two rpm filenames by name and version */
int rpmnamecmp(char *filename1, char *filename2, int checkver) { int rpmnamecmp(char *filename1, char *filename2, int checkver) {
int end1=0, end2=0, f, i; int end1=0, end2=0, i;
char c1,c2; char c1,c2;
f=0; /* find idx of base name from filenames */
end1 = rpmnameidx(filename1);
/* find name end position assuming a "name-version-release" scheme */ end2 = rpmnameidx(filename2);
for (i = strlen(filename1)-1; (i > 0) && (f < 2); i--) {
if (filename1[i] == '-') {
f++;
end1=i-1;
}
}
f=0;
for (i = strlen(filename2)-1; (i > 0) && (f < 2); i--) {
if (filename2[i] == '-') {
f++;
end2=i-1;
}
}
/* make comparison, case insensitive */ /* make comparison, case insensitive */
for (i=0; (i <= end1) && (i <= end2); i++) { for (i=0; (i <= end1) && (i <= end2); i++) {