Index: attr-2.4.39/doc/CHANGES =================================================================== --- attr-2.4.39.orig/doc/CHANGES +++ attr-2.4.39/doc/CHANGES @@ -1,3 +1,13 @@ +attr-2.4.40 (?) + - In some cases, gcc does not link in functions from libmisc.a + unless libmisc is specifief before the dynamic libraries on + the command line. + - Rip out nftw tree walking, it is broken and hopeless to fix. + The replacement walk_tree() function does exactly what we + want, and is much simpler to use. + - Add a test case for tree walking. + - For some reason, test/attr.test broke. + attr-2.4.39 (11 September 2007) - Fix symlink handling with getfattr, thanks to Utako Usaka. Index: attr-2.4.39/getfattr/Makefile =================================================================== --- attr-2.4.39.orig/getfattr/Makefile +++ attr-2.4.39/getfattr/Makefile @@ -8,8 +8,8 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = getfattr CFILES = getfattr.c -LLDLIBS = $(LIBATTR) $(LIBMISC) -LTDEPENDENCIES = $(LIBATTR) $(LIBMISC) +LLDLIBS = $(LIBMISC) $(LIBATTR) +LTDEPENDENCIES = $(LIBMISC) $(LIBATTR) default: $(LTCOMMAND) Index: attr-2.4.39/getfattr/getfattr.c =================================================================== --- attr-2.4.39.orig/getfattr/getfattr.c +++ attr-2.4.39/getfattr/getfattr.c @@ -28,11 +28,11 @@ #include #include #include -#include #include #include #include "config.h" +#include "walk_tree.h" #include "misc.h" #define CMD_LINE_OPTIONS "n:de:m:hRLP" @@ -54,11 +54,8 @@ struct option long_options[] = { { NULL, 0, 0, 0 } }; -int opt_recursive; /* recurse into sub-directories? */ -int opt_walk_logical; /* always follow symbolic links */ -int opt_walk_physical; /* never follow symbolic links */ +int walk_flags = WALK_TREE_DEREFERENCE; int opt_dump; /* dump attribute values (or only list the names) */ -int opt_deref = 1; /* dereference symbolic links */ char *opt_name; /* dump named attributes */ char *opt_name_pattern = "^user\\."; /* include only matching names */ char *opt_encoding; /* encode values automatically (NULL), or as "text", @@ -84,12 +81,14 @@ static const char *xquote(const char *st int do_getxattr(const char *path, const char *name, void *value, size_t size) { - return (opt_deref ? getxattr : lgetxattr)(path, name, value, size); + return ((walk_flags & WALK_TREE_DEREFERENCE) ? + getxattr : lgetxattr)(path, name, value, size); } int do_listxattr(const char *path, char *list, size_t size) { - return (opt_deref ? listxattr : llistxattr)(path, list, size); + return ((walk_flags & WALK_TREE_DEREFERENCE) ? + listxattr : llistxattr)(path, list, size); } const char *strerror_ea(int err) @@ -347,21 +346,19 @@ int list_attributes(const char *path, in return 0; } -int do_print(const char *path, const struct stat *stat, - int flag, struct FTW *ftw) +int do_print(const char *path, const struct stat *stat, int walk_flags, void *unused) { - int saved_errno = errno; int header_printed = 0; - /* - * Process the target of a symbolic link, and traverse the - * link, only if doing a logical walk, or if the symbolic link - * was specified on the command line. Always skip symbolic - * links if doing a physical walk. - */ + if (walk_flags & WALK_TREE_FAILED) { + fprintf(stderr, "%s: %s: %s\n", progname, xquote(path), strerror(errno)); + return 1; + } - if (S_ISLNK(stat->st_mode) && - (opt_walk_physical || (ftw->level > 0 && !opt_walk_logical))) + if ((walk_flags & WALK_TREE_SYMLINK) && + (walk_flags & WALK_TREE_DEREFERENCE) && + ((walk_flags & WALK_TREE_PHYSICAL) || + !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL)))) return 0; if (opt_name) @@ -371,21 +368,6 @@ int do_print(const char *path, const str if (header_printed) puts(""); - - if (flag == FTW_DNR && opt_recursive) { - /* Item is a directory which can't be read. */ - fprintf(stderr, "%s: %s: %s\n", progname, xquote(path), - strerror(saved_errno)); - return 0; - } - - /* - * We also get here in non-recursive mode. In that case, - * return something != 0 to abort nftw. - */ - - if (!opt_recursive) - return 1; return 0; } @@ -410,39 +392,6 @@ void help(void) " --help this help text\n")); } -char *resolve_symlinks(const char *file) -{ - static char buffer[4096]; - struct stat stat; - char *path = NULL; - - if (lstat(file, &stat) == -1) - return path; - - if (S_ISLNK(stat.st_mode) && !opt_walk_physical) - path = realpath(file, buffer); - else - path = (char *)file; /* not a symlink, use given path */ - - return path; -} - -int walk_tree(const char *file) -{ - const char *p; - - if ((p = resolve_symlinks(file)) == NULL) { - fprintf(stderr, "%s: %s: %s\n", progname, - xquote(file), strerror(errno)); - return 1; - } else if (nftw(p, do_print, 0, opt_walk_logical? 0 : FTW_PHYS) < 0) { - fprintf(stderr, "%s: %s: %s\n", progname, xquote(file), - strerror(errno)); - return 1; - } - return 0; -} - int main(int argc, char *argv[]) { int opt; @@ -478,7 +427,7 @@ int main(int argc, char *argv[]) return 0; case 'h': /* do not dereference symlinks */ - opt_deref = 0; + walk_flags &= ~WALK_TREE_DEREFERENCE; break; case 'n': /* get named attribute */ @@ -497,17 +446,17 @@ int main(int argc, char *argv[]) break; case 'L': - opt_walk_logical = 1; - opt_walk_physical = 0; + walk_flags |= WALK_TREE_LOGICAL; + walk_flags &= ~WALK_TREE_PHYSICAL; break; case 'P': - opt_walk_logical = 0; - opt_walk_physical = 1; + walk_flags |= WALK_TREE_PHYSICAL; + walk_flags &= ~WALK_TREE_LOGICAL; break; case 'R': - opt_recursive = 1; + walk_flags |= WALK_TREE_RECURSIVE; break; case 'V': @@ -531,7 +480,8 @@ int main(int argc, char *argv[]) } while (optind < argc) { - had_errors += walk_tree(argv[optind]); + had_errors += walk_tree(argv[optind], walk_flags, 0, + do_print, NULL); optind++; } Index: attr-2.4.39/libmisc/Makefile =================================================================== --- attr-2.4.39.orig/libmisc/Makefile +++ attr-2.4.39/libmisc/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/include/builddefs LTLIBRARY = libmisc.la LTLDFLAGS = -CFILES = quote.c unquote.c high_water_alloc.c next_line.c +CFILES = quote.c unquote.c high_water_alloc.c next_line.c walk_tree.c default: $(LTLIBRARY) install install-dev install-lib: Index: attr-2.4.39/setfattr/Makefile =================================================================== --- attr-2.4.39.orig/setfattr/Makefile +++ attr-2.4.39/setfattr/Makefile @@ -8,8 +8,8 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = setfattr CFILES = setfattr.c -LLDLIBS = $(LIBATTR) $(LIBMISC) -LTDEPENDENCIES = $(LIBATTR) $(LIBMISC) +LLDLIBS = $(LIBMISC) $(LIBATTR) +LTDEPENDENCIES = $(LIBMISC) $(LIBATTR) default: $(LTCOMMAND) Index: attr-2.4.39/test/attr.test =================================================================== --- attr-2.4.39.orig/test/attr.test +++ attr-2.4.39/test/attr.test @@ -10,6 +10,9 @@ Execute this test using the `run' script Try various valid and invalid names + $ mkdir d + $ cd d + $ touch f $ setfattr -n user -v value f > setfattr: f: Operation not supported @@ -29,8 +32,8 @@ Try various valid and invalid names Size checks, for an ext2/ext3 file system with a block size of 4K $ touch f - $ setfattr -n user.name -v 4040+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ f - $ setfattr -n user.name -v 4041++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ f + $ setfattr -n user.name -v 4040++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ f + $ setfattr -n user.name -v 4041+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ f > setfattr: f: No space left on device $ rm f @@ -86,13 +89,6 @@ Value encodings > user.name3=0s3vrO > - $ getfattr -d -e text f - > # file: f - > user.name="º¾" - > user.name2="Þ­¾ï" - > user.name3="ÞúÎ" - > - $ rm f Everything with one file @@ -105,7 +101,7 @@ Everything with one file $ setfattr -n user.short -v value f $ setfattr -n user.novalue-yet f $ ls -s f - > 4 f + > 4 f $ getfattr -d f > # file: f @@ -143,7 +139,7 @@ Everything with one file $ setfattr -x user.novalue-yet f $ getfattr -d f $ ls -s f - > 0 f + > 0 f $ rm f @@ -152,15 +148,15 @@ Test extended attribute block sharing $ touch f g h $ setfattr -n user.novalue f g h $ ls -s f g h - > 4 f - > 4 g - > 4 h + > 4 f + > 4 g + > 4 h $ setfattr -n user.name -v value f $ ls -s f g h - > 4 f - > 4 g - > 4 h + > 4 f + > 4 g + > 4 h $ getfattr -d f g h > # file: f @@ -176,15 +172,15 @@ Test extended attribute block sharing $ setfattr -n user.name -v value g $ ls -s f g h - > 4 f - > 4 g - > 4 h + > 4 f + > 4 g + > 4 h $ setfattr -x user.novalue h $ ls -s f g h - > 4 f - > 4 g - > 0 h + > 4 f + > 4 g + > 0 h $ getfattr -d f g h > # file: f @@ -201,9 +197,9 @@ Test extended attribute block sharing $ setfattr -x user.name f g $ setfattr -x user.novalue f g $ ls -s f g h - > 0 f - > 0 g - > 0 h + > 0 f + > 0 g + > 0 h $ rm f g h @@ -260,6 +256,5 @@ Tests for attribute names that contains $ setfattr -x "user.special\\007" f $ rm f -Some POSIX ACL tests... - - $ touch f + $ cd .. + $ rm -rf d Index: attr-2.4.39/include/walk_tree.h =================================================================== --- /dev/null +++ attr-2.4.39/include/walk_tree.h @@ -0,0 +1,19 @@ +#ifndef __WALK_TREE_H +#define __WALK_TREE_H + +#define WALK_TREE_RECURSIVE 0x1 +#define WALK_TREE_PHYSICAL 0x2 +#define WALK_TREE_LOGICAL 0x4 +#define WALK_TREE_DEREFERENCE 0x8 + +#define WALK_TREE_TOPLEVEL 0x100 +#define WALK_TREE_SYMLINK 0x200 +#define WALK_TREE_FAILED 0x400 + +struct stat; + +extern int walk_tree(const char *path, int walk_flags, unsigned int num, + int (*func)(const char *, const struct stat *, int, + void *), void *arg); + +#endif Index: attr-2.4.39/libmisc/walk_tree.c =================================================================== --- /dev/null +++ attr-2.4.39/libmisc/walk_tree.c @@ -0,0 +1,188 @@ +/* + File: walk_tree.c + + Copyright (C) 2007 Andreas Gruenbacher + + This program 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. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "walk_tree.h" + +struct entry_handle { + struct entry_handle *prev, *next; + struct stat st; + DIR *stream; + off_t pos; +}; + +struct entry_handle head = { + .next = &head, + .prev = &head, + /* The other fields are unused. */ +}; +struct entry_handle *closed = &head; +unsigned int num_dir_handles; + +static int walk_tree_rec(const char *path, int walk_flags, + int (*func)(const char *, const struct stat *, int, + void *), void *arg, int depth) +{ + int (*xstat)(const char *, struct stat *) = lstat; + int flags = walk_flags, err; + struct entry_handle dir; + + /* + * If (walk_flags & WALK_TREE_PHYSICAL), do not traverse symlinks. + * If (walk_flags & WALK_TREE_LOGICAL), traverse all symlinks. + * Otherwise, traverse only top-level symlinks. + */ + if (depth == 0) + flags |= WALK_TREE_TOPLEVEL; + +follow_symlink: + if (xstat(path, &dir.st) != 0) + return func(path, NULL, flags | WALK_TREE_FAILED, arg); + if (S_ISLNK(dir.st.st_mode)) { + flags |= WALK_TREE_SYMLINK; + if (flags & WALK_TREE_DEREFERENCE) { + xstat = stat; + goto follow_symlink; + } + } + err = func(path, &dir.st, flags, arg); + if ((flags & WALK_TREE_RECURSIVE) && + (S_ISDIR(dir.st.st_mode) || (S_ISLNK(dir.st.st_mode))) && + (!(flags & WALK_TREE_PHYSICAL) || !(flags & WALK_TREE_SYMLINK)) && + (flags & (WALK_TREE_LOGICAL | WALK_TREE_TOPLEVEL))) { + struct entry_handle *i; + struct dirent *entry; + + /* Check if we have already visited this directory. */ + for (i = head.next; i != &head; i = i->next) + if (i->st.st_dev == dir.st.st_dev && + i->st.st_ino == dir.st.st_ino) + return err; + + if (num_dir_handles == 0 && closed->prev != &head) { +close_another_dir: + /* Close the topmost directory handle still open. */ + closed = closed->prev; + closed->pos = telldir(closed->stream); + closedir(closed->stream); + closed->stream = NULL; + num_dir_handles++; + } + + dir.stream = opendir(path); + if (!dir.stream) { + if (errno == ENFILE && closed->prev != &head) { + /* Ran out of file descriptors. */ + num_dir_handles = 0; + goto close_another_dir; + } + + /* + * PATH may be a symlink to a regular file, or a dead + * symlink which we didn't follow above. + */ + if (errno != ENOTDIR && errno != ENOENT) + err += func(path, &dir.st, + flags | WALK_TREE_FAILED, arg); + return err; + } + + /* Insert into the list of handles. */ + dir.next = head.next; + dir.prev = &head; + dir.prev->next = &dir; + dir.next->prev = &dir; + num_dir_handles--; + + while ((entry = readdir(dir.stream)) != NULL) { + char *path_end; + + if (!strcmp(entry->d_name, ".") || + !strcmp(entry->d_name, "..")) + continue; + path_end = strchr(path, 0); + if ((path_end - path) + strlen(entry->d_name) + 1 >= + FILENAME_MAX) { + errno = ENAMETOOLONG; + err += func(path, NULL, + flags | WALK_TREE_FAILED, arg); + continue; + } + *path_end++ = '/'; + strcpy(path_end, entry->d_name); + err += walk_tree_rec(path, walk_flags, func, arg, + depth + 1); + *--path_end = 0; + if (!dir.stream) { + /* Reopen the directory handle. */ + dir.stream = opendir(path); + if (!dir.stream) + return err + func(path, &dir.st, flags | + WALK_TREE_FAILED, arg); + seekdir(dir.stream, dir.pos); + + closed = closed->next; + num_dir_handles--; + } + } + + if (closedir(dir.stream) != 0) + err += func(path, &dir.st, flags | WALK_TREE_FAILED, + arg); + + /* Remove from the list of handles. */ + dir.prev->next = dir.next; + dir.next->prev = dir.prev; + num_dir_handles++; + } + return err; +} + +int walk_tree(const char *path, int walk_flags, unsigned int num, + int (*func)(const char *, const struct stat *, int, void *), + void *arg) +{ + char path_copy[FILENAME_MAX]; + + num_dir_handles = num; + if (num_dir_handles < 1) { + struct rlimit rlimit; + + num_dir_handles = 1; + if (getrlimit(RLIMIT_NOFILE, &rlimit) == 0 && + rlimit.rlim_cur >= 2) + num_dir_handles = rlimit.rlim_cur / 2; + } + if (strlen(path) >= FILENAME_MAX) { + errno = ENAMETOOLONG; + return func(path, NULL, WALK_TREE_FAILED, arg); + } + strcpy(path_copy, path); + return walk_tree_rec(path_copy, walk_flags, func, arg, 0); +} Index: attr-2.4.39/test/getfattr.test =================================================================== --- /dev/null +++ attr-2.4.39/test/getfattr.test @@ -0,0 +1,52 @@ + $ mkdir d + $ cd d + + $ touch f + $ setfattr -n user.test -v test f + $ ln -s f l + +This case should be obvious: + $ getfattr -d f + > # file: f + > user.test="test" + > + +If a symlink is explicitly specified on the command line, follow it +(-H behavior): + $ getfattr -d l + > # file: l + > user.test="test" + > + +Unless we are explicitly told not to dereference symlinks: + $ getfattr -hd l + +When walking a tree, it does not make sense to follow symlinks. We should +only see f's attributes here -- that's a bug: + $ getfattr -Rd . + > # file: f + > user.test="test" + > + +This case works as expected: + $ getfattr -Rhd . + > # file: f + > user.test="test" + > + +In these two cases, getfattr should dereference the symlink passed on the +command line, but not l. This doesn't work correctly, either; it's the same +bug: + $ ln -s . here + $ getfattr -Rd here + > # file: here/f + > user.test="test" + > + + $ getfattr -Rhd here + > # file: here/f + > user.test="test" + > + + $ cd .. + $ rm -rf d