Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140874686
D14934.id41353.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D14934.id41353.diff
View Options
Index: bin/setfacl/setfacl.h
===================================================================
--- bin/setfacl/setfacl.h
+++ bin/setfacl/setfacl.h
@@ -47,6 +47,7 @@
int set_acl_mask(acl_t *prev_acl, const char *filename);
/* util.c */
void *zmalloc(size_t size);
+void *zrealloc(void *ptr, size_t size);
const char *brand_name(int brand);
int branding_mismatch(int brand1, int brand2);
Index: bin/setfacl/setfacl.1
===================================================================
--- bin/setfacl/setfacl.1
+++ bin/setfacl/setfacl.1
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 23, 2016
+.Dd March 29, 2018
.Dt SETFACL 1
.Os
.Sh NAME
@@ -34,6 +34,7 @@
.Nd set ACL information
.Sh SYNOPSIS
.Nm
+.Op Fl R Op Fl H | L | P
.Op Fl bdhkn
.Op Fl a Ar position entries
.Op Fl m Ar entries
@@ -83,6 +84,12 @@
.It Fl h
If the target of the operation is a symbolic link, perform the operation
on the symbolic link itself, rather than following the link.
+.It Fl H
+If the
+.Fl R
+option is specified, symbolic links on the command line are followed
+and hence unaffected by the command.
+(Symbolic links encountered during tree traversal are not followed.)
.It Fl k
Delete any default ACL entries on the specified files.
It
@@ -91,6 +98,10 @@
An error will be reported if any of
the specified files cannot have a default entry (i.e.\&
non-directories). This option is not applicable to NFSv4 ACLs.
+.It Fl L
+If the
+.Fl R
+option is specified, all symbolic links are followed.
.It Fl m Ar entries
Modify the ACL on the specified file.
New entries will be added, and existing entries will be modified
@@ -116,6 +127,13 @@
Do not recalculate the permissions associated with the ACL
mask entry.
This option is not applicable to NFSv4 ACLs.
+.It Fl P
+If the
+.Fl R
+option is specified, no symbolic links are followed.
+This is the default.
+.It Fl R
+Perform the action recursively on any specified directories.
.It Fl x Ar entries | position
If
.Ar entries
Index: bin/setfacl/setfacl.c
===================================================================
--- bin/setfacl/setfacl.c
+++ bin/setfacl/setfacl.c
@@ -35,6 +35,9 @@
#include <err.h>
#include <errno.h>
+#include <fts.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,41 +62,20 @@
};
static TAILQ_HEAD(, sf_entry) entrylist;
-/* TAILQ entry for files */
-struct sf_file {
- const char *filename;
- TAILQ_ENTRY(sf_file) next;
-};
-static TAILQ_HEAD(, sf_file) filelist;
-
uint have_mask;
uint need_mask;
uint have_stdin;
uint n_flag;
-static void add_filename(const char *filename);
static void usage(void);
-static void
-add_filename(const char *filename)
-{
- struct sf_file *file;
-
- if (strlen(filename) > PATH_MAX - 1) {
- warn("illegal filename");
- return;
- }
- file = zmalloc(sizeof(struct sf_file));
- file->filename = filename;
- TAILQ_INSERT_TAIL(&filelist, file, next);
-}
-
static void
usage(void)
{
- fprintf(stderr, "usage: setfacl [-bdhkn] [-a position entries] "
- "[-m entries] [-M file] [-x entries] [-X file] [file ...]\n");
+ fprintf(stderr, "usage: setfacl [-R [-H | -L | -P]] [-bdhkn] "
+ "[-a position entries] [-m entries] [-M file] "
+ "[-x entries] [-X file] [file ...]\n");
exit(1);
}
@@ -104,23 +86,32 @@
acl_type_t acl_type;
acl_entry_t unused_entry;
char filename[PATH_MAX];
- int local_error, carried_error, ch, i, entry_number, ret;
- int h_flag;
- struct sf_file *file;
+ int local_error, carried_error, ch, entry_number, ret, fts_options;
+ bool h_flag, H_flag, L_flag, R_flag, follow_symlink;
+ size_t fl_count, i;
+ FTS *ftsp;
+ FTSENT *file;
+ char **files_list;
struct sf_entry *entry;
- const char *fn_dup;
char *end;
- struct stat sb;
acl_type = ACL_TYPE_ACCESS;
- carried_error = local_error = 0;
- h_flag = have_mask = have_stdin = n_flag = need_mask = 0;
+ carried_error = local_error = fts_options = 0;
+ have_mask = have_stdin = n_flag = need_mask = 0;
+ h_flag = H_flag = L_flag = R_flag = false;
TAILQ_INIT(&entrylist);
- TAILQ_INIT(&filelist);
- while ((ch = getopt(argc, argv, "M:X:a:bdhkm:nx:")) != -1)
+ while ((ch = getopt(argc, argv, "HLM:PRX:a:bdhkm:nx:")) != -1)
switch(ch) {
+ case 'H':
+ H_flag = true;
+ L_flag = false;
+ break;
+ case 'L':
+ L_flag = true;
+ H_flag = false;
+ break;
case 'M':
entry = zmalloc(sizeof(struct sf_entry));
entry->acl = get_acl_from_file(optarg);
@@ -129,6 +120,12 @@
entry->op = OP_MERGE_ACL;
TAILQ_INSERT_TAIL(&entrylist, entry, next);
break;
+ case 'P':
+ H_flag = L_flag = false;
+ break;
+ case 'R':
+ R_flag = true;
+ break;
case 'X':
entry = zmalloc(sizeof(struct sf_entry));
entry->acl = get_acl_from_file(optarg);
@@ -213,43 +210,93 @@
err(1, "cannot have more than one stdin");
have_stdin = 1;
bzero(&filename, sizeof(filename));
+ i = 0;
+ /* start with an array size sufficient for basic cases */
+ fl_count = 1024;
+ files_list = zmalloc(fl_count * sizeof(char *));
while (fgets(filename, (int)sizeof(filename), stdin)) {
/* remove the \n */
filename[strlen(filename) - 1] = '\0';
- fn_dup = strdup(filename);
- if (fn_dup == NULL)
+ files_list[i] = strdup(filename);
+ if (files_list[i] == NULL)
err(1, "strdup() failed");
- add_filename(fn_dup);
+ /* grow array if necessary */
+ if (++i == fl_count) {
+ fl_count <<= 1;
+ if (fl_count > SIZE_MAX / sizeof(char *))
+ errx(1, "Too many input files");
+ files_list = zrealloc(files_list,
+ fl_count * sizeof(char *));
+ }
}
+
+ /* fts_open() requires the last array element to be NULL */
+ files_list[i] = NULL;
} else
- for (i = 0; i < argc; i++)
- add_filename(argv[i]);
+ files_list = argv;
- /* cycle through each file */
- TAILQ_FOREACH(file, &filelist, next) {
- local_error = 0;
+ if (R_flag) {
+ if (h_flag)
+ errx(1, "the -R and -h options may not be "
+ "specified together.");
+ if (L_flag) {
+ fts_options = FTS_LOGICAL;
+ } else {
+ fts_options = FTS_PHYSICAL;
- if (stat(file->filename, &sb) == -1) {
- warn("%s: stat() failed", file->filename);
- carried_error++;
+ if (H_flag) {
+ fts_options |= FTS_COMFOLLOW;
+ }
+ }
+ } else if (h_flag) {
+ fts_options = FTS_PHYSICAL;
+ } else {
+ fts_options = FTS_LOGICAL;
+ }
+
+ /* open all files */
+ if ((ftsp = fts_open(files_list, fts_options | FTS_NOSTAT, 0)) == NULL)
+ err(1, "fts_open");
+ while ((file = fts_read(ftsp)) != NULL) {
+ switch (file->fts_info) {
+ case FTS_D:
+ /* Do not recurse if -R not specified */
+ if (!R_flag)
+ fts_set(ftsp, file, FTS_SKIP);
+ break;
+ case FTS_DP:
+ /* Skip the second visit to a directory */
continue;
+ case FTS_DNR:
+ case FTS_ERR:
+ warnx("%s: %s", file->fts_path,
+ strerror(file->fts_errno));
+ continue;
+ default:
+ break;
}
- if (acl_type == ACL_TYPE_DEFAULT && S_ISDIR(sb.st_mode) == 0) {
- warnx("%s: default ACL may only be set on a directory",
- file->filename);
+ if (acl_type == ACL_TYPE_DEFAULT && file->fts_info != FTS_D) {
+ warnx("%s: default ACL may only be set on "
+ "a directory", file->fts_path);
carried_error++;
continue;
}
- if (h_flag)
- ret = lpathconf(file->filename, _PC_ACL_NFS4);
+ local_error = 0;
+
+ follow_symlink = ((fts_options & FTS_LOGICAL) ||
+ ((fts_options & FTS_COMFOLLOW) &&
+ file->fts_level == FTS_ROOTLEVEL));
+
+ if (follow_symlink)
+ ret = pathconf(file->fts_accpath, _PC_ACL_NFS4);
else
- ret = pathconf(file->filename, _PC_ACL_NFS4);
+ ret = lpathconf(file->fts_accpath, _PC_ACL_NFS4);
if (ret > 0) {
if (acl_type == ACL_TYPE_DEFAULT) {
warnx("%s: there are no default entries "
- "in NFSv4 ACLs", file->filename);
+ "in NFSv4 ACLs", file->fts_path);
carried_error++;
continue;
}
@@ -259,20 +306,20 @@
acl_type = ACL_TYPE_ACCESS;
} else if (ret < 0 && errno != EINVAL) {
warn("%s: pathconf(..., _PC_ACL_NFS4) failed",
- file->filename);
+ file->fts_path);
}
- if (h_flag)
- acl = acl_get_link_np(file->filename, acl_type);
+ if (follow_symlink)
+ acl = acl_get_file(file->fts_accpath, acl_type);
else
- acl = acl_get_file(file->filename, acl_type);
+ acl = acl_get_link_np(file->fts_accpath, acl_type);
if (acl == NULL) {
- if (h_flag)
- warn("%s: acl_get_link_np() failed",
- file->filename);
- else
+ if (follow_symlink)
warn("%s: acl_get_file() failed",
- file->filename);
+ file->fts_path);
+ else
+ warn("%s: acl_get_link_np() failed",
+ file->fts_path);
carried_error++;
continue;
}
@@ -285,11 +332,12 @@
switch(entry->op) {
case OP_ADD_ACL:
local_error += add_acl(entry->acl,
- entry->entry_number, &acl, file->filename);
+ entry->entry_number,
+ &acl, file->fts_path);
break;
case OP_MERGE_ACL:
local_error += merge_acl(entry->acl, &acl,
- file->filename);
+ file->fts_path);
need_mask = 1;
break;
case OP_REMOVE_EXT:
@@ -301,37 +349,37 @@
acl_get_entry(acl, ACL_FIRST_ENTRY,
&unused_entry) == 0) {
local_error += remove_default(&acl,
- file->filename);
+ file->fts_path);
break;
}
- remove_ext(&acl, file->filename);
+ remove_ext(&acl, file->fts_path);
need_mask = 0;
break;
case OP_REMOVE_DEF:
if (acl_type == ACL_TYPE_NFS4) {
warnx("%s: there are no default entries in NFSv4 ACLs; "
- "cannot remove", file->filename);
+ "cannot remove", file->fts_path);
local_error++;
break;
}
- if (acl_delete_def_file(file->filename) == -1) {
+ if (acl_delete_def_file(file->fts_accpath) == -1) {
warn("%s: acl_delete_def_file() failed",
- file->filename);
+ file->fts_path);
local_error++;
}
if (acl_type == ACL_TYPE_DEFAULT)
local_error += remove_default(&acl,
- file->filename);
+ file->fts_path);
need_mask = 0;
break;
case OP_REMOVE_ACL:
local_error += remove_acl(entry->acl, &acl,
- file->filename);
+ file->fts_path);
need_mask = 1;
break;
case OP_REMOVE_BY_NUMBER:
local_error += remove_by_number(entry->entry_number,
- &acl, file->filename);
+ &acl, file->fts_path);
need_mask = 1;
break;
}
@@ -343,9 +391,9 @@
*/
if (acl_type == ACL_TYPE_DEFAULT &&
acl_get_entry(acl, ACL_FIRST_ENTRY, &unused_entry) == 0) {
- if (acl_delete_def_file(file->filename) == -1) {
+ if (acl_delete_def_file(file->fts_accpath) == -1) {
warn("%s: acl_delete_def_file() failed",
- file->filename);
+ file->fts_path);
carried_error++;
}
continue;
@@ -358,22 +406,22 @@
}
if (acl_type != ACL_TYPE_NFS4 && need_mask &&
- set_acl_mask(&acl, file->filename) == -1) {
- warnx("%s: failed to set ACL mask", file->filename);
+ set_acl_mask(&acl, file->fts_path) == -1) {
+ warnx("%s: failed to set ACL mask", file->fts_path);
carried_error++;
- } else if (h_flag) {
- if (acl_set_link_np(file->filename, acl_type,
+ } else if (follow_symlink) {
+ if (acl_set_file(file->fts_accpath, acl_type,
acl) == -1) {
carried_error++;
- warn("%s: acl_set_link_np() failed",
- file->filename);
+ warn("%s: acl_set_file() failed",
+ file->fts_path);
}
} else {
- if (acl_set_file(file->filename, acl_type,
+ if (acl_set_link_np(file->fts_accpath, acl_type,
acl) == -1) {
carried_error++;
- warn("%s: acl_set_file() failed",
- file->filename);
+ warn("%s: acl_set_link_np() failed",
+ file->fts_path);
}
}
Index: bin/setfacl/util.c
===================================================================
--- bin/setfacl/util.c
+++ bin/setfacl/util.c
@@ -44,6 +44,17 @@
return (ptr);
}
+void *
+zrealloc(void *ptr, size_t size)
+{
+ void *newptr;
+
+ newptr = realloc(ptr, size);
+ if (newptr == NULL)
+ err(1, "realloc() failed");
+ return (newptr);
+}
+
const char *
brand_name(int brand)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Dec 30, 3:19 AM (11 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27374669
Default Alt Text
D14934.id41353.diff (11 KB)
Attached To
Mode
D14934: Add recursive flags to setfacl(1)
Attached
Detach File
Event Timeline
Log In to Comment