1 /* chgrp.c - Change user and group ownership
3 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/chown.html
6 * See http://opengroup.org/onlinepubs/9699919799/utilities/chgrp.html
8 USE_CHGRP(NEWTOY(chgrp, "<2hPLHRfv[-HLP]", TOYFLAG_BIN))
9 USE_CHOWN(OLDTOY(chown, chgrp, TOYFLAG_BIN))
15 usage: chgrp/chown [-RHLP] [-fvh] group file...
17 Change group of one or more files.
19 -f suppress most error messages.
20 -h change symlinks instead of what they point to
21 -R recurse into subdirectories (implies -h).
22 -H with -R change target of symlink, follow command line symlinks
23 -L with -R change target of symlink, follow all symlinks
24 -P with -R change symlink, do not follow symlinks (default)
41 char *owner_name, *group_name;
45 static int do_chgrp(struct dirtree *node)
47 int fd, ret, flags = toys.optflags;
50 if (!dirtree_notdotdot(node)) return 0;
51 if ((flags & FLAG_R) && !node->again && S_ISDIR(node->st.st_mode))
52 return DIRTREE_COMEAGAIN|(DIRTREE_SYMFOLLOW*!!(flags&FLAG_L));
54 fd = dirtree_parentfd(node);
55 ret = fchownat(fd, node->name, TT.owner, TT.group,
56 AT_SYMLINK_NOFOLLOW*(!(flags&(FLAG_L|FLAG_H)) && (flags&(FLAG_h|FLAG_R))));
58 if (ret || (flags & FLAG_v)) {
59 char *path = dirtree_path(node, 0);
61 xprintf("%s %s%s%s %s\n", toys.which->name,
62 TT.owner_name ? TT.owner_name : "",
63 toys.which->name[2]=='o' && TT.group_name ? ":" : "",
64 TT.group_name ? TT.group_name : "", path);
65 if (ret == -1 && !(toys.optflags & FLAG_f))
66 perror_msg("'%s' to '%s:%s'", path, TT.owner_name, TT.group_name);
76 int ischown = toys.which->name[2] == 'o';
79 TT.owner = TT.group = -1;
81 // Distinguish chown from chgrp
85 own = xstrdup(*toys.optargs);
86 if ((grp = strchr(own, ':')) || (grp = strchr(own, '.'))) {
90 if (*own) TT.owner = xgetuid(TT.owner_name = own);
91 } else TT.group_name = *toys.optargs;
93 if (TT.group_name && *TT.group_name)
94 TT.group = xgetgid(TT.group_name);
96 for (s=toys.optargs+1; *s; s++)
97 dirtree_flagread(*s, DIRTREE_SYMFOLLOW*!!(toys.optflags&(FLAG_H|FLAG_L)),
100 if (CFG_TOYBOX_FREE && ischown) free(own);