chown.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
chown.c (1992B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <errno.h> | |
3 #include <fcntl.h> | |
4 #include <grp.h> | |
5 #include <limits.h> | |
6 #include <pwd.h> | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <unistd.h> | |
10 | |
11 #include "fs.h" | |
12 #include "util.h" | |
13 | |
14 static int hflag = 0; | |
15 static uid_t uid = -1; | |
16 static gid_t gid = -1; | |
17 static int ret = 0; | |
18 | |
19 static void | |
20 chownpwgr(int dirfd, const char *name, struct stat *st, void *data, stru… | |
21 { | |
22 int flags = 0; | |
23 | |
24 if ((r->maxdepth == 0 && r->follow == 'P') || (r->follow == 'H' … | |
25 flags |= AT_SYMLINK_NOFOLLOW; | |
26 | |
27 if (fchownat(dirfd, name, uid, gid, flags) < 0) { | |
28 weprintf("chown %s:", r->path); | |
29 ret = 1; | |
30 } else if (S_ISDIR(st->st_mode)) { | |
31 recurse(dirfd, name, NULL, r); | |
32 } | |
33 } | |
34 | |
35 static void | |
36 usage(void) | |
37 { | |
38 eprintf("usage: %s [-h] [-R [-H | -L | -P]] owner[:[group]] file… | |
39 " %s [-h] [-R [-H | -L | -P]] :group file ...\n", | |
40 argv0, argv0); | |
41 } | |
42 | |
43 int | |
44 main(int argc, char *argv[]) | |
45 { | |
46 struct group *gr; | |
47 struct passwd *pw; | |
48 struct recursor r = { .fn = chownpwgr, .maxdepth = 1, .follow = … | |
49 char *owner, *group; | |
50 | |
51 ARGBEGIN { | |
52 case 'h': | |
53 hflag = 1; | |
54 break; | |
55 case 'r': | |
56 case 'R': | |
57 r.maxdepth = 0; | |
58 break; | |
59 case 'H': | |
60 case 'L': | |
61 case 'P': | |
62 r.follow = ARGC(); | |
63 break; | |
64 default: | |
65 usage(); | |
66 } ARGEND | |
67 | |
68 if (argc < 2) | |
69 usage(); | |
70 | |
71 owner = argv[0]; | |
72 if ((group = strchr(owner, ':'))) | |
73 *group++ = '\0'; | |
74 | |
75 if (owner && *owner) { | |
76 errno = 0; | |
77 pw = getpwnam(owner); | |
78 if (pw) { | |
79 uid = pw->pw_uid; | |
80 } else { | |
81 if (errno) | |
82 eprintf("getpwnam %s:", owner); | |
83 uid = estrtonum(owner, 0, UINT_MAX); | |
84 } | |
85 } | |
86 if (group && *group) { | |
87 errno = 0; | |
88 gr = getgrnam(group); | |
89 if (gr) { | |
90 gid = gr->gr_gid; | |
91 } else { | |
92 if (errno) | |
93 eprintf("getgrnam %s:", group); | |
94 gid = estrtonum(group, 0, UINT_MAX); | |
95 } | |
96 } | |
97 if (uid == (uid_t)-1 && gid == (gid_t)-1) | |
98 usage(); | |
99 | |
100 for (argc--, argv++; *argv; argc--, argv++) | |
101 recurse(AT_FDCWD, *argv, NULL, &r); | |
102 | |
103 return ret || recurse_status; | |
104 } |