aboutsummaryrefslogtreecommitdiff
path: root/chown.c
diff options
context:
space:
mode:
Diffstat (limited to 'chown.c')
-rw-r--r--chown.c156
1 files changed, 109 insertions, 47 deletions
diff --git a/chown.c b/chown.c
index a611f92f1..fc0c2424f 100644
--- a/chown.c
+++ b/chown.c
@@ -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
7const 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
12int 28static int uid=-1;
13parse_user_name(const char * s, struct FileInfo * i) 29static int gid=0;
14{ 30static int chownApp;
15 struct passwd * p; 31static char* invocationName=NULL;
16 char * dot = strchr(s, '.');
17 32
18 if (! dot )
19 dot = strchr(s, ':');
20 33
21 if ( dot ) 34const 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";
37const 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; 43static 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
42extern int 56int chown_main(int argc, char **argv)
43chown_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}