build/checkFiles.c: reimplemented checkFiles() using fts(3)

This commit is contained in:
Alexey Tourbin 2011-01-15 10:58:41 +03:00
parent 6528547c06
commit d3c57d3ee4
10 changed files with 121 additions and 203 deletions

1
.gitignore vendored
View File

@ -66,7 +66,6 @@ Makefile.in
/scripts/brp-strip /scripts/brp-strip
/scripts/brp-verify-info /scripts/brp-verify-info
/scripts/brp-verify_elf /scripts/brp-verify_elf
/scripts/check-files
/scripts/compress_files /scripts/compress_files
/scripts/files.req.files /scripts/files.req.files
/scripts/find-lang /scripts/find-lang

View File

@ -12,11 +12,11 @@ LIBS =
pkgincdir = $(pkgincludedir) pkgincdir = $(pkgincludedir)
pkginc_HEADERS = rpmbuild.h rpmspec.h pkginc_HEADERS = rpmbuild.h rpmspec.h
noinst_HEADERS = buildio.h noinst_HEADERS = buildio.h checkFiles.h
lib_LTLIBRARIES = librpmbuild.la lib_LTLIBRARIES = librpmbuild.la
librpmbuild_la_SOURCES = \ librpmbuild_la_SOURCES = \
build.c expression.c files.c misc.c names.c pack.c \ build.c checkFiles.c expression.c files.c misc.c names.c pack.c \
parseBuildInstallClean.c parseChangelog.c parseDescription.c \ parseBuildInstallClean.c parseChangelog.c parseDescription.c \
parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \ parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \
parseSpec.c poptBT.c reqprov.c spec.c parseSpec.c poptBT.c reqprov.c spec.c

107
build/checkFiles.c Normal file
View File

@ -0,0 +1,107 @@
#include "system.h"
#include "rpmio_internal.h"
#include "rpmbuild.h"
#include "psm.h"
#include "checkFiles.h"
static
int fiSearch(TFI_t fi, const char *path)
{
if (fi == NULL || fi->fc == 0)
return -1;
int l = 0;
int u = fi->fc;
while (l < u) {
int i = (l + u) / 2;
const char *d = fi->dnl[fi->dil[i]];
int dlen = strlen(d);
int cmp = strncmp(path, d, dlen);
if (cmp == 0) {
const char *b = fi->bnl[i];
cmp = strcmp(path + dlen, b);
}
if (cmp < 0)
u = i;
else if (cmp > 0)
l = i + 1;
else
return i;
}
return -1;
}
#include <fts.h>
static
int checkUnpackaged(Spec spec)
{
int rc = 0;
int uc = 0;
char **uv = NULL;
void check(const char *path)
{
Package pkg;
for (pkg = spec->packages; pkg; pkg = pkg->next)
if (fiSearch(pkg->cpioList, path) >= 0)
return;
AUTO_REALLOC(uv, uc, 8);
uv[uc++] = xstrdup(path + strlen(spec->buildRootURL));
rc |= 1;
}
char *paths[] = { (char *) spec->buildRootURL, 0 };
int options = FTS_COMFOLLOW | FTS_PHYSICAL;
FTS *ftsp = fts_open(paths, options, NULL);
FTSENT *fts;
while ((fts = fts_read(ftsp)) != NULL) {
// skip dotfiles in buildroot
if (fts->fts_level == 1 && *fts->fts_name == '.') {
if (fts->fts_info == FTS_D)
fts_set(ftsp, fts, FTS_SKIP);
continue;
}
switch (fts->fts_info) {
// do not check for unpackaged directories
case FTS_D:
case FTS_DP:
break;
case FTS_F:
case FTS_SL:
case FTS_SLNONE:
case FTS_DEFAULT:
check(fts->fts_path);
break;
default:
rpmlog(RPMLOG_WARNING, "%s: fts error\n", fts->fts_path);
rc |= 2;
break;
}
}
int cmp(const void *sptr1, const void *sptr2)
{
const char *s1 = *(const char **) sptr1;
const char *s2 = *(const char **) sptr2;
return strcmp(s1, s2);
}
if (uv) {
rpmlog(RPMLOG_WARNING, "Installed (but unpackaged) file(s) found:\n");
qsort(uv, uc, sizeof(*uv), cmp);
int i;
for (i = 0; i < uc; i++)
rpmlog(RPMLOG_INFO, " %s\n", uv[i]);
free(uv);
}
return rc;
}
int checkFiles(Spec spec)
{
int rc = checkUnpackaged(spec);
if (rc && rpmExpandNumeric("%{?_unpackaged_files_terminate_build}")) {
rpmlog(RPMLOG_ERR, "File list check failed, terminating build\n");
return rc;
}
return 0;
}
// ex: set ts=8 sts=4 sw=4 noet:

