|
Steve Grubb |
d5ab53 |
--- acl-2.2.39/getfacl/getfacl.c.walk 2006-06-20 08:51:25.000000000 +0200
|
|
Thomas Woerner |
71326a |
+++ acl-2.2.39/getfacl/getfacl.c 2007-03-21 10:52:07.000000000 +0100
|
|
Steve Grubb |
d5ab53 |
@@ -34,7 +34,6 @@
|
|
Steve Grubb |
d5ab53 |
#include <dirent.h>
|
|
Steve Grubb |
d5ab53 |
#include <libgen.h>
|
|
Steve Grubb |
d5ab53 |
#include <getopt.h>
|
|
Steve Grubb |
d5ab53 |
-#include <ftw.h>
|
|
Steve Grubb |
d5ab53 |
#include <locale.h>
|
|
Steve Grubb |
d5ab53 |
#include "config.h"
|
|
Steve Grubb |
d5ab53 |
#include "user_group.h"
|
|
Steve Grubb |
d5ab53 |
@@ -70,9 +69,9 @@
|
|
Steve Grubb |
d5ab53 |
const char *progname;
|
|
Steve Grubb |
d5ab53 |
const char *cmd_line_options;
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
-int opt_recursive; /* recurse into sub-directories? */
|
|
Steve Grubb |
d5ab53 |
-int opt_walk_logical; /* always follow symbolic links */
|
|
Steve Grubb |
d5ab53 |
-int opt_walk_physical; /* never follow symbolic links */
|
|
Steve Grubb |
d5ab53 |
+int opt_recursive = 0; /* recurse into sub-directories? */
|
|
Steve Grubb |
d5ab53 |
+int opt_walk_logical = 0; /* always follow symbolic links */
|
|
Steve Grubb |
d5ab53 |
+int opt_walk_physical = 0; /* never follow symbolic links */
|
|
Steve Grubb |
d5ab53 |
int opt_print_acl = 0;
|
|
Steve Grubb |
d5ab53 |
int opt_print_default_acl = 0;
|
|
Steve Grubb |
d5ab53 |
int opt_strip_leading_slash = 1;
|
|
Thomas Woerner |
71326a |
@@ -562,71 +561,140 @@
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
static int __errors;
|
|
Steve Grubb |
d5ab53 |
-int __do_print(const char *file, const struct stat *stat,
|
|
Steve Grubb |
d5ab53 |
- int flag, struct FTW *ftw)
|
|
Steve Grubb |
d5ab53 |
+
|
|
Steve Grubb |
d5ab53 |
+int walk_tree(const char *file)
|
|
Steve Grubb |
d5ab53 |
{
|
|
Steve Grubb |
d5ab53 |
- int saved_errno = errno;
|
|
Steve Grubb |
d5ab53 |
+ static int level = 0;
|
|
Steve Grubb |
d5ab53 |
+ static int link_count = 0;
|
|
Steve Grubb |
d5ab53 |
+ DIR *dir;
|
|
Steve Grubb |
d5ab53 |
+ struct dirent *entry;
|
|
Steve Grubb |
d5ab53 |
+ struct stat buf;
|
|
Thomas Woerner |
71326a |
+ char path[FILENAME_MAX];
|
|
Thomas Woerner |
71326a |
+ char path2[FILENAME_MAX];
|
|
Thomas Woerner |
71326a |
+ char path3[FILENAME_MAX];
|
|
Thomas Woerner |
71326a |
+ char *dir_name;
|
|
Thomas Woerner |
71326a |
+ size_t len;
|
|
Thomas Woerner |
71326a |
+ ssize_t slen;
|
|
Thomas Woerner |
71326a |
+ int res;
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
/* Process the target of a symbolic link, and traverse the link,
|
|
Steve Grubb |
d5ab53 |
only if doing a logical walk, or if the symbolic link was
|
|
Steve Grubb |
d5ab53 |
specified on the command line. Always skip symbolic links if
|
|
Steve Grubb |
d5ab53 |
doing a physical walk. */
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
- if (S_ISLNK(stat->st_mode) &&
|
|
Steve Grubb |
d5ab53 |
- (opt_walk_physical || (ftw->level > 0 && !opt_walk_logical)))
|
|
Thomas Woerner |
71326a |
+ len = strlen(file);
|
|
Thomas Woerner |
71326a |
+ /* check for FILENAME_MAX */
|
|
Thomas Woerner |
71326a |
+ if (len >= FILENAME_MAX) {
|
|
Thomas Woerner |
71326a |
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(file),
|
|
Thomas Woerner |
71326a |
+ strerror(ENAMETOOLONG));
|
|
Thomas Woerner |
71326a |
+ __errors++;
|
|
Steve Grubb |
d5ab53 |
return 0;
|
|
Thomas Woerner |
71326a |
+ }
|
|
Thomas Woerner |
71326a |
+ /* string ends with '/', remove it and restart */
|
|
Thomas Woerner |
71326a |
+ if (len > 1 && file[len-1] == '/') {
|
|
Thomas Woerner |
71326a |
+ strncpy(path, file, len);
|
|
Thomas Woerner |
71326a |
+ path[len-1] = '\0'; /* overwrite slash */
|
|
Thomas Woerner |
71326a |
+ return walk_tree(path);
|
|
Thomas Woerner |
71326a |
+ }
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
- if (do_print(file, stat))
|
|
Thomas Woerner |
71326a |
- __errors++;
|
|
Thomas Woerner |
71326a |
+ if (level > 0 && !opt_recursive)
|
|
Thomas Woerner |
71326a |
+ return 0;
|
|
Thomas Woerner |
71326a |
|
|
Steve Grubb |
d5ab53 |
- if (flag == FTW_DNR && opt_recursive) {
|
|
Steve Grubb |
d5ab53 |
- /* Item is a directory which can't be read. */
|
|
Steve Grubb |
d5ab53 |
- fprintf(stderr, "%s: %s: %s\n",
|
|
Steve Grubb |
d5ab53 |
- progname, file, strerror(saved_errno));
|
|
Thomas Woerner |
71326a |
+ if (lstat(file, &buf) != 0) {
|
|
Thomas Woerner |
71326a |
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(file),
|
|
Thomas Woerner |
71326a |
+ strerror(errno));
|
|
Thomas Woerner |
71326a |
+ __errors++;
|
|
Steve Grubb |
d5ab53 |
return 0;
|
|
Steve Grubb |
d5ab53 |
}
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
- /* We also get here in non-recursive mode. In that case,
|
|
Steve Grubb |
d5ab53 |
- return something != 0 to abort nftw. */
|
|
Thomas Woerner |
71326a |
+ if (S_ISLNK(buf.st_mode)) {
|
|
Thomas Woerner |
71326a |
+ /* physical means: no links at all */
|
|
Thomas Woerner |
71326a |
+ if (opt_walk_physical)
|
|
Thomas Woerner |
71326a |
+ return 1;
|
|
Thomas Woerner |
71326a |
+
|
|
Thomas Woerner |
71326a |
+ /* logical: show information or walk if points to directory
|
|
Thomas Woerner |
71326a |
+ * also for symbolic link arguments on level 0 */
|
|
Thomas Woerner |
71326a |
+ if (opt_walk_logical || level == 0) {
|
|
Thomas Woerner |
71326a |
+ /* copy and append terminating '\0' */
|
|
Thomas Woerner |
71326a |
+ strncpy(path2, file, len+1);
|
|
Thomas Woerner |
71326a |
+
|
|
Thomas Woerner |
71326a |
+ /* get directory name */
|
|
Thomas Woerner |
71326a |
+ dir_name = dirname(path2);
|
|
Thomas Woerner |
71326a |
+
|
|
Thomas Woerner |
71326a |
+ /* get link target */
|
|
Thomas Woerner |
71326a |
+ slen = readlink(file, path, FILENAME_MAX-1);
|
|
Thomas Woerner |
71326a |
+ if (slen < 0) {
|
|
Thomas Woerner |
71326a |
+ fprintf(stderr, "%s: %s: %s\n", progname,
|
|
Thomas Woerner |
71326a |
+ xquote(file), strerror(errno));
|
|
Thomas Woerner |
71326a |
+ __errors++;
|
|
Thomas Woerner |
71326a |
+ return 0;
|
|
Thomas Woerner |
71326a |
+ }
|
|
Thomas Woerner |
71326a |
+ path[slen] = '\0';
|
|
Thomas Woerner |
71326a |
|
|
Steve Grubb |
d5ab53 |
- if (!opt_recursive)
|
|
Thomas Woerner |
71326a |
- return 1;
|
|
Thomas Woerner |
71326a |
+ if (slen == 0 || path[0] == '/') {
|
|
Thomas Woerner |
71326a |
+ /* absolute:
|
|
Thomas Woerner |
71326a |
+ * copy and append terminating '\0' */
|
|
Thomas Woerner |
71326a |
+ strncpy(path3, path, slen+1);
|
|
Thomas Woerner |
71326a |
+ } else
|
|
Thomas Woerner |
71326a |
+ /* relative */
|
|
Thomas Woerner |
71326a |
+ snprintf(path3, FILENAME_MAX, "%s/%s",
|
|
Thomas Woerner |
71326a |
+ dir_name, path);
|
|
Thomas Woerner |
71326a |
+
|
|
Thomas Woerner |
71326a |
+ if (lstat(path3, &buf) != 0) {
|
|
Thomas Woerner |
71326a |
+ fprintf(stderr, "%s: %s: %s\n", progname,
|
|
Thomas Woerner |
71326a |
+ xquote(path), strerror(errno));
|
|
Thomas Woerner |
71326a |
+ __errors++;
|
|
Thomas Woerner |
71326a |
+ return 0;
|
|
Thomas Woerner |
71326a |
+ }
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
- return 0;
|
|
Steve Grubb |
d5ab53 |
-}
|
|
Thomas Woerner |
71326a |
+ if ((S_ISDIR(buf.st_mode) && opt_recursive &&
|
|
Thomas Woerner |
71326a |
+ link_count < 1) || S_ISLNK(buf.st_mode)) {
|
|
Thomas Woerner |
71326a |
+ /* walk directory or follow symlink on level
|
|
Thomas Woerner |
71326a |
+ * 0 */
|
|
Thomas Woerner |
71326a |
+ link_count++;
|
|
Thomas Woerner |
71326a |
+ res = walk_tree(path3);
|
|
Thomas Woerner |
71326a |
+ link_count--;
|
|
Thomas Woerner |
71326a |
+ if (res != 1)
|
|
Thomas Woerner |
71326a |
+ return 0;
|
|
Thomas Woerner |
71326a |
+ } else
|
|
Thomas Woerner |
71326a |
+ if (do_print(path3, &buf))
|
|
Thomas Woerner |
71326a |
+ __errors++;
|
|
Thomas Woerner |
71326a |
|
|
Steve Grubb |
d5ab53 |
-char *resolve_symlinks(const char *file)
|
|
Steve Grubb |
d5ab53 |
-{
|
|
Steve Grubb |
d5ab53 |
- static char buffer[4096];
|
|
Steve Grubb |
d5ab53 |
- char *path = NULL;
|
|
Steve Grubb |
d5ab53 |
- ssize_t len;
|
|
Steve Grubb |
d5ab53 |
-
|
|
Steve Grubb |
d5ab53 |
- len = readlink(file, buffer, sizeof(buffer)-1);
|
|
Steve Grubb |
d5ab53 |
- if (len < 0) {
|
|
Steve Grubb |
d5ab53 |
- if (errno == EINVAL) /* not a symlink, use given path */
|
|
Steve Grubb |
d5ab53 |
- path = (char *)file;
|
|
Steve Grubb |
d5ab53 |
- } else {
|
|
Steve Grubb |
d5ab53 |
- buffer[len+1] = '\0';
|
|
Steve Grubb |
d5ab53 |
- path = buffer;
|
|
Steve Grubb |
d5ab53 |
+ return 1;
|
|
Steve Grubb |
d5ab53 |
+ }
|
|
Steve Grubb |
d5ab53 |
}
|
|
Steve Grubb |
d5ab53 |
- return path;
|
|
Steve Grubb |
d5ab53 |
-}
|
|
Steve Grubb |
d5ab53 |
-
|
|
Steve Grubb |
d5ab53 |
-int walk_tree(const char *file)
|
|
Steve Grubb |
d5ab53 |
-{
|
|
Steve Grubb |
d5ab53 |
- const char *p;
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
- __errors = 0;
|
|
Steve Grubb |
d5ab53 |
- if ((p = resolve_symlinks(file)) == NULL) {
|
|
Steve Grubb |
d5ab53 |
- fprintf(stderr, "%s: %s: %s\n", progname,
|
|
Steve Grubb |
d5ab53 |
- xquote(file), strerror(errno));
|
|
Steve Grubb |
d5ab53 |
- __errors++;
|
|
Steve Grubb |
d5ab53 |
- } else if (nftw(p, __do_print, 0, opt_walk_logical? 0 : FTW_PHYS) < 0) {
|
|
Steve Grubb |
d5ab53 |
- fprintf(stderr, "%s: %s: %s\n", progname, xquote(file),
|
|
Steve Grubb |
d5ab53 |
- strerror(errno));
|
|
Steve Grubb |
d5ab53 |
+ if (do_print(file, &buf))
|
|
Steve Grubb |
d5ab53 |
__errors++;
|
|
Steve Grubb |
d5ab53 |
+
|
|
Thomas Woerner |
71326a |
+ /* it is a directory, walk */
|
|
Steve Grubb |
d5ab53 |
+ if (S_ISDIR(buf.st_mode)) {
|
|
Steve Grubb |
d5ab53 |
+ dir = opendir(file);
|
|
Steve Grubb |
d5ab53 |
+ if (!dir) {
|
|
Steve Grubb |
d5ab53 |
+ fprintf(stderr, "%s: %s: %s\n", progname,
|
|
Steve Grubb |
d5ab53 |
+ xquote(file), strerror(errno));
|
|
Steve Grubb |
d5ab53 |
+ __errors++;
|
|
Steve Grubb |
d5ab53 |
+ return 0;
|
|
Steve Grubb |
d5ab53 |
+ }
|
|
Steve Grubb |
d5ab53 |
+
|
|
Thomas Woerner |
71326a |
+ level++;
|
|
Steve Grubb |
d5ab53 |
+ while ((entry = readdir(dir)) != NULL) {
|
|
Steve Grubb |
d5ab53 |
+ if (! strcmp(entry->d_name, ".") ||
|
|
Steve Grubb |
d5ab53 |
+ ! strcmp(entry->d_name, ".."))
|
|
Steve Grubb |
d5ab53 |
+ continue;
|
|
Steve Grubb |
d5ab53 |
+
|
|
Thomas Woerner |
71326a |
+ snprintf(path, FILENAME_MAX, "%s/%s", file,
|
|
Thomas Woerner |
71326a |
+ entry->d_name);
|
|
Steve Grubb |
d5ab53 |
+
|
|
Thomas Woerner |
71326a |
+ /* ignore result, walk every entry */
|
|
Thomas Woerner |
71326a |
+ res = walk_tree(path);
|
|
Steve Grubb |
d5ab53 |
+ }
|
|
Steve Grubb |
d5ab53 |
+ level--;
|
|
Thomas Woerner |
71326a |
+
|
|
Thomas Woerner |
71326a |
+ closedir(dir);
|
|
Steve Grubb |
d5ab53 |
}
|
|
Steve Grubb |
d5ab53 |
- return __errors;
|
|
Steve Grubb |
d5ab53 |
+
|
|
Steve Grubb |
d5ab53 |
+ return 1;
|
|
Steve Grubb |
d5ab53 |
}
|
|
Steve Grubb |
d5ab53 |
|
|
Steve Grubb |
d5ab53 |
int main(int argc, char *argv[])
|
|
Thomas Woerner |
71326a |
@@ -762,15 +830,22 @@
|
|
Thomas Woerner |
71326a |
if (*line == '\0')
|
|
Thomas Woerner |
71326a |
continue;
|
|
Thomas Woerner |
71326a |
|
|
Thomas Woerner |
71326a |
- had_errors += walk_tree(line);
|
|
Thomas Woerner |
71326a |
+ /* ignore result of walk_tree, use __errors */
|
|
Thomas Woerner |
71326a |
+ __errors = 0;
|
|
Thomas Woerner |
71326a |
+ walk_tree(line);
|
|
Thomas Woerner |
71326a |
+ had_errors += __errors;
|
|
Thomas Woerner |
71326a |
}
|
|
Thomas Woerner |
71326a |
if (!feof(stdin)) {
|
|
Thomas Woerner |
71326a |
fprintf(stderr, _("%s: Standard input: %s\n"),
|
|
Thomas Woerner |
71326a |
progname, strerror(errno));
|
|
Thomas Woerner |
71326a |
had_errors++;
|
|
Thomas Woerner |
71326a |
}
|
|
Thomas Woerner |
71326a |
- } else
|
|
Thomas Woerner |
71326a |
- had_errors += walk_tree(argv[optind]);
|
|
Thomas Woerner |
71326a |
+ } else {
|
|
Thomas Woerner |
71326a |
+ /* ignore result of walk_tree, use __errors */
|
|
Thomas Woerner |
71326a |
+ __errors = 0;
|
|
Thomas Woerner |
71326a |
+ walk_tree(argv[optind]);
|
|
Thomas Woerner |
71326a |
+ had_errors += __errors;
|
|
Thomas Woerner |
71326a |
+ }
|
|
Thomas Woerner |
71326a |
optind++;
|
|
Thomas Woerner |
71326a |
} while (optind < argc);
|
|
Thomas Woerner |
71326a |
|