10f66f451Sopenharmony_ci/* chgrp.c - Change user and group ownership 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/chown.html 60f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/chgrp.html 70f66f451Sopenharmony_ci 80f66f451Sopenharmony_ciUSE_CHGRP(NEWTOY(chgrp, "<2hPLHRfv[-HLP]", TOYFLAG_BIN)) 90f66f451Sopenharmony_ciUSE_CHOWN(OLDTOY(chown, chgrp, TOYFLAG_BIN)) 100f66f451Sopenharmony_ci 110f66f451Sopenharmony_ciconfig CHGRP 120f66f451Sopenharmony_ci bool "chgrp" 130f66f451Sopenharmony_ci default y 140f66f451Sopenharmony_ci help 150f66f451Sopenharmony_ci usage: chgrp/chown [-RHLP] [-fvh] group file... 160f66f451Sopenharmony_ci 170f66f451Sopenharmony_ci Change group of one or more files. 180f66f451Sopenharmony_ci 190f66f451Sopenharmony_ci -f Suppress most error messages 200f66f451Sopenharmony_ci -h Change symlinks instead of what they point to 210f66f451Sopenharmony_ci -R Recurse into subdirectories (implies -h) 220f66f451Sopenharmony_ci -H With -R change target of symlink, follow command line symlinks 230f66f451Sopenharmony_ci -L With -R change target of symlink, follow all symlinks 240f66f451Sopenharmony_ci -P With -R change symlink, do not follow symlinks (default) 250f66f451Sopenharmony_ci -v Verbose 260f66f451Sopenharmony_ci 270f66f451Sopenharmony_ciconfig CHOWN 280f66f451Sopenharmony_ci bool "chown" 290f66f451Sopenharmony_ci default y 300f66f451Sopenharmony_ci help 310f66f451Sopenharmony_ci see: chgrp 320f66f451Sopenharmony_ci*/ 330f66f451Sopenharmony_ci 340f66f451Sopenharmony_ci#define FOR_chgrp 350f66f451Sopenharmony_ci#define FORCE_FLAGS 360f66f451Sopenharmony_ci#include "toys.h" 370f66f451Sopenharmony_ci 380f66f451Sopenharmony_ciGLOBALS( 390f66f451Sopenharmony_ci uid_t owner; 400f66f451Sopenharmony_ci gid_t group; 410f66f451Sopenharmony_ci char *owner_name, *group_name; 420f66f451Sopenharmony_ci int symfollow; 430f66f451Sopenharmony_ci) 440f66f451Sopenharmony_ci 450f66f451Sopenharmony_cistatic int do_chgrp(struct dirtree *node) 460f66f451Sopenharmony_ci{ 470f66f451Sopenharmony_ci int fd, ret, flags = toys.optflags; 480f66f451Sopenharmony_ci 490f66f451Sopenharmony_ci // Depth first search 500f66f451Sopenharmony_ci if (!dirtree_notdotdot(node)) return 0; 510f66f451Sopenharmony_ci if ((flags & FLAG_R) && !node->again && S_ISDIR(node->st.st_mode)) 520f66f451Sopenharmony_ci return DIRTREE_COMEAGAIN|(DIRTREE_SYMFOLLOW*!!(flags&FLAG_L)); 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci fd = dirtree_parentfd(node); 550f66f451Sopenharmony_ci ret = fchownat(fd, node->name, TT.owner, TT.group, 560f66f451Sopenharmony_ci AT_SYMLINK_NOFOLLOW*(!(flags&(FLAG_L|FLAG_H)) && (flags&(FLAG_h|FLAG_R)))); 570f66f451Sopenharmony_ci 580f66f451Sopenharmony_ci if (ret || (flags & FLAG_v)) { 590f66f451Sopenharmony_ci char *path = dirtree_path(node, 0); 600f66f451Sopenharmony_ci if (flags & FLAG_v) 610f66f451Sopenharmony_ci xprintf("%s %s%s%s %s\n", toys.which->name, TT.owner_name, 620f66f451Sopenharmony_ci (toys.which->name[2]=='o' && *TT.group_name) ? ":" : "", 630f66f451Sopenharmony_ci TT.group_name, path); 640f66f451Sopenharmony_ci if (ret == -1 && !(toys.optflags & FLAG_f)) 650f66f451Sopenharmony_ci perror_msg("'%s' to '%s:%s'", path, TT.owner_name, TT.group_name); 660f66f451Sopenharmony_ci free(path); 670f66f451Sopenharmony_ci } 680f66f451Sopenharmony_ci toys.exitval |= ret; 690f66f451Sopenharmony_ci 700f66f451Sopenharmony_ci return 0; 710f66f451Sopenharmony_ci} 720f66f451Sopenharmony_ci 730f66f451Sopenharmony_civoid chgrp_main(void) 740f66f451Sopenharmony_ci{ 750f66f451Sopenharmony_ci int ischown = toys.which->name[2] == 'o'; 760f66f451Sopenharmony_ci char **s, *own; 770f66f451Sopenharmony_ci 780f66f451Sopenharmony_ci TT.owner = TT.group = -1; 790f66f451Sopenharmony_ci TT.owner_name = TT.group_name = ""; 800f66f451Sopenharmony_ci 810f66f451Sopenharmony_ci // Distinguish chown from chgrp 820f66f451Sopenharmony_ci if (ischown) { 830f66f451Sopenharmony_ci char *grp; 840f66f451Sopenharmony_ci 850f66f451Sopenharmony_ci own = xstrdup(*toys.optargs); 860f66f451Sopenharmony_ci if ((grp = strchr(own, ':')) || (grp = strchr(own, '.'))) { 870f66f451Sopenharmony_ci *(grp++) = 0; 880f66f451Sopenharmony_ci TT.group_name = grp; 890f66f451Sopenharmony_ci } 900f66f451Sopenharmony_ci if (*own) TT.owner = xgetuid(TT.owner_name = own); 910f66f451Sopenharmony_ci } else TT.group_name = *toys.optargs; 920f66f451Sopenharmony_ci 930f66f451Sopenharmony_ci if (TT.group_name && *TT.group_name) 940f66f451Sopenharmony_ci TT.group = xgetgid(TT.group_name); 950f66f451Sopenharmony_ci 960f66f451Sopenharmony_ci for (s=toys.optargs+1; *s; s++) 970f66f451Sopenharmony_ci dirtree_flagread(*s, DIRTREE_SYMFOLLOW*!!(toys.optflags&(FLAG_H|FLAG_L)), 980f66f451Sopenharmony_ci do_chgrp); 990f66f451Sopenharmony_ci 1000f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE && ischown) free(own); 1010f66f451Sopenharmony_ci} 1020f66f451Sopenharmony_ci 1030f66f451Sopenharmony_civoid chown_main() 1040f66f451Sopenharmony_ci{ 1050f66f451Sopenharmony_ci chgrp_main(); 1060f66f451Sopenharmony_ci} 107