comparison toys/chgrp.c @ 544:f11693d78764

New toys - chmod, chown, and chgrp.
author Georgi Chorbadzhiyski <gf@unixsol.org>
date Tue, 13 Mar 2012 21:05:12 -0500
parents
children 4a91ede70548
comparison
equal deleted inserted replaced
543:60b97ba66a70 544:f11693d78764
1 /* vi: set sw=4 ts=4:
2 *
3 * chgrp.c - Change group ownership
4 *
5 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
6 *
7 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/chgrp.html
8 *
9 * TODO: Add support for -h
10 * TODO: Add support for -H
11 * TODO: Add support for -L
12 * TODO: Add support for -P
13
14 USE_CHGRP(NEWTOY(chgrp, "<2Rfv", TOYFLAG_BIN))
15
16 config CHGRP
17 bool "chgrp"
18 default y
19 help
20 usage: chgrp [-R] [-f] [-v] group file...
21 Change group ownership of one or more files.
22
23 -R recurse into subdirectories.
24 -f suppress most error messages.
25 -v verbose output.
26 */
27
28 #include "toys.h"
29
30 #define FLAG_R 4
31 #define FLAG_f 2
32 #define FLAG_v 1
33
34 DEFINE_GLOBALS(
35 gid_t group;
36 char *group_name;
37 )
38
39 #define TT this.chgrp
40
41 static int do_chgrp(const char *path) {
42 int ret = chown(path, -1, TT.group);
43 if (toys.optflags & FLAG_v)
44 xprintf("chgrp(%s, %s)\n", TT.group_name, path);
45 if (ret == -1 && !(toys.optflags & FLAG_f))
46 perror_msg("changing group of '%s' to '%s'", path, TT.group_name);
47 toys.exitval |= ret;
48 return ret;
49 }
50
51 // Copied from toys/cp.c:cp_node()
52 int chgrp_node(char *path, struct dirtree *node)
53 {
54 char *s = path + strlen(path);
55 struct dirtree *n = node;
56
57 for ( ; ; n = n->parent) {
58 while (s!=path) {
59 if (*(--s) == '/') break;
60 }
61 if (!n) break;
62 }
63 if (s != path) s++;
64
65 do_chgrp(s);
66
67 return 0;
68 }
69
70 void chgrp_main(void)
71 {
72 char **s;
73 struct group *group;
74
75 TT.group_name = *toys.optargs;
76 group = getgrnam(TT.group_name);
77 if (!group) {
78 error_msg("invalid group '%s'", TT.group_name);
79 toys.exitval = 1;
80 return;
81 }
82 TT.group = group->gr_gid;
83
84 if (toys.optflags & FLAG_R) {
85 // Recurse into subdirectories
86 for (s=toys.optargs + 1; *s; s++) {
87 struct stat sb;
88 if (stat(*s, &sb) == -1) {
89 if (!(toys.optflags & FLAG_f))
90 perror_msg("stat '%s'", *s);
91 continue;
92 }
93 do_chgrp(*s);
94 if (S_ISDIR(sb.st_mode)) {
95 strncpy(toybuf, *s, sizeof(toybuf) - 1);
96 toybuf[sizeof(toybuf) - 1] = 0;
97 dirtree_read(toybuf, NULL, chgrp_node);
98 }
99 }
100 } else {
101 // Do not recurse
102 for (s=toys.optargs + 1; *s; s++) {
103 do_chgrp(*s);
104 }
105 }
106 }