Commit | Line | Data |
---|---|---|
c20a3dbc | 1 | static char *sccsid = "@(#)chown.c 4.5 (Berkeley) %G%"; |
702e3fe5 | 2 | |
69e53de7 | 3 | /* |
c20a3dbc | 4 | * chown [-fR] uid[.gid] file ... |
69e53de7 BJ |
5 | */ |
6 | ||
7 | #include <stdio.h> | |
8 | #include <ctype.h> | |
9 | #include <sys/types.h> | |
10 | #include <sys/stat.h> | |
11 | #include <pwd.h> | |
702e3fe5 KM |
12 | #include <sys/dir.h> |
13 | #include <grp.h> | |
69e53de7 BJ |
14 | |
15 | struct passwd *pwd,*getpwnam(); | |
16 | struct stat stbuf; | |
17 | int uid; | |
18 | int status; | |
702e3fe5 | 19 | int fflag, rflag; |
69e53de7 BJ |
20 | |
21 | main(argc, argv) | |
22 | char *argv[]; | |
23 | { | |
702e3fe5 KM |
24 | register int c, gid; |
25 | register char *flags, *group; | |
26 | struct group *grp; | |
69e53de7 BJ |
27 | |
28 | if(argc < 3) { | |
c20a3dbc | 29 | fprintf(stderr, "usage: chown [-fR] owner[.group] file ...\n"); |
702e3fe5 | 30 | exit(-1); |
69e53de7 | 31 | } |
702e3fe5 KM |
32 | if (*argv[1] == '-') { |
33 | for (flags = argv[1]; *flags; ++flags) | |
34 | switch (*flags) { | |
35 | case '-': break; | |
36 | case 'f': fflag++; break; | |
37 | case 'R': rflag++; break; | |
38 | default: | |
39 | printf("chown: unknown option: %c\n", *flags); | |
40 | exit(-2); | |
41 | } | |
9a5d5654 KM |
42 | argv++, argc--; |
43 | } | |
702e3fe5 KM |
44 | |
45 | for (group = argv[1]; *group ; group++) { | |
46 | if (*group == '.') { | |
47 | *group = '\0'; | |
48 | group++; | |
49 | if (isnumber(group)) | |
50 | gid = atoi(group); | |
51 | else { | |
52 | if ((grp=getgrnam(group)) == NULL) { | |
53 | printf("unknown group: %s\n",group); | |
54 | exit(-3); | |
55 | } | |
56 | gid = grp -> gr_gid; | |
57 | endgrent(); | |
58 | } | |
59 | goto owner; | |
60 | } | |
69e53de7 | 61 | } |
702e3fe5 KM |
62 | group = NULL; |
63 | ||
64 | owner: | |
65 | if (isnumber(argv[1])) { | |
66 | uid = atoi(argv[1]); | |
67 | } else { | |
68 | if ((pwd=getpwnam(argv[1])) == NULL) { | |
69 | printf("unknown user id: %s\n",argv[1]); | |
70 | exit(-4); | |
71 | } | |
72 | uid = pwd->pw_uid; | |
69e53de7 | 73 | } |
69e53de7 | 74 | |
69e53de7 | 75 | for(c=2; c<argc; c++) { |
702e3fe5 KM |
76 | if (lstat(argv[c], &stbuf) < 0) { |
77 | printf("chown: couldn't stat %s\n", argv[c]); | |
78 | exit(-5); | |
79 | } | |
80 | if (group == NULL) | |
81 | gid = stbuf.st_gid; | |
82 | if (rflag && stbuf.st_mode & S_IFDIR) | |
83 | status += chownr(argv[c], group, uid, gid); | |
84 | else if (chown(argv[c], uid, gid) < 0 && !fflag) { | |
69e53de7 | 85 | perror(argv[c]); |
702e3fe5 | 86 | status++; |
69e53de7 BJ |
87 | } |
88 | } | |
89 | exit(status); | |
90 | } | |
91 | ||
92 | isnumber(s) | |
93 | char *s; | |
94 | { | |
95 | register c; | |
96 | ||
97 | while(c = *s++) | |
98 | if(!isdigit(c)) | |
99 | return(0); | |
100 | return(1); | |
101 | } | |
702e3fe5 KM |
102 | |
103 | chownr(dir, dogrp, uid, gid_save) | |
104 | char *dir; | |
105 | { | |
106 | register DIR *dirp; | |
107 | register struct direct *dp; | |
108 | register struct stat st; | |
109 | char savedir[1024]; | |
110 | int gid; | |
111 | ||
112 | if (getwd(savedir) == 0) { | |
113 | fprintf(stderr, "chown: %s\n", savedir); | |
114 | exit(-6); | |
115 | } | |
116 | if (chown(dir, uid, gid_save) < 0 && !fflag) { | |
117 | perror(dir); | |
118 | return(1); | |
119 | } | |
120 | ||
121 | chdir(dir); | |
122 | if ((dirp = opendir(".")) == NULL) { | |
123 | perror(dir); | |
124 | exit(status); | |
125 | } | |
126 | dp = readdir(dirp); | |
127 | dp = readdir(dirp); /* read "." and ".." */ | |
128 | ||
129 | for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { | |
130 | if (lstat(dp->d_name, &st) < 0) { | |
131 | fprintf(stderr, "chown: can't access %s\n", dp->d_name); | |
132 | return(1); | |
133 | } | |
134 | if (dogrp) | |
135 | gid = gid_save; | |
136 | else | |
137 | gid = st.st_gid; | |
138 | if (st.st_mode & S_IFDIR) | |
139 | chownr(dp->d_name, dogrp, uid, gid); | |
140 | else | |
141 | if (chown(dp->d_name, uid, gid) < 0 && !fflag) { | |
142 | perror(dp->d_name); | |
143 | return(1); | |
144 | } | |
145 | } | |
146 | closedir(dirp); | |
147 | chdir(savedir); | |
148 | return(0); | |
149 | } |