From d24817d3a32d69c7bb1bf4e778a0db07600ace79 Mon Sep 17 00:00:00 2001 From: Silvan Calarco Date: Mon, 15 Feb 2021 21:48:54 +0100 Subject: [PATCH] Second part of support for getting info from repodata --- src/headerlist.c | 810 ++++++++++++++++++++----------------- src/include/headerlist.h | 1 - src/include/rpmfunctions.h | 2 + src/rpmfunctions.c | 35 +- 4 files changed, 462 insertions(+), 386 deletions(-) diff --git a/src/headerlist.c b/src/headerlist.c index 0a0e97e..457f306 100644 --- a/src/headerlist.c +++ b/src/headerlist.c @@ -142,21 +142,10 @@ findPackageByName(struct headerList *list, char *name) int getPackageNameFromFile(char *name) { - char *st1, *st2; - - st2 = strrchr(name, '-'); - if (st2) { - *st2 = '\0'; - st1 = strrchr(name, '-'); - if (st1) { - *st1 = '\0'; - } else { - /* something wrong occurred: revert all */ - *st2 = '-'; - return 1; - } - } - return 0; + int idx = rpmnameidx(name); + if (idx < 0 || idx+1 >= strlen(name)) return 1; + name[idx + 1] = '\0'; + return 0; } struct headerSourceList * @@ -657,6 +646,8 @@ struct repoData* getRepodata(char *repodata_url, char *arch) { else snprintf(urls[0], PATH_MAX, "%s/RPMS.%s/", repodata_url, arch); + logmsg(LOG_DEBUG, "fetching repodata from %s...", urls[0]); + h = lr_handle_init(); r = lr_result_init(); @@ -711,27 +702,6 @@ struct repoData* getRepodata(char *repodata_url, char *arch) { 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");*/ } } @@ -867,13 +837,13 @@ xmlNode* findXMLPackageByName(xmlNode *root_node, char* name) { } static long sourceid = 0; +struct headerSourceList *currheadersourcelist = NULL; -void addNewToSourceHeaderList(struct headerSourceList **headersourcelist, - struct headerSourceList *newheadersourcelist, struct configTag *ct, - int altrepository) { +void addNewToSourceHeaderList(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 @@ -882,9 +852,9 @@ void addNewToSourceHeaderList(struct headerSourceList **headersourcelist, if (currheadersourcelist) { currheadersourcelist->next = newheadersourcelist; } - currheadersourcelist = newheadersourcelist; + currheadersourcelist = newheadersourcelist; } else { /* altrepository */ - currheadersourcelist = *headersourcelist; + currheadersourcelist = ct->headersourcelist; prevheadersourcelist = NULL; while ((currheadersourcelist) && (strcasecmp(currheadersourcelist->name,newheadersourcelist->name) < 0)) { @@ -933,22 +903,22 @@ void addNewToSourceHeaderList(struct headerSourceList **headersourcelist, if (prevheadersourcelist) { prevheadersourcelist->next = newheadersourcelist; } else { - *headersourcelist = newheadersourcelist; + ct->headersourcelist = newheadersourcelist; } } /* altrepository */ - if (!*headersourcelist) { + if (!ct->headersourcelist) { /* set first pointer of the list */ - *headersourcelist = newheadersourcelist; + ct->headersourcelist = newheadersourcelist; } } int -addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configTag *ct, - int mode, int altrepository) +addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) { char *scanpath; + struct repoData* repodata = NULL; struct headerSourceList *newheadersourcelist; struct dirent **namelist; struct changeLog *changelog; @@ -963,19 +933,23 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT uint_32 *requireflags, *dirindexes; char warning[PATH_MAX]; rpmts ts; - struct repoData* repodata = NULL; + + currheadersourcelist = NULL; if (altrepository == ct->repository_level) { scanpath = ct->repository_source_dir; 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) { // non-incremental mode scanpath = ct->repository_source_dir; altrepository = 0; if (ct->repodata_url) repodata = getRepodata(ct->repodata_url, NULL); + logmsg(LOG_DEBUG,"Scanning source packages in repository %s...", ct->tag); } else { scanpath = ct->repository[altrepository]->repository_source_dir; 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) { // Use repodata @@ -1044,17 +1018,19 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT newheadersourcelist->buildtime = atoi( (char*)findXMLAttributeByName(ptime, "build")); xmlNode *psize = findXMLPropertyByName(package_node, "size"); - newheadersourcelist->buildtime = atoi( + newheadersourcelist->size = atoi( (char*)findXMLAttributeByName(psize, "package")); //hl->patch = headerGetStringArrayEntry(h, RPMTAG_PATCH, &count); - addNewToSourceHeaderList(headersourcelist, - newheadersourcelist, ct, altrepository); + // TODO + newheadersourcelist->requirecount = 0; + newheadersourcelist->filenamecount = 0; + + addNewToSourceHeaderList(newheadersourcelist, ct, altrepository); + } } - cleanRepodata(repodata); - } else { // Scan local repository dir ts = rpmtsCreate(); @@ -1142,8 +1118,7 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT newheadersourcelist->changelog = NULL; } - addNewToSourceHeaderList(headersourcelist, - newheadersourcelist, ct, altrepository); + addNewToSourceHeaderList(newheadersourcelist, ct, altrepository); (void) headerFree(h); } // if getHeader() @@ -1158,13 +1133,12 @@ addToSourceHeaderList(struct headerSourceList **headersourcelist, struct configT int generateSourceHeaderList(struct configTag *ct, int mode, int incremental) { - struct headerSourceList **headersourcelist = &(ct->headersourcelist); int i; if (incremental) { for (i = 0; i <= ct->repository_level; i++) { if (ct->repository[i]) { - if (addToSourceHeaderList(headersourcelist, ct, mode, i)) { + if (addToSourceHeaderList(ct, mode, i)) { logmsg(LOG_ERROR,"Error scanning SRPMs repository"); return 1; } @@ -1173,7 +1147,7 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental) } } } else { - if (addToSourceHeaderList(headersourcelist, ct, mode, -1)) { + if (addToSourceHeaderList(ct, mode, -1)) { logmsg(LOG_ERROR,"Error scanning SRPMs repository"); return 1; } @@ -1181,24 +1155,117 @@ generateSourceHeaderList(struct configTag *ct, int mode, int incremental) 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 */ -int addToHeaderList(struct configTag *ct, - const char *scanpath, /*int mode,*/ - const char *scantag, - const char *altscanpath[ALT_REPS_MAX], - const char *altscantag[ALT_REPS_MAX], - int arch) { - struct headerList *currheaderlist, *newheaderlist, *currbrother; + * Reads all headers and generates a structure based on struct headerList + */ + int generateHeaderList(struct configTag* ct, int arch, int incremental) { + + struct repoData* repodata[ALT_REPS_MAX + 1]; + xmlNode *package_node[ALT_REPS_MAX + 1]; + char nextname[bufsize + 1]; + + 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 headerList ** newprovider; struct dirent **namelist, **altnamelist[ALT_REPS_MAX]; Header h; char filepath[bufsize + 1], currname[bufsize + 1]; 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, - filenamecount, dirnamecount; + filenamecount, dirnamecount, alt_reps_num = 0; int_16 *fileflags; char **obsoletename, **obsoleteversion, **providename, **provideversion, @@ -1213,272 +1280,322 @@ int addToHeaderList(struct configTag *ct, rpmts ts = NULL; #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]; - n = scansdir(scanpath, &namelist, rpmselector, scanrpmnamecmp); - if (n < 0) { - errstr = strerror(errno); - logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", scantag, scanpath, errstr); - return 1; - } - logmsg(LOG_DEBUG, "%s scan directory is '%s'", scantag, scanpath); - for (i = 0; i < ALT_REPS_MAX; i++) { - if (altscanpath[i]) { - altn[i] = scansdir(altscanpath[i], &altnamelist[i], rpmselector, scanrpmnamecmp); - logmsg(LOG_DEBUG, "%s scan directory is '%s'", altscantag[i], altscanpath[i]); - if (altn[i] < 0) { - errstr = strerror(errno); - logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", altscantag[i], altscanpath[i], errstr); - return 1; - } - } else { break; } - } - if (i < ALT_REPS_MAX) { - altnamelist[i]=NULL; - } - - int cnt = 0, altcnt[ALT_REPS_MAX]; - for (i = 0; i < ALT_REPS_MAX; i++) { - altcnt[i]=0; + if (repodata[0]) { + for (i = 0; i <= alt_reps_num; i++) { + package_node[i] = xmlDocGetRootElement(repodata[i]->primary_doc)->children; + } + } else { + n = scansdir(scanpath, &namelist, rpmselector, scanrpmnamecmp); + if (n < 0) { + errstr = strerror(errno); + logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", scantag, scanpath, errstr); + return 1; + } + for (i = 0; i < alt_reps_num; i++) { + altn[i] = scansdir(altscanpath[i], &altnamelist[i], rpmselector, scanrpmnamecmp); + logmsg(LOG_DEBUG, "%s scan directory is '%s'", altscantag[i], altscanpath[i]); + if (altn[i] < 0) { + errstr = strerror(errno); + logmsg(LOG_ERROR, "%s: cannot scan directory '%s' (%s)", altscantag[i], altscanpath[i], errstr); + return 1; + } + } + logmsg(LOG_DEBUG, "%s scan directory is '%s'", scantag, scanpath); + for (i = 0; i < alt_reps_num; i++) { + altcnt[i]=0; + } } while (1) { - /* check for duplicates in main repository */ - if ((cnt < n - 1) && - (!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) { - logmsg(LOG_WARNING, "%s: duplicated RPM package in %s repository (skipped)",namelist[cnt]->d_name, scantag); - cnt++; - } - /* find next package in all repositories */ - if (cnt < n) { - strncpy(currname, namelist[cnt]->d_name, bufsize); - } else { - currname[0] = '\0'; - } - for (i = 0; i < ALT_REPS_MAX; i++) { - /* 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'))) { - strncpy(currname, altnamelist[i][altcnt[i]]->d_name,bufsize); - } - } + if (repodata[0]) { + /* Use repodata */ + int altidx = -1; + char *newname = NULL; + nextname[0] = '\0'; + for (i = 0; i <= alt_reps_num; i++) { + newname = advanceXMLPackageNode(currname, &(package_node[i])); + if (newname) { + if (nextname[0] == '\0' || strcmp(nextname, newname) >= 0) { + strncpy(nextname, newname, bufsize); + altidx = i; + } + free(newname); + } + } + if (altidx >=0) { + 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 { - for (i = 0; i < ALT_REPS_MAX; i++) { - if (altscanpath[i] && (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; - } - } + /* Scan packages from local directories */ + /* check for duplicates in main repository */ + if ((cnt < n - 1) && + (!rpmnamecmp(namelist[cnt]->d_name,namelist[cnt+1]->d_name,0))) { + logmsg(LOG_WARNING, "%s: duplicated RPM package in %s repository (skipped)",namelist[cnt]->d_name, scantag); + cnt++; + } + /* find next package in all repositories */ + if (cnt < n) { + strncpy(currname, namelist[cnt]->d_name, bufsize); + } else { + currname[0] = '\0'; + } + for (i = 0; i < alt_reps_num; 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'))) { + 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; jfile[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; jfile[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 #if RPM_VERSION >= 0x050000 rpmtsFree(ts); @@ -1487,44 +1604,3 @@ int addToHeaderList(struct configTag *ct, createProvidedListIndex((struct providedList **)&(ct->providedlist_idx[arch]), arch); 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; -} diff --git a/src/include/headerlist.h b/src/include/headerlist.h index ae63eca..cd4afaa 100644 --- a/src/include/headerlist.h +++ b/src/include/headerlist.h @@ -205,7 +205,6 @@ int generateSourceHeaderList(struct configTag *ct, int mode, int incremental); int addToSourceHeaderList( - struct headerSourceList **headersourcelist, struct configTag *ct, int mode, int altrepository); diff --git a/src/include/rpmfunctions.h b/src/include/rpmfunctions.h index bcc1e07..4f8b59c 100644 --- a/src/include/rpmfunctions.h +++ b/src/include/rpmfunctions.h @@ -70,6 +70,8 @@ getPackageFiles(Header h, uint_32 **dirindexes, char ***usernames, char ***groupnames, int_16 **fileflags); +int rpmnameidx(char *filename); + int rpmnamecmp(char *filename1, char *filename2, int checkver); int scanrpmnamecmp(const struct dirent **f1, const struct dirent **f2); diff --git a/src/rpmfunctions.c b/src/rpmfunctions.c index bdb297f..e19ed5a 100644 --- a/src/rpmfunctions.c +++ b/src/rpmfunctions.c @@ -354,27 +354,26 @@ getPackageFiles(Header h, uint_32 **dirindexes, 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 end1=0, end2=0, f, i; + int end1=0, end2=0, i; char c1,c2; - f=0; - - /* find name end position assuming a "name-version-release" scheme */ - 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; - } - } + /* find idx of base name from filenames */ + end1 = rpmnameidx(filename1); + end2 = rpmnameidx(filename2); /* make comparison, case insensitive */ for (i=0; (i <= end1) && (i <= end2); i++) {