diff --git a/build/checkFiles.c b/build/checkFiles.c index 29b6a2d..5f99a43 100644 --- a/build/checkFiles.c +++ b/build/checkFiles.c @@ -5,6 +5,63 @@ #include "checkFiles.h" +void fiIntersect(TFI_t fi1, TFI_t fi2, void (*cb)(char *f, int i1, int i2)) +{ + if (fi1 == NULL) return; + if (fi2 == NULL) return; + int i1 = 0, i2 = 0; + while (i1 < fi1->fc && i2 < fi2->fc) { + char f1[PATH_MAX], f2[PATH_MAX]; + strcpy(f1, fi1->dnl[fi1->dil[i1]] + fi1->astriplen); + strcpy(f2, fi2->dnl[fi2->dil[i2]] + fi2->astriplen); + strcat(f1, fi1->bnl[i1]); + strcat(f2, fi2->bnl[i2]); + int cmp = strcmp(f1, f2); + if (cmp < 0) { + i1++; + continue; + } + if (cmp > 0) { + i2++; + continue; + } + cb(f1, i1, i2); + i1++; + i2++; + } +} + +static +void checkPkgIntersect(Package pkg1, Package pkg2) +{ + TFI_t fi1 = pkg1->cpioList; + TFI_t fi2 = pkg2->cpioList; + if (fi1 == NULL) return; + if (fi2 == NULL) return; + int once = 0; + void cb(char *f, int i1, int i2) + { + if (S_ISDIR(fi1->fmodes[i1]) && S_ISDIR(fi2->fmodes[i2])) + return; + if (once++ == 0) + rpmlog(RPMLOG_WARNING, + "File(s) packaged into both %s-%s-%s and %s-%s-%s:\n", + fi1->name, fi1->version, fi1->release, + fi2->name, fi2->version, fi2->release); + rpmlog(RPMLOG_INFO, " %s\n", f); + } + fiIntersect(fi1, fi2, cb); +} + +static +void checkIntersect(Spec spec) +{ + Package pkg1, pkg2; + for (pkg1 = spec->packages; pkg1; pkg1 = pkg1->next) + for (pkg2 = pkg1->next; pkg2; pkg2 = pkg2->next) + checkPkgIntersect(pkg1, pkg2); +} + static int fiSearch(TFI_t fi, const char *path) { @@ -96,6 +153,7 @@ int checkUnpackaged(Spec spec) int checkFiles(Spec spec) { + checkIntersect(spec); int rc = checkUnpackaged(spec); if (rc && rpmExpandNumeric("%{?_unpackaged_files_terminate_build}")) { rpmlog(RPMLOG_ERR, "File list check failed, terminating build\n"); diff --git a/build/checkFiles.h b/build/checkFiles.h index 5ee8e7b..1b7e40d 100644 --- a/build/checkFiles.h +++ b/build/checkFiles.h @@ -4,4 +4,7 @@ /* Perform filst list check. */ int checkFiles(Spec spec); +/* Helper function: process files with the same name. */ +void fiIntersect(TFI_t fi1, TFI_t fi2, void (*cb)(char *f, int i1, int i2)); + #endif diff --git a/build/files.c b/build/files.c index db54e48..bc6e334 100644 --- a/build/files.c +++ b/build/files.c @@ -2898,115 +2898,6 @@ static void printDeps(Header h) versions = hfd(versions, dvt); } -/* Written by Alexey Tourbin! */ -typedef struct MyFileList { - const char **bn, **dn; - int_32 *di; - int_16 *md; - int_32 bnt, dnt, dit, mdt; - int_32 bnc, dnc, dic, mdc; -} MyFileList; - -static -int fillMyFileList(MyFileList *l, Header h) -{ - if (!headerGetEntry(h, RPMTAG_BASENAMES, &l->bnt, (void**)&l->bn, &l->bnc)) - return 1; - if (!headerGetEntry(h, RPMTAG_DIRNAMES, &l->dnt, (void**)&l->dn, &l->dnc)) { - headerFreeData(l->bn, l->bnt); - return 1; - } - if (!headerGetEntry(h, RPMTAG_DIRINDEXES, &l->dit, (void**)&l->di, &l->dic)) { - headerFreeData(l->bn, l->bnt); - headerFreeData(l->dn, l->dnt); - return 1; - } - if (!headerGetEntry(h, RPMTAG_FILEMODES, &l->mdt, (void**)&l->md, &l->mdc)) { - headerFreeData(l->bn, l->bnt); - headerFreeData(l->dn, l->dnt); - headerFreeData(l->di, l->dit); - return 1; - } - assert(l->bnc == l->dic); - assert(l->bnc == l->mdc); - return 0; -} - -static -void freeMyFileList(MyFileList *l) -{ - headerFreeData(l->bn, l->bnt); - headerFreeData(l->dn, l->dnt); - headerFreeData(l->di, l->dit); - headerFreeData(l->md, l->mdt); -} - -static -void checkHdrIntersect(Header h1, Header h2) -{ - MyFileList l1 = {0}, l2 = {0}; - if (fillMyFileList(&l1, h1) != 0) - return; - if (fillMyFileList(&l2, h2) != 0) { - freeMyFileList(&l1); - return; - } - char f1[PATH_MAX], f2[PATH_MAX]; - int i1 = 0, i2 = 0; - if (i1 < l1.bnc) { - strcpy(f1, l1.dn[l1.di[i1]]); - strcat(f1, l1.bn[i1]); - } - if (i2 < l2.bnc) { - strcpy(f2, l2.dn[l2.di[i2]]); - strcat(f2, l2.bn[i2]); - } - const char *N1 = NULL, *N2 = NULL; - while (i1 < l1.bnc && i2 < l2.bnc) { - int cmp = strcmp(f1, f2); - if (cmp < 0) { - if (++i1 < l1.bnc) { - strcpy(f1, l1.dn[l1.di[i1]]); - strcat(f1, l1.bn[i1]); - } - } - else if (cmp > 0) { - if (++i2 < l2.bnc) { - strcpy(f2, l2.dn[l2.di[i2]]); - strcat(f2, l2.bn[i2]); - } - } - else { - if (!(S_ISDIR(l1.md[i1]) && S_ISDIR(l2.md[i2]))) { - if (!N1) headerNVR(h1, &N1, NULL, NULL); - if (!N2) headerNVR(h2, &N2, NULL, NULL); - rpmMessage(RPMMESS_WARNING, - _("file %s is packaged into both %s and %s\n"), - f1, N1, N2); - } - if (++i1 < l1.bnc) { - strcpy(f1, l1.dn[l1.di[i1]]); - strcat(f1, l1.bn[i1]); - } - if (++i2 < l2.bnc) { - strcpy(f2, l2.dn[l2.di[i2]]); - strcat(f2, l2.bn[i2]); - } - } - } - freeMyFileList(&l1); - freeMyFileList(&l2); -} - -static -void checkSpecIntersect(Spec spec) -{ - Package pkg1, pkg2; - for (pkg1 = spec->packages; pkg1; pkg1 = pkg1->next) - for (pkg2 = pkg1->next; pkg2; pkg2 = pkg2->next) - checkHdrIntersect(pkg1->header, pkg2->header); -} - #include "checkFiles.h" int processBinaryFiles(Spec spec, int installSpecialDoc, int test) @@ -3039,10 +2930,8 @@ int processBinaryFiles(Spec spec, int installSpecialDoc, int test) * and duplicated files. */ - if (rc == 0) { + if (rc == 0) rc = checkFiles(spec); - checkSpecIntersect(spec); - } return rc; }