chgrp.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
chgrp.c (1400B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <sys/stat.h> | |
3 | |
4 #include <errno.h> | |
5 #include <fcntl.h> | |
6 #include <grp.h> | |
7 #include <unistd.h> | |
8 | |
9 #include "fs.h" | |
10 #include "util.h" | |
11 | |
12 static int hflag = 0; | |
13 static gid_t gid = -1; | |
14 static int ret = 0; | |
15 | |
16 static void | |
17 chgrp(int dirfd, const char *name, struct stat *st, void *data, struct r… | |
18 { | |
19 int flags = 0; | |
20 | |
21 if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' … | |
22 flags |= AT_SYMLINK_NOFOLLOW; | |
23 if (fchownat(dirfd, name, -1, gid, flags) < 0) { | |
24 weprintf("chown %s:", r->path); | |
25 ret = 1; | |
26 } else if (S_ISDIR(st->st_mode)) { | |
27 recurse(dirfd, name, NULL, r); | |
28 } | |
29 } | |
30 | |
31 static void | |
32 usage(void) | |
33 { | |
34 eprintf("usage: %s [-h] [-R [-H | -L | -P]] group file ...\n", a… | |
35 } | |
36 | |
37 int | |
38 main(int argc, char *argv[]) | |
39 { | |
40 struct group *gr; | |
41 struct recursor r = { .fn = chgrp, .maxdepth = 1, .follow = 'P' … | |
42 | |
43 ARGBEGIN { | |
44 case 'h': | |
45 hflag = 1; | |
46 break; | |
47 case 'R': | |
48 r.maxdepth = 0; | |
49 break; | |
50 case 'H': | |
51 case 'L': | |
52 case 'P': | |
53 r.follow = ARGC(); | |
54 break; | |
55 default: | |
56 usage(); | |
57 } ARGEND | |
58 | |
59 if (argc < 2) | |
60 usage(); | |
61 | |
62 errno = 0; | |
63 if ((gr = getgrnam(argv[0]))) { | |
64 gid = gr->gr_gid; | |
65 } else { | |
66 if (errno) | |
67 eprintf("getgrnam %s:", argv[0]); | |
68 gid = estrtonum(argv[0], 0, UINT_MAX); | |
69 } | |
70 | |
71 for (argc--, argv++; *argv; argc--, argv++) | |
72 recurse(AT_FDCWD, *argv, NULL, &r); | |
73 | |
74 return ret || recurse_status; | |
75 } |