summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Shimmin <tes@sgi.com>2007-11-21 05:13:52 +0000
committerTim Shimmin <tes@sgi.com>2007-11-21 05:13:52 +0000
commitf1ae7ff642ca2aead656ddc0d1b2c8bcd621ec9f (patch)
treee72a9ed287fce9f52ee6bbe766f18d5d062a16d0
parent86f937bed13742a7b7de686dad188cac50a31d78 (diff)
downloadattr-f1ae7ff642ca2aead656ddc0d1b2c8bcd621ec9f.tar.gz
fix up tree walking for symlinks
Merge of master-melb:xfs-cmds:30105a by kenmcd.
-rw-r--r--VERSION2
-rw-r--r--doc/CHANGES11
-rw-r--r--getfattr/Makefile4
-rw-r--r--getfattr/getfattr.c93
-rw-r--r--include/walk_tree.h18
-rw-r--r--libmisc/Makefile2
-rw-r--r--libmisc/walk_tree.c100
-rw-r--r--setfattr/Makefile4
-rw-r--r--test/attr.test53
-rw-r--r--test/getfattr.test52
10 files changed, 228 insertions, 111 deletions
diff --git a/VERSION b/VERSION
index 7893f73..a1d6280 100644
--- a/VERSION
+++ b/VERSION
@@ -3,5 +3,5 @@
#
PKG_MAJOR=2
PKG_MINOR=4
-PKG_REVISION=39
+PKG_REVISION=40
PKG_BUILD=0
diff --git a/doc/CHANGES b/doc/CHANGES
index a2a612a..dabe0cb 100644
--- a/doc/CHANGES
+++ b/doc/CHANGES
@@ -1,5 +1,14 @@
-attr-2.4.40
+attr-2.4.40 (21 November 2007)
- Address compilation warning about signedness in libattr.c
+ - A number of changes from Andreas Gruenbacher:
+ - In some cases, gcc does not link in functions from libmisc.a
+ unless libmisc is specified 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.
diff --git a/getfattr/Makefile b/getfattr/Makefile
index a883a57..c33cfa2 100644
--- a/getfattr/Makefile
+++ b/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)
diff --git a/getfattr/getfattr.c b/getfattr/getfattr.c
index dccad37..9cabe43 100644
--- a/getfattr/getfattr.c
+++ b/getfattr/getfattr.c
@@ -28,11 +28,11 @@
#include <ctype.h>
#include <getopt.h>
#include <regex.h>
-#include <ftw.h>
#include <locale.h>
#include <attr/xattr.h>
#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 *str)
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,22 +346,14 @@ int list_attributes(const char *path, int *header_printed)
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 (S_ISLNK(stat->st_mode) &&
- (opt_walk_physical || (ftw->level > 0 && !opt_walk_logical)))
- return 0;
+ if (walk_flags & WALK_TREE_FAILED) {
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(path), strerror(errno));
+ return 1;
+ }
if (opt_name)
print_attribute(path, opt_name, &header_printed);
@@ -371,21 +362,6 @@ int do_print(const char *path, const struct stat *stat,
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 +386,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 +421,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 +440,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 +474,7 @@ int main(int argc, char *argv[])
}
while (optind < argc) {
- had_errors += walk_tree(argv[optind]);
+ had_errors += walk_tree(argv[optind], walk_flags, do_print, NULL);
optind++;
}
diff --git a/include/walk_tree.h b/include/walk_tree.h
new file mode 100644
index 0000000..96bb7a3
--- /dev/null
+++ b/include/walk_tree.h
@@ -0,0 +1,18 @@
+#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_SYMLINK 0x10
+#define WALK_TREE_FAILED 0x20
+
+struct stat;
+
+extern int walk_tree(const char *path, int walk_flags,
+ int (*func)(const char *, const struct stat *, int, void *),
+ void *arg);
+
+#endif
diff --git a/libmisc/Makefile b/libmisc/Makefile
index 9491d41..cdea6ad 100644
--- a/libmisc/Makefile
+++ b/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:
diff --git a/libmisc/walk_tree.c b/libmisc/walk_tree.c
new file mode 100644
index 0000000..62bc74d
--- /dev/null
+++ b/libmisc/walk_tree.c
@@ -0,0 +1,100 @@
+/*
+ File: walk_tree.c
+
+ Copyright (C) 2007 Andreas Gruenbacher <a.gruenbacher@computer.org>
+
+ 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "walk_tree.h"
+
+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;
+ struct stat st;
+ int local_walk_flags = walk_flags, err;
+
+ /* Default to traversing symlinks on the command line, traverse all symlinks
+ * with -L, and do not traverse symlinks with -P. (This is similar to chown.)
+ */
+
+follow_symlink:
+ if (xstat(path, &st) != 0)
+ return func(path, NULL, local_walk_flags | WALK_TREE_FAILED, arg);
+ if (S_ISLNK(st.st_mode)) {
+ if ((local_walk_flags & WALK_TREE_PHYSICAL) ||
+ (!(local_walk_flags & WALK_TREE_LOGICAL) && depth > 1))
+ return 0;
+ local_walk_flags |= WALK_TREE_SYMLINK;
+ xstat = stat;
+ if (local_walk_flags & WALK_TREE_DEREFERENCE)
+ goto follow_symlink;
+ }
+ err = func(path, &st, local_walk_flags, arg);
+ if ((local_walk_flags & WALK_TREE_RECURSIVE) &&
+ (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
+ char path2[FILENAME_MAX];
+ DIR *dir;
+ struct dirent *entry;
+ int err2;
+
+ dir = opendir(path);
+ if (!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, &st,
+ local_walk_flags | WALK_TREE_FAILED, arg);
+ return err;
+ }
+ while ((entry = readdir(dir)) != NULL) {
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+ continue;
+ err2 = snprintf(path2, sizeof(path2), "%s/%s", path,
+ entry->d_name);
+ if (err2 < 0 || err2 > FILENAME_MAX) {
+ errno = ENAMETOOLONG;
+ err += func(path, NULL,
+ local_walk_flags | WALK_TREE_FAILED, arg);
+ continue;
+ }
+ err += walk_tree_rec(path2, walk_flags, func, arg, depth + 1);
+ }
+ if (closedir(dir) != 0)
+ err += func(path, &st, local_walk_flags | WALK_TREE_FAILED, arg);
+ }
+ return err;
+}
+
+int walk_tree(const char *path, int walk_flags,
+ int (*func)(const char *, const struct stat *, int, void *), void *arg)
+{
+ if (strlen(path) >= FILENAME_MAX) {
+ errno = ENAMETOOLONG;
+ return func(path, NULL, WALK_TREE_FAILED, arg);
+ }
+ return walk_tree_rec(path, walk_flags, func, arg, 1);
+}
diff --git a/setfattr/Makefile b/setfattr/Makefile
index 8d10ec2..ad40d71 100644
--- a/setfattr/Makefile
+++ b/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)
diff --git a/test/attr.test b/test/attr.test
index d777518..143e7e9 100644
--- a/test/attr.test
+++ b/test/attr.test
@@ -10,6 +10,9 @@ Execute this test using the `run' script in this directory:
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 special characters
$ setfattr -x "user.special\\007" f
$ rm f
-Some POSIX ACL tests...
-
- $ touch f
+ $ cd ..
+ $ rm -rf d
diff --git a/test/getfattr.test b/test/getfattr.test
new file mode 100644
index 0000000..1e9366d
--- /dev/null
+++ b/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