From 7cee87317b2265e9785a4842b2fdd735ce9be8b6 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 3 Feb 2012 11:09:44 -0500 Subject: Add support for -R (recurse) to init chown builtin. This is helpful for setting ownerships on entire directory trees, such as sysfs and selinuxfs, particularly when the precise set of files is dynamically generated at runtime. Change-Id: I81070ea36fd7ffcab4ee8b3ef1bb0028d4b7839c Signed-off-by: Stephen Smalley --- init/builtins.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'init/builtins.c') diff --git a/init/builtins.c b/init/builtins.c index ba7fe3f3..de067ce0 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef HAVE_SELINUX #include @@ -804,6 +805,47 @@ int do_chown(int nargs, char **args) { } else if (nargs == 4) { if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0) return -errno; + } else if (nargs == 5) { + int ret = 0; + int ftsflags = FTS_PHYSICAL; + FTS *fts; + FTSENT *ftsent; + char *options = args[1]; + uid_t uid = decode_uid(args[2]); + uid_t gid = decode_uid(args[3]); + char * path_argv[] = {args[4], NULL}; + if (strcmp(options, "-R")) { + ERROR("do_chown: Invalid argument: %s\n", args[1]); + return -EINVAL; + } + fts = fts_open(path_argv, ftsflags, NULL); + if (!fts) { + ERROR("do_chown: Error traversing hierarchy starting at %s\n", path_argv[0]); + return -errno; + } + while ((ftsent = fts_read(fts))) { + switch (ftsent->fts_info) { + case FTS_DP: + case FTS_SL: + break; + case FTS_DNR: + case FTS_ERR: + case FTS_NS: + ERROR("do_chown: Could not access %s\n", ftsent->fts_path); + fts_set(fts, ftsent, FTS_SKIP); + ret = -errno; + break; + default: + if (_chown(ftsent->fts_accpath, uid, gid) < 0) { + ret = -errno; + fts_set(fts, ftsent, FTS_SKIP); + } + break; + } + } + fts_close(fts); + if (ret) + return ret; } else { return -1; } -- cgit v1.2.3