7
build/checkFiles.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef CHECKFILES_H
#define CHECKFILES_H
/* Perform filst list check. */
int checkFiles(Spec spec);
#endif

View File

@ -79,10 +79,6 @@ typedef struct AttrRec_s {
mode_t ar_dmode; mode_t ar_dmode;
} * AttrRec; } * AttrRec;
/* List of files */
static StringBuf check_fileList = NULL;
static int check_fileListLen = 0;
/** /**
* Package file tree walk data. * Package file tree walk data.
*/ */
@ -1597,13 +1593,6 @@ static rpmRC addFile1(FileList fl, const char * diskPath, struct stat * statp)
if (fileGname == NULL) if (fileGname == NULL)
fileGname = getGname(getgid()); fileGname = getGname(getgid());
/* This check must be consistent with check-files script. */
if (S_ISREG(fileMode) || S_ISLNK(fileMode)) {
appendStringBuf(check_fileList, diskPath);
appendStringBuf(check_fileList, "\n");
check_fileListLen += strlen(diskPath) + 1;
}
/* Add to the file list */ /* Add to the file list */
if (fl->fileListRecsUsed == fl->fileListRecsAlloced) { if (fl->fileListRecsUsed == fl->fileListRecsAlloced) {
fl->fileListRecsAlloced += 128; fl->fileListRecsAlloced += 128;
@ -2909,132 +2898,6 @@ static void printDeps(Header h)
versions = hfd(versions, dvt); versions = hfd(versions, dvt);
} }
/**
* Check packaged file list against what's in the build root.
* @param fileList packaged file list
* @param fileListLen no. of packaged files
* @return -1 if skipped, 0 on OK, 1 on error
*/
static int checkFiles(Spec spec, StringBuf fileList, int fileListLen)
{
StringBuf readBuf = NULL;
const char *rootURL = spec->rootURL;
const char *runDirURL = NULL;
const char *runTemplate = NULL;
const char *runPost = NULL;
const char *scriptName = NULL;
const char *runCmd = NULL;
const char *rootDir;
const char *runScript;
const char *mTemplate = "%{?__spec_autodep_template}";
const char *mPost = "%{?__spec_autodep_post}";
urlinfo u = NULL;
FD_t fd, xfd;
FILE *fp = 0;
const char ** av = 0;
int ac = 0;
int rc = 0;
if (fileListLen == 0)
return 0;
runDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
(void) urlPath(rootURL, &rootDir);
if ( !*rootDir )
rootDir = "/";
if (runDirURL && runDirURL[0] != '/' && urlSplit(runDirURL, &u) ) {
rc = RPMERR_SCRIPT;
goto exit;
}
runCmd = rpmExpand("%{?__check_files}", NULL);
if (!(runCmd && *runCmd)) {
rc = -1;
goto exit;
}
rpmMessage(RPMMESS_NORMAL, _("Finding %s (using %s)\n"), _("unpackaged files"), runCmd);
if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
rc = RPMERR_SCRIPT;
rpmError(RPMERR_SCRIPT, _("Unable to open temp file."));
goto exit;
}
if ( !fdGetFp(fd) )
xfd = Fdopen(fd, "w.fpio");
else
xfd = fd;
if ( !(fp = fdGetFp(xfd)) ) {
rc = RPMERR_SCRIPT;
goto exit;
}
urlPath(scriptName, &runScript);
runTemplate = rpmExpand(mTemplate, NULL);
fputs(runTemplate, fp);
runTemplate = _free(runTemplate);
fputc('\n', fp);
fputs(runCmd, fp);
runCmd = _free(runCmd);
fputc('\n', fp);
runPost = rpmExpand(mPost, NULL);
fputs(runPost, fp);
runPost = _free(runPost);
fputc('\n', fp);
Fclose(xfd);
runCmd = rpmExpand("%{?___build_cmd}", " ", runScript, NULL);
if (!((rc = poptParseArgvString(runCmd, &ac, (const char ***)&av)) == 0
&& ac > 0 && av != NULL))
{
rc = RPMERR_SCRIPT;
goto exit;
}
rpmMessage(RPMMESS_NORMAL, _("Executing(%s): %s\n"), _("check-files"), runCmd);
readBuf = getOutputFrom(NULL, av, 0, getStringBuf(fileList), fileListLen, 1);
if (!readBuf) {
rc = RPMERR_EXEC;
rpmError(rc, _("Failed to check for unpackaged files\n"));
goto exit;
} else {
static int _unpackaged_files_terminate_build = 0;
static int oneshot = 0;
char *buf;
if (!oneshot) {
_unpackaged_files_terminate_build =
rpmExpandNumeric("%{?_unpackaged_files_terminate_build}");
oneshot = 1;
}
buf = getStringBuf(readBuf);
if (*buf && (*buf != '\n')) {
rc = (_unpackaged_files_terminate_build) ? 1 : 0;
rpmMessage((rc ? RPMMESS_ERROR : RPMMESS_WARNING),
_("Installed (but unpackaged) file(s) found:\n%s"), buf);
}
}
exit:
if (scriptName) Unlink(scriptName);
freeStringBuf(readBuf);
av = _free(av);
runCmd = _free(runCmd);
scriptName = _free(scriptName);
runDirURL = _free(runDirURL);
return rc;
}
/* Written by Alexey Tourbin! */ /* Written by Alexey Tourbin! */
typedef struct MyFileList { typedef struct MyFileList {
const char **bn, **dn; const char **bn, **dn;
@ -3144,14 +3007,13 @@ void checkSpecIntersect(Spec spec)
checkHdrIntersect(pkg1->header, pkg2->header); checkHdrIntersect(pkg1->header, pkg2->header);
} }
#include "checkFiles.h"
int processBinaryFiles(Spec spec, int installSpecialDoc, int test) int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
{ {
Package pkg; Package pkg;
int rc = 0; int rc = 0;
check_fileList = newStringBuf();
check_fileListLen = 0;
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
const char *n, *v, *r; const char *n, *v, *r;
@ -3178,13 +3040,9 @@ int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
*/ */
if (rc == 0) { if (rc == 0) {
if (checkFiles(spec, check_fileList, check_fileListLen) > 0) rc = checkFiles(spec);
rc = 1;
checkSpecIntersect(spec); checkSpecIntersect(spec);
} }
check_fileListLen = 0;
freeStringBuf(check_fileList);
return rc; return rc;
} }

