2 * Copyright (c) 2001-2002 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <sys/types.h>
31 #include <acl/libacl.h>
35 static int acl_delete_file (const char * path, acl_type_t type);
36 static int list_acl(char *file);
37 static int set_acl(acl_t acl, acl_t dacl, const char *fname);
38 static int walk_dir(acl_t acl, acl_t dacl, const char *fname);
46 fprintf(stderr, _("Usage:\n"));
47 fprintf(stderr, _("\t%s acl pathname...\n"), program);
48 fprintf(stderr, _("\t%s -b acl dacl pathname...\n"), program);
49 fprintf(stderr, _("\t%s -d dacl pathname...\n"), program);
50 fprintf(stderr, _("\t%s -R pathname...\n"), program);
51 fprintf(stderr, _("\t%s -D pathname...\n"), program);
52 fprintf(stderr, _("\t%s -B pathname...\n"), program);
53 fprintf(stderr, _("\t%s -l pathname...\t[not IRIX compatible]\n"),
55 fprintf(stderr, _("\t%s -r pathname...\t[not IRIX compatible]\n"),
61 main(int argc, char *argv[])
64 int switch_flag = 0; /* ensure only one switch is used */
65 int args_required = 2;
66 int failed = 0; /* exit status */
67 int c; /* For use by getopt(3) */
68 int dflag = 0; /* a Default ACL is desired */
69 int bflag = 0; /* a both ACLs are desired */
70 int Rflag = 0; /* set to true to remove an acl */
71 int Dflag = 0; /* set to true to remove default acls */
72 int Bflag = 0; /* set to true to remove both acls */
73 int lflag = 0; /* set to true to list acls */
74 acl_t acl = NULL; /* File ACL */
75 acl_t dacl = NULL; /* Directory Default ACL */
77 program = basename(argv[0]);
79 setlocale(LC_CTYPE, "");
80 setlocale(LC_MESSAGES, "");
81 bindtextdomain(PACKAGE, LOCALEDIR);
85 while ((c = getopt(argc, argv, "bdlRDBr")) != -1) {
125 /* if not enough arguments quit */
126 if ((argc - optind) < args_required)
131 for (; optind < argc; optind++) {
139 /* remove the acls */
140 if (Rflag || Dflag || Bflag) {
141 for (; optind < argc; optind++) {
144 (acl_delete_file(file, ACL_TYPE_ACCESS) == -1)) {
146 "%s: error removing access acl on \"%s\": %s\n"),
147 program, file, strerror(errno));
151 (acl_delete_file(file, ACL_TYPE_DEFAULT) == -1)) {
153 "%s: error removing default acl on \"%s\": %s\n"),
154 program, file, strerror(errno));
161 /* file access acl */
163 acl = acl_from_text(argv[optind]);
164 failed = acl_check(acl, &c);
166 fprintf(stderr, "%s: %s - %s\n",
167 program, argv[optind], strerror(errno));
170 else if (failed > 0) {
172 "%s: access ACL '%s': %s at entry %d\n"),
173 program, argv[optind], acl_error(failed), c);
180 /* directory default acl */
181 if (bflag || dflag) {
182 dacl = acl_from_text(argv[optind]);
183 failed = acl_check(dacl, &c);
185 fprintf(stderr, "%s: %s - %s\n",
186 program, argv[optind], strerror(errno));
189 else if (failed > 0) {
191 "%s: access ACL '%s': %s at entry %d\n"),
192 program, argv[optind], acl_error(failed), c);
198 /* place acls on files */
199 for (; optind < argc; optind++)
200 failed += set_acl(acl, dacl, argv[optind]);
211 * deletes an access acl or directory default acl if one exists
214 acl_delete_file(const char *path, acl_type_t type)
218 /* converts access ACL to a minimal ACL */
219 if (type == ACL_TYPE_ACCESS) {
224 acl = acl_get_file(path, ACL_TYPE_ACCESS);
227 error = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
229 acl_get_tag_type(entry, &tag);
234 acl_delete_entry(acl, entry);
237 error = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
240 error = acl_set_file(path, ACL_TYPE_ACCESS, acl);
242 error = acl_delete_def_file(path);
247 * lists the acl for a file/dir in short text form
248 * return 0 on failure
249 * return 1 on success
256 char *acl_text, *dacl_text = NULL;
258 if ((acl = acl_get_file(file, ACL_TYPE_ACCESS)) == NULL) {
259 fprintf(stderr, _("%s: cannot get access ACL on '%s': %s\n"),
260 program, file, strerror(errno));
263 if ((dacl = acl_get_file(file, ACL_TYPE_DEFAULT)) == NULL &&
264 (errno != EACCES)) { /* EACCES given if not a directory */
265 fprintf(stderr, _("%s: cannot get default ACL on '%s': %s\n"),
266 program, file, strerror(errno));
269 acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
270 if (acl_text == NULL) {
271 fprintf(stderr, _("%s: cannot get access ACL text on "
272 "'%s': %s\n"), program, file, strerror(errno));
275 if (acl_entries(dacl) > 0) {
276 dacl_text = acl_to_any_text(dacl, NULL, ',', TEXT_ABBREVIATE);
277 if (dacl_text == NULL) {
278 fprintf(stderr, _("%s: cannot get default ACL text on "
279 "'%s': %s\n"), program, file, strerror(errno));
284 printf("%s [%s/%s]\n", file, acl_text, dacl_text);
287 printf("%s [%s]\n", file, acl_text);
295 set_acl(acl_t acl, acl_t dacl, const char *fname)
300 failed += walk_dir(acl, dacl, fname);
302 /* set regular acl */
303 if (acl && acl_set_file(fname, ACL_TYPE_ACCESS, acl) == -1) {
304 fprintf(stderr, _("%s: cannot set access acl on \"%s\": %s\n"),
305 program, fname, strerror(errno));
308 /* set default acl */
309 if (dacl && acl_set_file(fname, ACL_TYPE_DEFAULT, dacl) == -1) {
310 fprintf(stderr, _("%s: cannot set default acl on \"%s\": %s\n"),
311 program, fname, strerror(errno));
319 walk_dir(acl_t acl, acl_t dacl, const char *fname)
326 if ((dir = opendir(fname)) == NULL) {
327 if (errno != ENOTDIR) {
328 fprintf(stderr, _("%s: opendir failed: %s\n"),
329 program, strerror(errno));
332 return(0); /* got a file, not an error */
335 while ((d = readdir64(dir)) != NULL) {
336 /* skip "." and ".." entries */
337 if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
340 name = malloc(strlen(fname) + strlen(d->d_name) + 2);
342 fprintf(stderr, _("%s: malloc failed: %s\n"),
343 program, strerror(errno));
346 sprintf(name, "%s/%s", fname, d->d_name);
348 failed += set_acl(acl, dacl, name);