blob: 27c02fe5430c0814913c295ef8d5567721a21583 [file] [log] [blame]
Eric Andersen2b69c401999-10-05 22:58:32 +00001/*
Eric Andersen1b61f411999-10-13 18:56:42 +00002 * Mini chown/chmod/chgrp implementation for busybox
Eric Andersen2b69c401999-10-05 22:58:32 +00003 *
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;
Eric Andersen1b61f411999-10-13 18:56:42 +000030static int whichApp;
Eric Andersen2b69c401999-10-05 22:58:32 +000031static char* invocationName=NULL;
Eric Andersenf6be9441999-10-13 21:12:06 +000032static mode_t mode=0644;
Eric Andersen2b69c401999-10-05 22:58:32 +000033
34
Eric Andersen1b61f411999-10-13 18:56:42 +000035#define CHGRP_APP 1
36#define CHOWN_APP 2
37#define CHMOD_APP 3
38
Eric Andersen4bea32a1999-10-06 00:30:51 +000039static const char chgrp_usage[] = "[OPTION]... GROUP FILE...\n"
Eric Andersen2b69c401999-10-05 22:58:32 +000040 "Change the group membership of each FILE to GROUP.\n"
41 "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
Eric Andersen4bea32a1999-10-06 00:30:51 +000042static const char chown_usage[] = "[OPTION]... OWNER[.[GROUP] FILE...\n"
Eric Andersen2b69c401999-10-05 22:58:32 +000043 "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n"
44 "\n\tOptions:\n" "\t-R\tchange files and directories recursively\n";
Eric Andersen1b61f411999-10-13 18:56:42 +000045static const char chmod_usage[] = "[-R] MODE[,MODE]... FILE...\n"
46"Each MODE is one or more of the letters ugoa, one of the symbols +-= and\n"
47"one or more of the letters rwxst.\n\n"
48 "\t-R\tchange files and directories recursively.\n";
Eric Andersen2b69c401999-10-05 22:58:32 +000049
50
51
Eric Andersen9b587181999-10-17 05:43:39 +000052static int fileAction(const char *fileName, struct stat* statbuf)
Eric Andersencc8ed391999-10-05 16:24:54 +000053{
Eric Andersen9b587181999-10-17 05:43:39 +000054 switch (whichApp) {
55 case CHGRP_APP:
56 case CHOWN_APP:
57 if (chown(fileName, ((whichApp==CHOWN_APP)? uid: statbuf->st_uid), gid) < 0)
58 return( TRUE);
59 case CHMOD_APP:
60 fprintf(stderr, "%s, %d\n", fileName, mode);
61 if (chmod(fileName, mode))
62 return( TRUE);
Eric Andersen2b69c401999-10-05 22:58:32 +000063 }
Eric Andersen1b61f411999-10-13 18:56:42 +000064 perror(fileName);
65 return( FALSE);
Eric Andersencc8ed391999-10-05 16:24:54 +000066}
67
Eric Andersen1b61f411999-10-13 18:56:42 +000068int chmod_chown_chgrp_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000069{
Eric Andersen2b69c401999-10-05 22:58:32 +000070 struct group *grp;
71 struct passwd *pwd;
72 int recursiveFlag=FALSE;
73 char *groupName;
Eric Andersenf6be9441999-10-13 21:12:06 +000074 mode_t andWithMode= S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
Eric Andersen2b69c401999-10-05 22:58:32 +000075
Eric Andersen1b61f411999-10-13 18:56:42 +000076 whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP;
Eric Andersen2b69c401999-10-05 22:58:32 +000077
78 if (argc < 2) {
79 fprintf(stderr, "Usage: %s %s", *argv,
Eric Andersen1b61f411999-10-13 18:56:42 +000080 (whichApp==TRUE)? chown_usage : chgrp_usage);
Eric Andersen2ce1edc1999-10-12 15:42:48 +000081 exit( FALSE);
Eric Andersen2b69c401999-10-05 22:58:32 +000082 }
83 invocationName=*argv;
84 argc--;
85 argv++;
86
87 /* Parse options */
88 while (**argv == '-') {
89 while (*++(*argv)) switch (**argv) {
90 case 'R':
91 recursiveFlag = TRUE;
92 break;
93 default:
94 fprintf(stderr, "Unknown option: %c\n", **argv);
Eric Andersen2ce1edc1999-10-12 15:42:48 +000095 exit( FALSE);
Eric Andersencc8ed391999-10-05 16:24:54 +000096 }
Eric Andersencc8ed391999-10-05 16:24:54 +000097 argc--;
Eric Andersen2b69c401999-10-05 22:58:32 +000098 argv++;
99 }
100
Eric Andersen1b61f411999-10-13 18:56:42 +0000101 if ( whichApp == CHMOD_APP ) {
102 /* Find the specified modes */
Eric Andersenf6be9441999-10-13 21:12:06 +0000103 if ( parse_mode(*argv, &mode) == FALSE ) {
Eric Andersen1b61f411999-10-13 18:56:42 +0000104 fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv);
Eric Andersen2ce1edc1999-10-12 15:42:48 +0000105 exit( FALSE);
Eric Andersen2b69c401999-10-05 22:58:32 +0000106 }
Eric Andersenf6be9441999-10-13 21:12:06 +0000107 //mode &= andWithMode;
108 fprintf(stderr, "mode %d\n", mode);
Eric Andersen1b61f411999-10-13 18:56:42 +0000109 } else {
Eric Andersencc8ed391999-10-05 16:24:54 +0000110
Eric Andersen1b61f411999-10-13 18:56:42 +0000111 /* Find the selected group */
112 groupName = strchr(*argv, '.');
113 if ( whichApp==TRUE && groupName )
114 *groupName++ = '\0';
115 else
116 groupName = *argv;
117 grp = getgrnam(groupName);
118 if (grp == NULL) {
119 fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName);
120 exit( FALSE);
121 }
122 gid = grp->gr_gid;
123
124 /* Find the selected user (if appropriate) */
125 if (whichApp==TRUE) {
126 pwd = getpwnam(*argv);
127 if (pwd == NULL) {
128 fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv);
129 exit( FALSE);
130 }
131 uid = pwd->pw_uid;
132 }
133 }
134
Eric Andersen2b69c401999-10-05 22:58:32 +0000135 /* Ok, ready to do the deed now */
136 if (argc <= 1) {
137 fprintf(stderr, "%s: too few arguments", invocationName);
Eric Andersen2ce1edc1999-10-12 15:42:48 +0000138 exit( FALSE);
Eric Andersen2b69c401999-10-05 22:58:32 +0000139 }
140 while (argc-- > 1) {
Eric Andersenbed30e91999-10-18 19:02:32 +0000141 if (recursiveAction( *(++argv), recursiveFlag, TRUE, FALSE, fileAction, fileAction)==FALSE)
Eric Andersenf6be9441999-10-13 21:12:06 +0000142 exit( FALSE);
Eric Andersen2b69c401999-10-05 22:58:32 +0000143 }
Eric Andersen2ce1edc1999-10-12 15:42:48 +0000144 exit(TRUE);
Eric Andersencc8ed391999-10-05 16:24:54 +0000145}
Eric Andersen1b61f411999-10-13 18:56:42 +0000146