build/files.c (addFile): replaced myftw() with fts(3)
This commit is contained in:
parent
d3842e8715
commit
161864908a
@ -320,8 +320,6 @@ INPUT = \
|
|||||||
@top_srcdir@/build/expression.c \
|
@top_srcdir@/build/expression.c \
|
||||||
@top_srcdir@/build/files.c \
|
@top_srcdir@/build/files.c \
|
||||||
@top_srcdir@/build/misc.c \
|
@top_srcdir@/build/misc.c \
|
||||||
@top_srcdir@/build/myftw.c \
|
|
||||||
@top_srcdir@/build/myftw.h \
|
|
||||||
@top_srcdir@/build/names.c \
|
@top_srcdir@/build/names.c \
|
||||||
@top_srcdir@/build/pack.c \
|
@top_srcdir@/build/pack.c \
|
||||||
@top_srcdir@/build/parseBuildInstallClean.c \
|
@top_srcdir@/build/parseBuildInstallClean.c \
|
||||||
|
@ -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 myftw.h
|
noinst_HEADERS = buildio.h
|
||||||
|
|
||||||
lib_LTLIBRARIES = librpmbuild.la
|
lib_LTLIBRARIES = librpmbuild.la
|
||||||
librpmbuild_la_SOURCES = \
|
librpmbuild_la_SOURCES = \
|
||||||
build.c expression.c files.c misc.c myftw.c names.c pack.c \
|
build.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
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "buildio.h"
|
#include "buildio.h"
|
||||||
|
|
||||||
#include "myftw.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/*@access Header @*/
|
/*@access Header @*/
|
||||||
@ -103,7 +102,6 @@ typedef struct FileList_s {
|
|||||||
int devminor;
|
int devminor;
|
||||||
|
|
||||||
int isDir;
|
int isDir;
|
||||||
int inFtw;
|
|
||||||
int currentFlags;
|
int currentFlags;
|
||||||
specdFlags currentSpecdFlags;
|
specdFlags currentSpecdFlags;
|
||||||
int currentVerifyFlags;
|
int currentVerifyFlags;
|
||||||
@ -1460,6 +1458,9 @@ static int pathIsCanonical(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* forward ref */
|
||||||
|
static rpmRC recurseDir(FileList fl, const char * diskPath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a file to the package manifest.
|
* Add a file to the package manifest.
|
||||||
* @param fl package file tree walk data
|
* @param fl package file tree walk data
|
||||||
@ -1568,16 +1569,8 @@ static rpmRC addFile(FileList fl, const char * diskPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((! fl->isDir) && S_ISDIR(statp->st_mode)) {
|
if ((! fl->isDir) && S_ISDIR(statp->st_mode)) {
|
||||||
/* We use our own ftw() call, because ftw() uses stat() */
|
/* FIX: fl->buildRoot may be NULL */
|
||||||
/* instead of lstat(), which causes it to follow symlinks! */
|
return recurseDir(fl, diskPath);
|
||||||
/* It also has better callback support. */
|
|
||||||
|
|
||||||
fl->inFtw = 1; /* Flag to indicate file has buildRootURL prefixed */
|
|
||||||
fl->isDir = 1; /* Keep it from following myftw() again */
|
|
||||||
(void) myftw(diskPath, 16, (myftwFunc) addFile, fl);
|
|
||||||
fl->isDir = 0;
|
|
||||||
fl->inFtw = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileMode = statp->st_mode;
|
fileMode = statp->st_mode;
|
||||||
@ -1666,6 +1659,61 @@ static rpmRC addFile(FileList fl, const char * diskPath,
|
|||||||
return RPMRC_OK;
|
return RPMRC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <fts.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add directory (and all of its files) to the package manifest.
|
||||||
|
* @param fl package file tree walk data
|
||||||
|
* @param diskPath path to file
|
||||||
|
* @return RPMRC_OK on success
|
||||||
|
*/
|
||||||
|
static rpmRC recurseDir(FileList fl, const char * diskPath)
|
||||||
|
{
|
||||||
|
char * ftsSet[2];
|
||||||
|
FTS * ftsp;
|
||||||
|
FTSENT * fts;
|
||||||
|
int myFtsOpts = (FTS_COMFOLLOW | FTS_NOCHDIR | FTS_PHYSICAL);
|
||||||
|
rpmRC rc = RPMRC_FAIL;
|
||||||
|
|
||||||
|
fl->isDir = 1; /* Keep it from following myftw() again */
|
||||||
|
|
||||||
|
ftsSet[0] = (char *) diskPath;
|
||||||
|
ftsSet[1] = NULL;
|
||||||
|
ftsp = fts_open(ftsSet, myFtsOpts, NULL);
|
||||||
|
while ((fts = fts_read(ftsp)) != NULL) {
|
||||||
|
switch (fts->fts_info) {
|
||||||
|
case FTS_D: /* preorder directory */
|
||||||
|
case FTS_F: /* regular file */
|
||||||
|
case FTS_SL: /* symbolic link */
|
||||||
|
case FTS_SLNONE: /* symbolic link without target */
|
||||||
|
case FTS_DEFAULT: /* none of the above */
|
||||||
|
rc = addFile(fl, fts->fts_accpath, fts->fts_statp);
|
||||||
|
break;
|
||||||
|
case FTS_DOT: /* dot or dot-dot */
|
||||||
|
case FTS_DP: /* postorder directory */
|
||||||
|
rc = RPMRC_OK;
|
||||||
|
break;
|
||||||
|
case FTS_NS: /* stat(2) failed */
|
||||||
|
case FTS_DNR: /* unreadable directory */
|
||||||
|
case FTS_ERR: /* error; errno is set */
|
||||||
|
case FTS_DC: /* directory that causes cycles */
|
||||||
|
case FTS_NSOK: /* no stat(2) requested */
|
||||||
|
case FTS_INIT: /* initialized only */
|
||||||
|
case FTS_W: /* whiteout object */
|
||||||
|
default:
|
||||||
|
rc = RPMRC_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) fts_close(ftsp);
|
||||||
|
|
||||||
|
fl->isDir = 0;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a file to a binary package.
|
* Add a file to a binary package.
|
||||||
* @param pkg
|
* @param pkg
|
||||||
@ -1679,7 +1727,7 @@ static int processBinaryFile(/*@unused@*/ Package pkg, FileList fl,
|
|||||||
fileSystem@*/
|
fileSystem@*/
|
||||||
/*@modifies *fl, fl->processingFailed,
|
/*@modifies *fl, fl->processingFailed,
|
||||||
fl->fileList, fl->fileListRecsAlloced, fl->fileListRecsUsed,
|
fl->fileList, fl->fileListRecsAlloced, fl->fileListRecsUsed,
|
||||||
fl->totalFileSize, fl->fileCount, fl->inFtw, fl->isDir,
|
fl->totalFileSize, fl->fileCount, fl->isDir,
|
||||||
rpmGlobalMacroContext, fileSystem @*/
|
rpmGlobalMacroContext, fileSystem @*/
|
||||||
{
|
{
|
||||||
int doGlob;
|
int doGlob;
|
||||||
@ -1819,7 +1867,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
|||||||
fl.isSpecialDoc = 0;
|
fl.isSpecialDoc = 0;
|
||||||
|
|
||||||
fl.isDir = 0;
|
fl.isDir = 0;
|
||||||
fl.inFtw = 0;
|
|
||||||
fl.currentFlags = 0;
|
fl.currentFlags = 0;
|
||||||
fl.currentVerifyFlags = 0;
|
fl.currentVerifyFlags = 0;
|
||||||
|
|
||||||
@ -1873,7 +1920,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
|||||||
|
|
||||||
/* Reset for a new line in %files */
|
/* Reset for a new line in %files */
|
||||||
fl.isDir = 0;
|
fl.isDir = 0;
|
||||||
fl.inFtw = 0;
|
|
||||||
fl.currentFlags = 0;
|
fl.currentFlags = 0;
|
||||||
/* turn explicit flags into %def'd ones (gosh this is hacky...) */
|
/* turn explicit flags into %def'd ones (gosh this is hacky...) */
|
||||||
fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
|
fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
|
||||||
@ -1940,7 +1986,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
|||||||
|
|
||||||
/* Reset for %doc */
|
/* Reset for %doc */
|
||||||
fl.isDir = 0;
|
fl.isDir = 0;
|
||||||
fl.inFtw = 0;
|
|
||||||
fl.currentFlags = 0;
|
fl.currentFlags = 0;
|
||||||
fl.currentVerifyFlags = 0;
|
fl.currentVerifyFlags = 0;
|
||||||
|
|
||||||
|
247
build/myftw.c
247
build/myftw.c
@ -1,247 +0,0 @@
|
|||||||
/** \ingroup rpmbuild
|
|
||||||
* \file build/myftw.c
|
|
||||||
* Modified ftw() -- uses Lstat() instead of stat().
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
Contributed by Ian Lance Taylor (ian@airs.com).
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of the
|
|
||||||
License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library 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
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
|
||||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
|
||||||
Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
#include "rpmio.h"
|
|
||||||
|
|
||||||
#ifndef NAMLEN
|
|
||||||
#define NAMLEN(a) strlen((a)->d_name)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__LCLINT__)
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#ifdef _POSIX_VERSION
|
|
||||||
#define PATH_MAX _POSIX_PATH_MAX
|
|
||||||
#else
|
|
||||||
#ifdef MAXPATHLEN
|
|
||||||
#define PATH_MAX MAXPATHLEN
|
|
||||||
#else
|
|
||||||
#define PATH_MAX 1024
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif /* !__LCLINT */
|
|
||||||
|
|
||||||
#include "myftw.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
/* Traverse one level of a directory tree. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
/*@-nullstate@*/
|
|
||||||
static int
|
|
||||||
myftw_dir (DIR **dirs, int level, int descriptors,
|
|
||||||
char *dir, size_t len,
|
|
||||||
myftwFunc func,
|
|
||||||
void *fl)
|
|
||||||
/*@globals errno, fileSystem @*/
|
|
||||||
/*@modifies *dirs, *dir, errno, fileSystem @*/
|
|
||||||
{
|
|
||||||
int got;
|
|
||||||
struct dirent *entry;
|
|
||||||
int d_namlen;
|
|
||||||
|
|
||||||
got = 0;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
while ((entry = Readdir (dirs[level])) != NULL)
|
|
||||||
{
|
|
||||||
struct stat s;
|
|
||||||
int flag, retval, newlev = 0;
|
|
||||||
|
|
||||||
++got;
|
|
||||||
|
|
||||||
if (entry->d_name[0] == '.'
|
|
||||||
&& (entry->d_name [1] == '\0' ||
|
|
||||||
(entry->d_name [2] == '\0' && entry->d_name[1] == '.')))
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_namlen = NAMLEN(entry) + 1;
|
|
||||||
if (d_namlen + len > PATH_MAX)
|
|
||||||
{
|
|
||||||
#ifdef ENAMETOOLONG
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
#else
|
|
||||||
errno = ENOMEM;
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir[len] = '/';
|
|
||||||
memcpy ((void *) (dir + len + 1), (void *) entry->d_name, d_namlen);
|
|
||||||
|
|
||||||
if (Lstat (dir, &s) < 0)
|
|
||||||
{
|
|
||||||
/* Following POSIX.1 2.4 ENOENT is returned if the file cannot
|
|
||||||
* be stat'ed. This can happen for a file returned by Readdir
|
|
||||||
* if it's an unresolved symbolic link. This should be regarded
|
|
||||||
* as an forgivable error. -- Uli. */
|
|
||||||
if (errno != EACCES && errno != ENOENT)
|
|
||||||
return -1;
|
|
||||||
flag = MYFTW_NS;
|
|
||||||
}
|
|
||||||
else if (S_ISDIR (s.st_mode))
|
|
||||||
{
|
|
||||||
newlev = (level + 1) % descriptors;
|
|
||||||
|
|
||||||
/*@-unqualifiedtrans@*/
|
|
||||||
if (dirs[newlev] != NULL)
|
|
||||||
(void) Closedir (dirs[newlev]);
|
|
||||||
/*@=unqualifiedtrans@*/
|
|
||||||
|
|
||||||
dirs[newlev] = Opendir (dir);
|
|
||||||
if (dirs[newlev] != NULL)
|
|
||||||
flag = MYFTW_D;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (errno != EACCES)
|
|
||||||
return -1;
|
|
||||||
flag = MYFTW_DNR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
flag = MYFTW_F;
|
|
||||||
|
|
||||||
retval = (*func) (fl, dir, &s);
|
|
||||||
|
|
||||||
if (flag == MYFTW_D)
|
|
||||||
{
|
|
||||||
if (retval == 0)
|
|
||||||
retval = myftw_dir (dirs, newlev, descriptors, dir,
|
|
||||||
d_namlen + len, func, fl);
|
|
||||||
if (dirs[newlev] != NULL)
|
|
||||||
{
|
|
||||||
int save;
|
|
||||||
|
|
||||||
save = errno;
|
|
||||||
(void) Closedir (dirs[newlev]);
|
|
||||||
errno = save;
|
|
||||||
dirs[newlev] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval != 0)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
if (dirs[level] == NULL)
|
|
||||||
{
|
|
||||||
int skip;
|
|
||||||
|
|
||||||
dir[len] = '\0';
|
|
||||||
dirs[level] = Opendir (dir);
|
|
||||||
if (dirs[level] == NULL)
|
|
||||||
return -1;
|
|
||||||
skip = got;
|
|
||||||
while (skip-- != 0)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
if (Readdir (dirs[level]) == NULL)
|
|
||||||
return errno == 0 ? 0 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errno == 0 ? 0 : -1;
|
|
||||||
}
|
|
||||||
/*@=nullstate@*/
|
|
||||||
|
|
||||||
/* Call a function on every element in a directory tree. */
|
|
||||||
|
|
||||||
int myftw (const char *dir,
|
|
||||||
int descriptors,
|
|
||||||
myftwFunc func,
|
|
||||||
void *fl)
|
|
||||||
{
|
|
||||||
DIR **dirs;
|
|
||||||
size_t len;
|
|
||||||
char buf[PATH_MAX + 1];
|
|
||||||
struct stat s;
|
|
||||||
int flag, retval;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (descriptors <= 0)
|
|
||||||
descriptors = 1;
|
|
||||||
|
|
||||||
/*@access DIR@*/
|
|
||||||
dirs = (DIR **) alloca (descriptors * sizeof (*dirs));
|
|
||||||
i = descriptors;
|
|
||||||
while (i-- > 0)
|
|
||||||
dirs[i] = NULL;
|
|
||||||
|
|
||||||
if (Lstat (dir, &s) < 0)
|
|
||||||
{
|
|
||||||
/* Following POSIX.1 2.4 ENOENT is returned if the file cannot
|
|
||||||
* be stat'ed. This can happen for a file returned by Readdir
|
|
||||||
* if it's an unresolved symbolic link. This should be regarded
|
|
||||||
* as an forgivable error. -- Uli. */
|
|
||||||
if (errno != EACCES && errno != ENOENT)
|
|
||||||
return -1;
|
|
||||||
flag = MYFTW_NS;
|
|
||||||
}
|
|
||||||
else if (S_ISDIR (s.st_mode))
|
|
||||||
{
|
|
||||||
dirs[0] = Opendir (dir);
|
|
||||||
if (dirs[0] != NULL)
|
|
||||||
flag = MYFTW_D;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (errno != EACCES)
|
|
||||||
return -1;
|
|
||||||
flag = MYFTW_DNR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
flag = MYFTW_F;
|
|
||||||
|
|
||||||
len = strlen (dir);
|
|
||||||
memcpy ((void *) buf, (void *) dir, len + 1);
|
|
||||||
|
|
||||||
retval = (*func) (fl, buf, &s);
|
|
||||||
|
|
||||||
if (flag == MYFTW_D)
|
|
||||||
{
|
|
||||||
if (retval == 0)
|
|
||||||
retval = myftw_dir (dirs, 0, descriptors, buf, len, func, fl);
|
|
||||||
if (dirs[0] != NULL)
|
|
||||||
{
|
|
||||||
int save;
|
|
||||||
|
|
||||||
save = errno;
|
|
||||||
(void) Closedir (dirs[0]);
|
|
||||||
/*@-mods@*/
|
|
||||||
errno = save;
|
|
||||||
/*@=mods@*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
#ifndef _H_MYFTW_
|
|
||||||
#define _H_MYFTW_
|
|
||||||
|
|
||||||
/** \ingroup rpmbuild
|
|
||||||
* \file build/myftw.h
|
|
||||||
* Portable ftw(3) using lstat() instead of stat().
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
/* The FLAG argument to the user function passed to ftw. */
|
|
||||||
#define MYFTW_F 0 /* Regular file. */
|
|
||||||
#define MYFTW_D 1 /* Directory. */
|
|
||||||
#define MYFTW_DNR 2 /* Unreadable directory. */
|
|
||||||
#define MYFTW_NS 3 /* Unstatable file. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int (*myftwFunc) (void *fl, const char *name, struct stat *statp)
|
|
||||||
/*@*/;
|
|
||||||
|
|
||||||
int myftw (const char *dir, int descriptors, myftwFunc func, void *fl)
|
|
||||||
/*@globals fileSystem @*/
|
|
||||||
/*@modifies *fl, fileSystem @*/;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _H_MYFTW_ */
|
|
@ -9,7 +9,6 @@ build/build.c
|
|||||||
build/expression.c
|
build/expression.c
|
||||||
build/files.c
|
build/files.c
|
||||||
build/misc.c
|
build/misc.c
|
||||||
build/myftw.c
|
|
||||||
build/names.c
|
build/names.c
|
||||||
build/pack.c
|
build/pack.c
|
||||||
build/parseBuildInstallClean.c
|
build/parseBuildInstallClean.c
|
||||||
|
Loading…
Reference in New Issue
Block a user