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/files.c \
|
||||
@top_srcdir@/build/misc.c \
|
||||
@top_srcdir@/build/myftw.c \
|
||||
@top_srcdir@/build/myftw.h \
|
||||
@top_srcdir@/build/names.c \
|
||||
@top_srcdir@/build/pack.c \
|
||||
@top_srcdir@/build/parseBuildInstallClean.c \
|
||||
|
@ -12,11 +12,11 @@ LIBS =
|
||||
|
||||
pkgincdir = $(pkgincludedir)
|
||||
pkginc_HEADERS = rpmbuild.h rpmspec.h
|
||||
noinst_HEADERS = buildio.h myftw.h
|
||||
noinst_HEADERS = buildio.h
|
||||
|
||||
lib_LTLIBRARIES = librpmbuild.la
|
||||
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 \
|
||||
parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \
|
||||
parseSpec.c poptBT.c reqprov.c spec.c
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "buildio.h"
|
||||
|
||||
#include "myftw.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*@access Header @*/
|
||||
@ -103,7 +102,6 @@ typedef struct FileList_s {
|
||||
int devminor;
|
||||
|
||||
int isDir;
|
||||
int inFtw;
|
||||
int currentFlags;
|
||||
specdFlags currentSpecdFlags;
|
||||
int currentVerifyFlags;
|
||||
@ -1460,6 +1458,9 @@ static int pathIsCanonical(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* forward ref */
|
||||
static rpmRC recurseDir(FileList fl, const char * diskPath);
|
||||
|
||||
/**
|
||||
* Add a file to the package manifest.
|
||||
* @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)) {
|
||||
/* We use our own ftw() call, because ftw() uses stat() */
|
||||
/* instead of lstat(), which causes it to follow symlinks! */
|
||||
/* 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;
|
||||
/* FIX: fl->buildRoot may be NULL */
|
||||
return recurseDir(fl, diskPath);
|
||||
}
|
||||
|
||||
fileMode = statp->st_mode;
|
||||
@ -1666,6 +1659,61 @@ static rpmRC addFile(FileList fl, const char * diskPath,
|
||||
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.
|
||||
* @param pkg
|
||||
@ -1679,7 +1727,7 @@ static int processBinaryFile(/*@unused@*/ Package pkg, FileList fl,
|
||||
fileSystem@*/
|
||||
/*@modifies *fl, fl->processingFailed,
|
||||
fl->fileList, fl->fileListRecsAlloced, fl->fileListRecsUsed,
|
||||
fl->totalFileSize, fl->fileCount, fl->inFtw, fl->isDir,
|
||||
fl->totalFileSize, fl->fileCount, fl->isDir,
|
||||
rpmGlobalMacroContext, fileSystem @*/
|
||||
{
|
||||
int doGlob;
|
||||
@ -1819,7 +1867,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
||||
fl.isSpecialDoc = 0;
|
||||
|
||||
fl.isDir = 0;
|
||||
fl.inFtw = 0;
|
||||
fl.currentFlags = 0;
|
||||
fl.currentVerifyFlags = 0;
|
||||
|
||||
@ -1873,7 +1920,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
||||
|
||||
/* Reset for a new line in %files */
|
||||
fl.isDir = 0;
|
||||
fl.inFtw = 0;
|
||||
fl.currentFlags = 0;
|
||||
/* turn explicit flags into %def'd ones (gosh this is hacky...) */
|
||||
fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
|
||||
@ -1940,7 +1986,6 @@ static int processPackageFiles(Spec spec, Package pkg,
|
||||
|
||||
/* Reset for %doc */
|
||||
fl.isDir = 0;
|
||||
fl.inFtw = 0;
|
||||
fl.currentFlags = 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/files.c
|
||||
build/misc.c
|
||||
build/myftw.c
|
||||
build/names.c
|
||||
build/pack.c
|
||||
build/parseBuildInstallClean.c
|
||||
|
Loading…
Reference in New Issue
Block a user