View File

@ -932,7 +932,6 @@ AC_OUTPUT([ Doxyfile Makefile rpmrc macros platform rpmpopt
scripts/brp-strip scripts/brp-strip
scripts/brp-verify_elf scripts/brp-verify_elf
scripts/brp-verify-info scripts/brp-verify-info
scripts/check-files
scripts/compress_files scripts/compress_files
scripts/files.req scripts/files.req
scripts/files.req.files scripts/files.req.files

View File

@ -279,11 +279,6 @@
# #
#%vendor #%vendor
# Script gets packaged file list on input and buildroot in $RPM_BUILD_ROOT variable.
# Returns list of unpackaged files, i.e. files in $RPM_BUILD_ROOT not packaged.
#
%__check_files @RPMCONFIGDIR@/check-files
# Should unpackaged files in a buildroot terminate a build? # Should unpackaged files in a buildroot terminate a build?
# #
# Note: The default value should be 0 for legacy compatibility. # Note: The default value should be 0 for legacy compatibility.

View File

@ -446,7 +446,6 @@ fi
%rpmattr %_rpmlibdir/relative %rpmattr %_rpmlibdir/relative
%rpmattr %_rpmlibdir/brp-* %rpmattr %_rpmlibdir/brp-*
%rpmattr %_rpmlibdir/*_files %rpmattr %_rpmlibdir/*_files
%rpmattr %_rpmlibdir/check-files
%rpmattr %_rpmlibdir/ldd %rpmattr %_rpmlibdir/ldd
%rpmattr %_rpmlibdir/rpm2cpio.sh %rpmattr %_rpmlibdir/rpm2cpio.sh
%rpmattr %_rpmlibdir/find-lang %rpmattr %_rpmlibdir/find-lang

View File

@ -9,7 +9,7 @@ EXTRA_DIST = \
brp-adjust_libraries brp-alt brp-bytecompile_python \ brp-adjust_libraries brp-alt brp-bytecompile_python \
brp-cleanup brp-compress brp-fix-perms brp-fixup brp-strip \ brp-cleanup brp-compress brp-fix-perms brp-fixup brp-strip \
brp-verify_elf brp-verify-info \ brp-verify_elf brp-verify-info \
compress_files check-files \ compress_files \
find-lang \ find-lang \
fixup-binconfig fixup-pkgconfig fixup-libtool fixup-libraries \ fixup-binconfig fixup-pkgconfig fixup-libtool fixup-libraries \
files.req files.req.files 0common-files.req.list \ files.req files.req.files 0common-files.req.list \
@ -38,7 +38,7 @@ config_SCRIPTS = \
brp-adjust_libraries brp-alt brp-bytecompile_python \ brp-adjust_libraries brp-alt brp-bytecompile_python \
brp-cleanup brp-compress brp-fix-perms brp-fixup brp-strip \ brp-cleanup brp-compress brp-fix-perms brp-fixup brp-strip \
brp-verify_elf brp-verify-info \ brp-verify_elf brp-verify-info \
compress_files check-files \ compress_files \
find-lang \ find-lang \
fixup-binconfig fixup-pkgconfig fixup-libtool fixup-libraries \ fixup-binconfig fixup-pkgconfig fixup-libtool fixup-libraries \
files.req files.req.files \ files.req files.req.files \

View File

@ -1,46 +0,0 @@
#!/bin/sh -e
#
# Check for unpackaged files.
#
# Copyright (C) 2003 Dmitry V. Levin <ldv@altlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
. @RPMCONFIGDIR@/functions
ValidateBuildRoot
cd "$RPM_BUILD_ROOT"
WORKDIR=
exit_handler()
{
local rc=$?
trap - EXIT
[ -z "$WORKDIR" ] || rm -rf -- "$WORKDIR"
exit $rc
}
trap exit_handler SIGHUP SIGINT SIGQUIT SIGTERM EXIT
WORKDIR="$(mktemp -dt "$PROG.XXXXXXXXXX")"
export LC_ALL=C
sort >"$WORKDIR/packaged"
find "$RPM_BUILD_ROOT" -not -wholename "$RPM_BUILD_ROOT/.*" \( -type f -o -type l \) |
sort >"$WORKDIR/disk"
join -v1 "$WORKDIR/disk" "$WORKDIR/packaged" |sed -e "s#^$RPM_BUILD_ROOT# #g"