Date: Wed, 17 May 2006 19:06:01 GMT From: Todd Miller <millert@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 97367 for review Message-ID: <200605171906.k4HJ61nP044784@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=97367 Change 97367 by millert@millert_ibook on 2006/05/17 19:05:58 Use fts() not nftw() Affected files ... .. //depot/projects/trustedbsd/sedarwin7/src/sedarwin/policycoreutils/restorecon/restorecon.c#2 edit .. //depot/projects/trustedbsd/sedarwin7/src/sedarwin/policycoreutils/setfiles/setfiles.c#2 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin7/src/sedarwin/policycoreutils/restorecon/restorecon.c#2 (text+ko) ==== @@ -31,13 +31,13 @@ #include <unistd.h> #include <limits.h> #include <selinux/selinux.h> +#include <secompat.h> #include <getopt.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> -#define __USE_XOPEN_EXTENDED 1 /* nftw */ -#include <ftw.h> +#include <fts.h> static int change=1; static int verbose=0; @@ -46,8 +46,6 @@ static int errors=0; static int recurse=0; static int force=0; -#define STAT_BLOCK_SIZE 1 -static int pipe_fds[2] = { -1, -1 }; #define MAX_EXCLUDES 100 static int excludeCtr=0; @@ -118,7 +116,7 @@ "usage: %s [-FnrRv] [-e excludedir ] [-o filename ] [-f filename | pathname... ]\n", name); exit(1); } -/* filename has trailing '/' removed by nftw or other calling code */ +/* filename has trailing '/' removed by fts or other calling code */ int restore(const char *filename) { int retcontext=0; security_context_t scontext=NULL; @@ -228,59 +226,47 @@ return errors; } -static int pre_stat(const char *file_unused __attribute__((unused)), - const struct stat *sb_unused __attribute__((unused)), - int flag_unused __attribute__((unused)), - struct FTW *s_unused __attribute__((unused))) +static int apply_spec(const char *file, const struct stat *sb) { - char buf[STAT_BLOCK_SIZE]; - if(write(pipe_fds[1], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) - { - fprintf(stderr, "Error writing to stat pipe, child exiting.\n"); - exit(1); - } - return 0; -} - -static int apply_spec(const char *file, - const struct stat *sb_unused __attribute__((unused)), - int flag, - struct FTW *s_unused __attribute__((unused))) -{ - char buf[STAT_BLOCK_SIZE]; - if(pipe_fds[0] != -1 && read(pipe_fds[0], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) - { - fprintf(stderr, "Read error on pipe.\n"); - pipe_fds[0] = -1; - } - if (flag == FTW_DNR) { - fprintf(stderr, "%s: unable to read directory %s\n", - progname, file); - return 0; - } - errors=errors+restore(file); + errors += restore(file); return 0; } void process(char *buf) { - int rc; if (recurse) { - if(pipe(pipe_fds) == -1) - rc = -1; + FTS *fts; + FTSENT *ftsent; + char *av[2] = {buf, NULL}; + + fts = fts_open(av, FTS_PHYSICAL | FTS_COMFOLLOW, NULL); + if (fts == NULL) { + fprintf(stderr, "%s: error while labeling files under %s\n", + progname, buf); + errors++; + } else - rc = fork(); - if(rc == 0) { - close(pipe_fds[0]); - nftw(buf, pre_stat, 1024, FTW_PHYS); - exit(1); - } - if(rc > 0) - close(pipe_fds[1]); - if(rc == -1 || rc > 0) { - if (nftw(buf, apply_spec, 1024, FTW_PHYS)) { - fprintf(stderr, "%s: error while labeling files under %s\n", - progname, buf); - errors++; + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_DEFAULT: + case FTS_D: + case FTS_F: + case FTS_SL: + case FTS_W: + apply_spec(ftsent->fts_path, ftsent->fts_statp); + break; + case FTS_DNR: + fprintf(stderr, "%s: unable to read directory %s\n", + progname, ftsent->fts_path); + break; + case FTS_NS: + fprintf(stderr, "%s: unable to stat file %s\n", + progname, ftsent->fts_path); + break; + case FTS_ERR: + fprintf(stderr, "%s: %s: %s\n", progname, ftsent->fts_path, + strerror(ftsent->fts_errno)); + break; + } } } } ==== //depot/projects/trustedbsd/sedarwin7/src/sedarwin/policycoreutils/setfiles/setfiles.c#2 (text+ko) ==== @@ -68,8 +68,7 @@ #include <regex.h> #include <sys/types.h> #include <sys/stat.h> -#define __USE_XOPEN_EXTENDED 1 /* nftw */ -#include <ftw.h> +#include <fts.h> #include <limits.h> #include <sepol/sepol.h> #include <selinux/selinux.h> @@ -79,8 +78,6 @@ static int add_assoc = 1; static FILE *outfile=NULL; static int force=0; -#define STAT_BLOCK_SIZE 1 -static int pipe_fds[2] = { -1, -1 }; #define MAX_EXCLUDES 100 static int excludeCtr=0; @@ -163,9 +160,8 @@ return 0; } -int match(const char *name, struct stat *sb, char **con) +int match(const char *name, mode_t mode, char **con) { - int ret; const char *fullname = name; /* fullname will be the real file that gets labeled @@ -184,18 +180,12 @@ return -1; } } - ret = lstat(fullname, sb); - if (ret) { - fprintf(stderr, "%s: unable to stat file %s\n", progname, - fullname); - return -1; - } if(rootpath != NULL && name[0]=='\0') /* this is actually the root dir of the alt root */ - return matchpathcon_index("/", sb->st_mode, con); + return matchpathcon_index("/", mode, con); else - return matchpathcon_index(name, sb->st_mode, con); + return matchpathcon_index(name, mode, con); } void usage(const char * const name) @@ -234,25 +224,15 @@ /* * Apply the last matching specification to a file. - * This function is called by nftw on each file during + * This function is called for each file during * the directory traversal. */ -static int apply_spec(const char *file, - const struct stat *sb_unused __attribute__((unused)), - int flag, - struct FTW *s_unused __attribute__((unused))) +static int apply_spec(const char *file, const struct stat *sb) { const char *my_file; - struct stat my_sb; int i, j, ret; char *context, *newcon; int user_only_changed=0; - char buf[STAT_BLOCK_SIZE]; - if(pipe_fds[0] != -1 && read(pipe_fds[0], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) - { - fprintf(stderr, "Read error on pipe.\n"); - pipe_fds[0] = -1; - } /* Skip the extra slash at the beginning, if present. */ if (file[0] == '/' && file[1] == '/') @@ -260,13 +240,7 @@ else my_file = file; - if (flag == FTW_DNR) { - fprintf(stderr, "%s: unable to read directory %s\n", - progname, my_file); - return 0; - } - - i = match(my_file, &my_sb, &newcon); + i = match(my_file, sb->st_mode, &newcon); if (i < 0) /* No matching specification. */ return 0; @@ -278,7 +252,7 @@ * then use the last matching specification. */ if (add_assoc) { - j = matchpathcon_filespec_add(my_sb.st_ino, i, my_file); + j = matchpathcon_filespec_add(sb->st_ino, i, my_file); if (j < 0) goto err; @@ -424,20 +398,6 @@ return !valid; } -static int pre_stat(const char *file_unused __attribute__((unused)), - const struct stat *sb_unused __attribute__((unused)), - int flag_unused __attribute__((unused)), - struct FTW *s_unused __attribute__((unused))) -{ - char buf[STAT_BLOCK_SIZE]; - if(write(pipe_fds[1], buf, STAT_BLOCK_SIZE) != STAT_BLOCK_SIZE) - { - fprintf(stderr, "Error writing to stat pipe, child exiting.\n"); - exit(1); - } - return 0; -} - int main(int argc, char **argv) { int opt, rc, i; @@ -580,26 +540,16 @@ if(lstat(buf, &sb)) fprintf(stderr, "File \"%s\" not found.\n", buf); else - { - int flag; - switch(sb.st_mode) - { - case S_IFDIR: - flag = FTW_D; - break; - case S_IFLNK: - flag = FTW_SL; - break; - default: - flag = FTW_F; - } - apply_spec(buf, &sb, flag, NULL); - } + apply_spec(buf, &sb); } } } else for (; optind < argc; optind++) { + FTS *fts; + FTSENT *ftsent; + char *pv[2] = { argv[optind], NULL }; + if (NULL != rootpath) { qprintf("%s: labeling files, pretending %s is /\n", argv[0], rootpath); @@ -608,31 +558,49 @@ qprintf("%s: labeling files under %s\n", argv[0], argv[optind]); - int rc; - if(pipe(pipe_fds) == -1) - rc = -1; - else - rc = fork(); - if(rc == 0) - { - close(pipe_fds[0]); - nftw(argv[optind], pre_stat, OPEN_MAX, FTW_PHYS); + fts = fts_open(pv, + FTS_PHYSICAL | FTS_XDEV | FTS_COMFOLLOW, NULL); + if (fts == NULL) { + fprintf(stderr, "%s: cannot traverse filesystem %s", + argv[0], pv[0]); exit(1); } - if(rc > 0) - close(pipe_fds[1]); - if(rc == -1 || rc > 0) { /* Walk the file tree, calling apply_spec on each file. */ - if (nftw - (argv[optind], apply_spec, OPEN_MAX, - FTW_PHYS | FTW_MOUNT)) { + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_DEFAULT: + case FTS_D: /* dir in pre-order */ + case FTS_F: /* file */ + case FTS_SL: /* symlink */ + case FTS_W: /* whiteout */ + apply_spec(ftsent->fts_path, ftsent->fts_statp); + break; + case FTS_DNR: + fprintf(stderr, + "%s: unable to read directory %s\n", + progname, ftsent->fts_path); + break; + case FTS_NS: + fprintf(stderr, + "%s: unable to stat file %s\n", + progname, ftsent->fts_path); + break; + case FTS_ERR: fprintf(stderr, - "%s: error while labeling files under %s\n", - argv[0], argv[optind]); - exit(1); + "%s: %s: %s\n", + progname, ftsent->fts_path, + strerror(ftsent->fts_errno)); + break; + case FTS_DP: /* skip post-order dir */ + case FTS_DC: /* skip dir cycle */ + case FTS_DOT: /* skip . and .. */ + case FTS_SLNONE: /* skip broken symlinks */ + default: + break; } } + fts_close(fts); /* * Evaluate the association hash table distribution for the
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605171906.k4HJ61nP044784>