diff options
author | jbj <devnull@localhost> | 2002-09-20 21:26:16 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2002-09-20 21:26:16 +0000 |
commit | 9e6dc0e00ec028a14812ba36fc781fb6e121bb3b (patch) | |
tree | fea72d7f21ddd6a94438aa054bc7aa791358753e /build | |
parent | 56b4e83a2ee1ab40c7f92cfa4d962fcede4ef785 (diff) | |
download | rpm-9e6dc0e00ec028a14812ba36fc781fb6e121bb3b.tar.gz rpm-9e6dc0e00ec028a14812ba36fc781fb6e121bb3b.tar.bz2 rpm-9e6dc0e00ec028a14812ba36fc781fb6e121bb3b.zip |
- eliminate myftw, use Fts(3) instead.
CVS patchset: 5730
CVS date: 2002/09/20 21:26:16
Diffstat (limited to 'build')
-rw-r--r-- | build/Makefile.am | 4 | ||||
-rw-r--r-- | build/files.c | 129 | ||||
-rw-r--r-- | build/myftw.c | 253 | ||||
-rw-r--r-- | build/myftw.h | 32 |
4 files changed, 91 insertions, 327 deletions
diff --git a/build/Makefile.am b/build/Makefile.am index 75e2d103b..98cfb6053 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -14,11 +14,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 diff --git a/build/files.c b/build/files.c index fb87d5833..06fecb1f9 100644 --- a/build/files.c +++ b/build/files.c @@ -12,6 +12,8 @@ #include <signal.h> /* getOutputFrom() */ #include <rpmio_internal.h> +#include <fts.h> + #include <rpmbuild.h> #include "cpio.h" @@ -24,7 +26,6 @@ #include "buildio.h" -#include "myftw.h" #include "legacy.h" /* XXX domd5, expandFileList, compressFileList */ #include "misc.h" #include "debug.h" @@ -70,23 +71,28 @@ typedef struct FileListRec_s { #define fl_size fl_st.st_size #define fl_mtime fl_st.st_mtime -/*@only@*/ const char * diskURL; /* get file from here */ -/*@only@*/ const char * fileURL; /* filename in cpio archive */ -/*@observer@*/ const char * uname; -/*@observer@*/ const char * gname; +/*@only@*/ + const char *diskURL; /* get file from here */ +/*@only@*/ + const char *fileURL; /* filename in cpio archive */ +/*@observer@*/ + const char *uname; +/*@observer@*/ + const char *gname; unsigned flags; specdFlags specdFlags; /* which attributes have been explicitly specified. */ unsigned verifyFlags; -/*@only@*/ const char *langs; /* XXX locales separated with | */ +/*@only@*/ + const char *langs; /* XXX locales separated with | */ } * FileListRec; /** */ typedef struct AttrRec_s { - const char * ar_fmodestr; - const char * ar_dmodestr; - const char * ar_user; - const char * ar_group; + const char *ar_fmodestr; + const char *ar_dmodestr; + const char *ar_user; + const char *ar_group; mode_t ar_fmode; mode_t ar_dmode; } * AttrRec; @@ -106,8 +112,10 @@ static int check_fileListLen = 0; * Package file tree walk data. */ typedef struct FileList_s { -/*@only@*/ const char * buildRootURL; -/*@only@*/ const char * prefix; +/*@only@*/ + const char * buildRootURL; +/*@only@*/ + const char * prefix; int fileCount; int totalFileSize; @@ -131,14 +139,16 @@ typedef struct FileList_s { specdFlags defSpecdFlags; int defVerifyFlags; int nLangs; -/*@only@*/ /*@null@*/ const char ** currentLangs; +/*@only@*/ /*@null@*/ + const char ** currentLangs; /* Hard coded limit of MAXDOCDIR docdirs. */ /* If you break it you are doing something wrong. */ const char * docDirs[MAXDOCDIR]; int docDirCount; -/*@only@*/ FileListRec fileList; +/*@only@*/ + FileListRec fileList; int fileListRecsAlloced; int fileListRecsUsed; } * FileList; @@ -1503,6 +1513,10 @@ static /*@null@*/ FileListRec freeFileList(/*@only@*/ FileListRec fileList, } /*@=boundswrite@*/ +/* forward ref */ +static int recurseDir(FileList fl, const char * diskURL) + /*@*/; + /** * Add a file to the package manifest. * @param fl package file tree walk data @@ -1595,16 +1609,7 @@ static int addFile(FileList fl, const char * diskURL, } 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(diskURL, 16, (myftwFunc) addFile, fl); - fl->isDir = 0; - fl->inFtw = 0; - return 0; + return recurseDir(fl, diskURL); } fileMode = statp->st_mode; @@ -1629,30 +1634,17 @@ static int addFile(FileList fl, const char * diskURL, fileGname = getGname(fileGid); } -#if 0 /* XXX this looks dumb to me */ - if (! (fileUname && fileGname)) { - rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s\n"), diskName); - fl->processingFailed = 1; - return RPMERR_BADSPEC; - } -#else /* Default user/group to builder's user/group */ if (fileUname == NULL) fileUname = getUname(getuid()); if (fileGname == NULL) fileGname = getGname(getgid()); -#endif -#ifdef DYING /* XXX duplicates with %exclude, use psm.c output instead. */ - rpmMessage(RPMMESS_DEBUG, _("File%5d: %07o %s.%s\t %s\n"), fl->fileCount, - (unsigned)fileMode, fileUname, fileGname, fileURL); -#endif - /* S_XXX macro must be consistent with type in find call at check-files script */ if (check_fileList && S_ISREG(fileMode)) { - appendStringBuf(check_fileList, diskURL); - appendStringBuf(check_fileList, "\n"); - check_fileListLen += strlen(diskURL) + 1; + appendStringBuf(check_fileList, diskURL); + appendStringBuf(check_fileList, "\n"); + check_fileListLen += strlen(diskURL) + 1; } /* Add to the file list */ @@ -1736,6 +1728,63 @@ static int addFile(FileList fl, const char * diskURL, /*@=boundswrite@*/ /** + * Add directory (and all of its files) to the package manifest. + * @param fl package file tree walk data + * @param diskURL path to file + * @param statp file stat (possibly NULL) + * @return 0 on success + */ +static int recurseDir(FileList fl, const char * diskURL) + /*@*/ +{ + char * ftsSet[2]; + FTS * ftsp; + FTSENT * fts; + int ftsOpts = (FTS_COMFOLLOW | FTS_NOCHDIR | FTS_PHYSICAL); + int rc = RPMERR_BADSPEC; + + fl->inFtw = 1; /* Flag to indicate file has buildRootURL prefixed */ + fl->isDir = 1; /* Keep it from following myftw() again */ + + ftsSet[0] = (char *) diskURL; + ftsSet[1] = NULL; + ftsp = Fts_open(ftsSet, ftsOpts, 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 = 0; + 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 = RPMERR_BADSPEC; + break; + } + if (rc) + break; + } + (void) Fts_close(ftsp); + + fl->isDir = 0; + fl->inFtw = 0; + + return rc; +} + +/** * Add a file to a binary package. * @param pkg * @param fl package file tree walk data diff --git a/build/myftw.c b/build/myftw.c deleted file mode 100644 index 7c3c71733..000000000 --- a/build/myftw.c +++ /dev/null @@ -1,253 +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. */ - -/** - */ -/*@-boundswrite@*/ -/*@-nullstate@*/ -static int -myftw_dir (DIR **dirs, int level, int descriptors, - char *dir, size_t len, - myftwFunc func, - void *fl) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies *dirs, *dir, errno, fileSystem, internalState @*/ -{ - 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@*/ -/*@=boundswrite@*/ - -/* Call a function on every element in a directory tree. */ - -/*@-bounds@*/ -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) - { -/*@-compdef@*/ /* FIX: *dirs not defined */ - 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@*/ - } -/*@=compdef@*/ - } - - return retval; -} -/*@=bounds@*/ diff --git a/build/myftw.h b/build/myftw.h deleted file mode 100644 index 2330de100..000000000 --- a/build/myftw.h +++ /dev/null @@ -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, internalState @*/ - /*@modifies *fl, fileSystem, internalState @*/; - -#ifdef __cplusplus -} -#endif - -#endif /* _H_MYFTW_ */ |