aboutsummaryrefslogtreecommitdiff
path: root/coreutils/chown.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-27 16:07:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-27 16:07:20 +0000
commit51b4c92f80dc232b9d34985f99a4479393644433 (patch)
treee62b6e2b809db8135d640e3b8222cfd4d52d9098 /coreutils/chown.c
parentfefb279ace2da131cad369a3cc6983a1bc220a4a (diff)
downloadbusybox-w32-51b4c92f80dc232b9d34985f99a4479393644433.tar.gz
busybox-w32-51b4c92f80dc232b9d34985f99a4479393644433.tar.bz2
busybox-w32-51b4c92f80dc232b9d34985f99a4479393644433.zip
chown: add -vcf support if CONFIG_DESKTOP
chmod: stop following symlinks
Diffstat (limited to 'coreutils/chown.c')
-rw-r--r--coreutils/chown.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/coreutils/chown.c b/coreutils/chown.c
index 42f973f32..bef89ce86 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -7,14 +7,10 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */ 8 */
9 9
10/* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */ 10/* BB_AUDIT SUSv3 defects - unsupported options -H, -L, and -P. */
11/* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */ 11/* BB_AUDIT GNU defects - unsupported long options. */
12/* BB_AUDIT Note: gnu chown does not support -H, -L, or -P. */
13/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ 12/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
14 13
15#include <stdlib.h>
16#include <unistd.h>
17#include <string.h>
18#include "busybox.h" 14#include "busybox.h"
19 15
20static uid_t uid = -1; 16static uid_t uid = -1;
@@ -22,39 +18,55 @@ static gid_t gid = -1;
22 18
23static int (*chown_func)(const char *, uid_t, gid_t) = chown; 19static int (*chown_func)(const char *, uid_t, gid_t) = chown;
24 20
21#define OPT_RECURSE (option_mask32 & 1)
22#define OPT_NODEREF (option_mask32 & 2)
23#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0))
24#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0))
25#define OPT_QUIET (USE_DESKTOP(option_mask32 & 0x10) SKIP_DESKTOP(0))
26#define OPT_STR ("Rh" USE_DESKTOP("vcf"))
27
28/* TODO:
29 * -H if a command line argument is a symbolic link to a directory, traverse it
30 * -L traverse every symbolic link to a directory encountered
31 * -P do not traverse any symbolic links (default)
32 */
33
25static int fileAction(const char *fileName, struct stat *statbuf, 34static int fileAction(const char *fileName, struct stat *statbuf,
26 void ATTRIBUTE_UNUSED *junk) 35 void ATTRIBUTE_UNUSED *junk)
27{ 36{
37 // TODO: -H/-L/-P
38 // if (depth ... && S_ISLNK(statbuf->st_mode)) ....
39
28 if (!chown_func(fileName, 40 if (!chown_func(fileName,
29 (uid == (uid_t)-1) ? statbuf->st_uid : uid, 41 (uid == (uid_t)-1) ? statbuf->st_uid : uid,
30 (gid == (gid_t)-1) ? statbuf->st_gid : gid)) { 42 (gid == (gid_t)-1) ? statbuf->st_gid : gid)) {
43 if (OPT_VERBOSE
44 || (OPT_CHANGED && (statbuf->st_uid != uid || statbuf->st_gid != gid))
45 ) {
46 printf("changed ownership of '%s' to %u:%u\n", fileName, uid, gid);
47 }
31 return TRUE; 48 return TRUE;
32 } 49 }
33 bb_perror_msg("%s", fileName); /* A filename can have % in it... */ 50 if (!OPT_QUIET)
51 bb_perror_msg("%s", fileName); /* A filename can have % in it... */
34 return FALSE; 52 return FALSE;
35} 53}
36 54
37#define FLAG_R 1
38#define FLAG_h 2
39
40int chown_main(int argc, char **argv) 55int chown_main(int argc, char **argv)
41{ 56{
42 int flags;
43 int retval = EXIT_SUCCESS; 57 int retval = EXIT_SUCCESS;
44 char *groupName; 58 char *groupName;
45 59
46 flags = getopt32(argc, argv, "Rh"); 60 opt_complementary = "-2";
61 getopt32(argc, argv, OPT_STR);
47 62
48 if (flags & FLAG_h) chown_func = lchown; 63 if (OPT_NODEREF) chown_func = lchown;
49
50 if (argc - optind < 2) {
51 bb_show_usage();
52 }
53 64
54 argv += optind; 65 argv += optind;
55 66
56 /* First, check if there is a group name here */ 67 /* First, check if there is a group name here */
57 if ((groupName = strchr(*argv, '.')) == NULL) { 68 groupName = strchr(*argv, '.');
69 if (!groupName) {
58 groupName = strchr(*argv, ':'); 70 groupName = strchr(*argv, ':');
59 } 71 }
60 72
@@ -68,8 +80,14 @@ int chown_main(int argc, char **argv)
68 80
69 /* Ok, ready to do the deed now */ 81 /* Ok, ready to do the deed now */
70 do { 82 do {
71 if (! recursive_action (*argv, (flags & FLAG_R), FALSE, FALSE, 83 if (!recursive_action(*argv,
72 fileAction, fileAction, NULL)) { 84 OPT_RECURSE, // recurse
85 FALSE, // follow links: TODO: -H/-L/-P
86 FALSE, // depth first
87 fileAction, // file action
88 fileAction, // dir action
89 NULL) // user data
90 ) {
73 retval = EXIT_FAILURE; 91 retval = EXIT_FAILURE;
74 } 92 }
75 } while (*++argv); 93 } while (*++argv);