blob: fc0c2424fd0dc369a141a4ea0870c4987eb49c8c [file] [log] [blame]
Eric Andersen2b69c401999-10-05 22:58:32 +00001/*
2 * Mini chown/chgrp implementation for busybox
3 *
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
Eric Andersencc8ed391999-10-05 16:24:54 +000022#include <stdio.h>
Eric Andersen2b69c401999-10-05 22:58:32 +000023#include <grp.h>
24#include <pwd.h>
25#include "internal.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000026
Eric Andersencc8ed391999-10-05 16:24:54 +000027
Eric Andersen2b69c401999-10-05 22:58:32 +000028static int uid=-1;
29static int gid=0;
30static int chownApp;
31static char* invocationName=NULL;
32
33
34const char chgrp_usage[] = "[OPTION]... GROUP FILE...\n"
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";
40
41
42
43static int fileAction(const char *fileName)
Eric Andersencc8ed391999-10-05 16:24:54 +000044{
Eric Andersen2b69c401999-10-05 22:58:32 +000045 struct stat statBuf;
46 if ((stat(fileName, &statBuf) < 0) ||
47 (chown(fileName,
48 ((chownApp==TRUE)? uid: statBuf.st_uid),
49 gid) < 0)) {
50 perror(fileName);
51 return( TRUE);
52 }
53 return( FALSE);
Eric Andersencc8ed391999-10-05 16:24:54 +000054}
55
Eric Andersen2b69c401999-10-05 22:58:32 +000056int chown_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000057{
Eric Andersen2b69c401999-10-05 22:58:32 +000058 struct group *grp;
59 struct passwd *pwd;
60 int recursiveFlag=FALSE;
61 char *groupName;
Eric Andersencc8ed391999-10-05 16:24:54 +000062
Eric Andersen2b69c401999-10-05 22:58:32 +000063
64 chownApp = (strcmp(*argv, "chown")==0)? TRUE : FALSE;
65
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);
Eric Andersencc8ed391999-10-05 16:24:54 +000084 }
Eric Andersencc8ed391999-10-05 16:24:54 +000085 argc--;
Eric Andersen2b69c401999-10-05 22:58:32 +000086 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;
Eric Andersencc8ed391999-10-05 16:24:54 +0000101
Eric Andersen2b69c401999-10-05 22:58:32 +0000102 /* Find the selected user (if appropriate) */
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 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000111
Eric Andersen2b69c401999-10-05 22:58:32 +0000112 /* 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);
Eric Andersencc8ed391999-10-05 16:24:54 +0000125}