diff --git a/src/distromatic.c b/src/distromatic.c index 86331e8..767c7c2 100644 --- a/src/distromatic.c +++ b/src/distromatic.c @@ -761,9 +761,9 @@ resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx) } //} else if (provided->numbuildproviders > 1) { /*printf("Multiple providers for %s in package %s\n",currsourceheader->require[i]->name,currsourceheader->name);*/ - } + } - if (provided->numbuildproviders > 0) { + if (provided->numbuildproviders > 0) { if (strcmp(currsourceheader->require[i]->version,"") && (currsourceheader->require[i]->flags & (RPMSENSE_LESS+RPMSENSE_GREATER+RPMSENSE_EQUAL))) { found = 0; diff --git a/src/headerlist.c b/src/headerlist.c index 457f306..bd032ef 100644 --- a/src/headerlist.c +++ b/src/headerlist.c @@ -449,11 +449,9 @@ findOrCreateProvidedListEntry(struct providedList* *idx, } } // printf("idxbot=%d idxtop=%d %s %s\n",idxbot,idxtop,idx[idxbot]->name,findname); - } currprovided = idx[idxbot]; - while (currprovided && ((c=strcmp(currprovided->name,findname)) < 0)) { prevprovided = currprovided; @@ -479,6 +477,7 @@ findOrCreateProvidedListEntry(struct providedList* *idx, newprovided->id = ++providedListId; return newprovided; } + return currprovided; } @@ -836,6 +835,87 @@ xmlNode* findXMLPackageByName(xmlNode *root_node, char* name) { return NULL; } +int XMLFlagToInt(char *flag) { + if (!flag) + return RPMSENSE_ANY; + else if (!strcmp(flag, "EQ")) + return RPMSENSE_EQUAL; + else if (!strcmp(flag, "LT")) + return RPMSENSE_LESS; + else if (!strcmp(flag, "LE")) + return RPMSENSE_EQUAL | RPMSENSE_LESS; + else if (!strcmp(flag, "GT")) + return RPMSENSE_GREATER; + else if (!strcmp(flag, "GE")) + return RPMSENSE_EQUAL | RPMSENSE_GREATER; + return RPMSENSE_ANY; +} + +void getXMLPackageFiles(xmlNode *parent, uint **type, char ***path, int *count) { + + *count = xmlChildElementCount(parent) - 1; // first child node is "version" + if (*count == 0) { + *type = NULL; + *path = NULL; + return; + } + *type = malloc(sizeof(int*) * (*count)); + *path = malloc(sizeof(char*) * (*count)+1); + + int i = 0; + for (xmlNode *entry=parent->children; entry; entry=entry->next) { + if (entry->type == XML_ELEMENT_NODE && !strcmp((char*)entry->name, "file")) { + (*path)[i] = strdup((char*)entry->children->content); + char* ftype = (char*)findXMLAttributeByName(entry, "type"); + if (!ftype) + (*type)[i] = 0; + else if (!strcmp(ftype, "dir")) + (*type)[i] = 1; + else if (!strcmp(ftype, "ghost")) + (*type)[i] = 2; + i++; + } + } + // Null terminated list + (*path)[i] = NULL; +} + +void getXMLPackageNFV(xmlNode *parent, char ***name, + uint_32 **flags, char ***version, int *count) { + + *count = xmlChildElementCount(parent); + if (*count == 0) { + *name = NULL; + *flags = NULL; + *version = NULL; + return; + } + *name = malloc(sizeof(char*) * *count); + *flags = malloc(sizeof(uint_32) * *count); + *version = malloc(sizeof(char*) * *count); + + int i = 0; + for (xmlNode *entry=parent->children; entry; entry=entry->next) { + if (entry->type == XML_ELEMENT_NODE) { + if (i >= *count) { + logmsg(LOG_ERROR,"getXMLPackageNFV: count (%d) is less than found XML elements; skipping.", + *count); + return; + } + (*name)[i] = strdup((char*)findXMLAttributeByName(entry, "name")); + char *ver = (char*)findXMLAttributeByName(entry, "version"); + if (ver) { + (*version)[i] = strdup(ver); + free(ver); + } else + (*version)[i] = strdup(""); + (*flags)[i] = XMLFlagToInt( + (char*)findXMLAttributeByName(entry, "flags")); + i++; + } + } +} + static long sourceid = 0; struct headerSourceList *currheadersourcelist = NULL; @@ -914,9 +994,7 @@ void addNewToSourceHeaderList(struct headerSourceList *newheadersourcelist, } -int -addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) -{ +int addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) { char *scanpath; struct repoData* repodata = NULL; struct headerSourceList *newheadersourcelist; @@ -955,11 +1033,11 @@ addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) // 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")) { + //print_element_names(package_node->children, 0); newheadersourcelist = malloc(sizeof(struct headerSourceList)); if (newheadersourcelist == NULL) return 1; @@ -1008,7 +1086,6 @@ addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) 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) @@ -1022,12 +1099,30 @@ addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) (char*)findXMLAttributeByName(psize, "package")); //hl->patch = headerGetStringArrayEntry(h, RPMTAG_PATCH, &count); - // TODO - newheadersourcelist->requirecount = 0; + // XML requires + getXMLPackageNFV(findXMLPropertyByName(format, "requires"), + &requirename, &requireflags, &requireversion, &requirecount); + 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; + + // XML Files + xmlNode* filelistsNode = findXMLPackageByName(xmlDocGetRootElement( + repodata->filelists_doc), newheadersourcelist->name); + + getXMLPackageFiles(filelistsNode, &fileflags, &basenames, &filenamescount); + newheadersourcelist->source = basenames; newheadersourcelist->filenamecount = 0; addNewToSourceHeaderList(newheadersourcelist, ct, altrepository); - + // TODO: changelog } } cleanRepodata(repodata); @@ -1408,9 +1503,64 @@ char* advanceXMLPackageNode(char* prevname, xmlNode **package_node) { altidx, arch); if (ret == 0) { - newheaderlist->providecount = 0; - newheaderlist->requirecount = 0; - // TODO + getXMLPackageNFV(findXMLPropertyByName(format, "obsoletes"), + &obsoletename, &obsoleteflags, &obsoleteversion, &obsoletecount); + getXMLPackageNFV(findXMLPropertyByName(format, "provides"), + &providename, &provideflags, &provideversion, &providecount); + getXMLPackageNFV(findXMLPropertyByName(format, "requires"), + &requirename, &requireflags, &requireversion, &requirecount); + + 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; } } else {