diff options
Diffstat (limited to 'chown.c')
-rw-r--r-- | chown.c | 156 |
1 files changed, 109 insertions, 47 deletions
@@ -1,63 +1,125 @@ | |||
1 | #include "internal.h" | 1 | /* |
2 | #include <pwd.h> | 2 | * Mini chown/chgrp implementation for busybox |
3 | #include <grp.h> | 3 | * |
4 | #include <string.h> | 4 | * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> |
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
5 | #include <stdio.h> | 22 | #include <stdio.h> |
23 | #include <grp.h> | ||
24 | #include <pwd.h> | ||
25 | #include "internal.h" | ||
6 | 26 | ||
7 | const char chown_usage[] = "chown [-R] user-name file [file ...]\n" | ||
8 | "\n\tThe group list is kept in the file /etc/groups.\n\n" | ||
9 | "\t-R:\tRecursively change the mode of all files and directories\n" | ||
10 | "\t\tunder the argument directory."; | ||
11 | 27 | ||
12 | int | 28 | static int uid=-1; |
13 | parse_user_name(const char * s, struct FileInfo * i) | 29 | static int gid=0; |
14 | { | 30 | static int chownApp; |
15 | struct passwd * p; | 31 | static char* invocationName=NULL; |
16 | char * dot = strchr(s, '.'); | ||
17 | 32 | ||
18 | if (! dot ) | ||
19 | dot = strchr(s, ':'); | ||
20 | 33 | ||
21 | if ( dot ) | 34 | const char chgrp_usage[] = "[OPTION]... GROUP FILE...\n" |
22 | *dot = '\0'; | 35 | "Change the group membership of each FILE to GROUP.\n" |
36 | "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n"; | ||
37 | const char chown_usage[] = "[OPTION]... OWNER[.[GROUP] FILE...\n" | ||
38 | "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n" | ||
39 | "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n"; | ||
23 | 40 | ||
24 | if ( (p = getpwnam(s)) == 0 ) { | 41 | |
25 | fprintf(stderr, "%s: no such user.\n", s); | 42 | |
26 | return 1; | 43 | static int fileAction(const char *fileName) |
27 | } | 44 | { |
28 | i->userID = p->pw_uid; | 45 | struct stat statBuf; |
29 | 46 | if ((stat(fileName, &statBuf) < 0) || | |
30 | if ( dot ) { | 47 | (chown(fileName, |
31 | struct group * g = getgrnam(++dot); | 48 | ((chownApp==TRUE)? uid: statBuf.st_uid), |
32 | if ( g == 0 ) { | 49 | gid) < 0)) { |
33 | fprintf(stderr, "%s: no such group.\n", dot); | 50 | perror(fileName); |
34 | return 1; | 51 | return( TRUE); |
35 | } | 52 | } |
36 | i->groupID = g->gr_gid; | 53 | return( FALSE); |
37 | i->changeGroupID = 1; | ||
38 | } | ||
39 | return 0; | ||
40 | } | 54 | } |
41 | 55 | ||
42 | extern int | 56 | int chown_main(int argc, char **argv) |
43 | chown_main(struct FileInfo * i, int argc, char * * argv) | ||
44 | { | 57 | { |
45 | int status; | 58 | struct group *grp; |
59 | struct passwd *pwd; | ||
60 | int recursiveFlag=FALSE; | ||
61 | char *groupName; | ||
46 | 62 | ||
47 | while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) { | ||
48 | i->recursive = 1; | ||
49 | argc--; | ||
50 | argv++; | ||
51 | } | ||
52 | 63 | ||
53 | if ( (status = parse_user_name(argv[1], i)) != 0 ) | 64 | chownApp = (strcmp(*argv, "chown")==0)? TRUE : FALSE; |
54 | return status; | ||
55 | 65 | ||
56 | argv++; | 66 | if (argc < 2) { |
67 | fprintf(stderr, "Usage: %s %s", *argv, | ||
68 | (chownApp==TRUE)? chown_usage : chgrp_usage); | ||
69 | return( FALSE); | ||
70 | } | ||
71 | invocationName=*argv; | ||
72 | argc--; | ||
73 | argv++; | ||
74 | |||
75 | /* Parse options */ | ||
76 | while (**argv == '-') { | ||
77 | while (*++(*argv)) switch (**argv) { | ||
78 | case 'R': | ||
79 | recursiveFlag = TRUE; | ||
80 | break; | ||
81 | default: | ||
82 | fprintf(stderr, "Unknown option: %c\n", **argv); | ||
83 | return( FALSE); | ||
84 | } | ||
57 | argc--; | 85 | argc--; |
86 | argv++; | ||
87 | } | ||
88 | |||
89 | /* Find the selected group */ | ||
90 | groupName = strchr(*argv, '.'); | ||
91 | if ( chownApp==TRUE && groupName ) | ||
92 | *groupName++ = '\0'; | ||
93 | else | ||
94 | groupName = *argv; | ||
95 | grp = getgrnam(groupName); | ||
96 | if (grp == NULL) { | ||
97 | fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); | ||
98 | return( FALSE); | ||
99 | } | ||
100 | gid = grp->gr_gid; | ||
58 | 101 | ||
59 | i->changeUserID = 1; | 102 | /* Find the selected user (if appropriate) */ |
60 | i->complainInPostProcess = 1; | 103 | if (chownApp==TRUE) { |
104 | pwd = getpwnam(*argv); | ||
105 | if (pwd == NULL) { | ||
106 | fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); | ||
107 | return( FALSE); | ||
108 | } | ||
109 | uid = pwd->pw_uid; | ||
110 | } | ||
61 | 111 | ||
62 | return monadic_main(i, argc, argv); | 112 | /* Ok, ready to do the deed now */ |
113 | if (argc <= 1) { | ||
114 | fprintf(stderr, "%s: too few arguments", invocationName); | ||
115 | return( FALSE); | ||
116 | } | ||
117 | while (argc-- > 1) { | ||
118 | argv++; | ||
119 | if (recursiveFlag==TRUE) | ||
120 | recursiveAction( *argv, TRUE, fileAction, fileAction); | ||
121 | else | ||
122 | fileAction( *argv); | ||
123 | } | ||
124 | return(TRUE); | ||
63 | } | 125 | } |