It turns out that DODMALLOC was broken when I reorganized busybox.h
[oweals/busybox.git] / chmod_chown_chgrp.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini chown/chmod/chgrp implementation for busybox
4  *
5  *
6  * Copyright (C) 1999,2000,2001 by Lineo, inc.
7  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include "busybox.h"
30 #define BB_DECLARE_EXTERN
31 #define bb_need_invalid_option
32 #define bb_need_too_few_args
33 #include "messages.c"
34
35
36
37 static long uid = -1;
38 static long gid = -1;
39 static int whichApp;
40 static char *theMode = NULL;
41
42
43 #define CHGRP_APP   1
44 #define CHOWN_APP   2
45 #define CHMOD_APP   3
46
47 static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
48 {
49         switch (whichApp) {
50         case CHGRP_APP:
51         case CHOWN_APP:
52 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
53                 if (lchown
54                         (fileName, (whichApp == CHOWN_APP) ? uid : statbuf->st_uid,
55                          (gid == -1) ? statbuf->st_gid : gid) == 0)
56 #else
57                 if (chown
58                         (fileName, (whichApp == CHOWN_APP) ? uid : statbuf->st_uid,
59                          (gid == -1) ? statbuf->st_gid : gid) == 0)
60 #endif
61                 {
62                         return (TRUE);
63                 }
64                 break;
65         case CHMOD_APP:
66                 /* Parse the specified modes */
67                 if (parse_mode(theMode, &(statbuf->st_mode)) == FALSE) {
68                         error_msg_and_die( "unknown mode: %s", theMode);
69                 }
70                 if (chmod(fileName, statbuf->st_mode) == 0)
71                         return (TRUE);
72                 break;
73         }
74         perror(fileName);
75         return (FALSE);
76 }
77
78 int chmod_chown_chgrp_main(int argc, char **argv)
79 {
80         int stopIt = FALSE;
81         int recursiveFlag = FALSE;
82         char *groupName=NULL;
83         char *p=NULL;
84
85         whichApp = (applet_name[2]=='o')?           /* chown */
86                 CHOWN_APP : (applet_name[2]=='m')?      /* chmod */
87                 CHMOD_APP : CHGRP_APP;
88
89         if (argc < 2)
90                 show_usage();
91         argv++;
92
93         /* Parse options */
94         while (--argc >= 0 && *argv && (**argv == '-')) {
95                 while (stopIt==FALSE && *++(*argv)) {
96                         switch (**argv) {
97                                 case 'R':
98                                         recursiveFlag = TRUE;
99                                         break;
100                                 default:
101                                         theMode=*argv-1;
102                                         stopIt = TRUE;
103                         }
104                 }
105                 if (stopIt==TRUE)
106                         break;
107                 argv++;
108         }
109
110         if (argc == 0 || *argv == NULL) {
111                 error_msg(too_few_args);
112         }
113
114         if (whichApp == CHMOD_APP) {
115                 if (theMode==NULL)
116                         theMode = *argv;
117         } else {
118
119                 /* Find the selected group */
120                 if (whichApp == CHGRP_APP) {
121                         groupName = *argv;
122                         gid = strtoul(groupName, &p, 10);       /* maybe it's already numeric */
123                         if (groupName == p)
124                                 gid = my_getgrnam(groupName);
125                         if (gid == -1)
126                                 goto bad_group;
127                 } else {
128                         groupName = strchr(*argv, '.');
129                         if (groupName == NULL)
130                                 groupName = strchr(*argv, ':');
131                         if (groupName) {
132                                 *groupName++ = '\0';
133                                 gid = strtoul(groupName, &p, 10);
134                                 if (groupName == p)
135                                         gid = my_getgrnam(groupName);
136                                 if (gid == -1)
137                                         goto bad_group;
138                         } else
139                                 gid = -1;
140                 }
141
142
143                 /* Find the selected user (if appropriate)  */
144                 if (whichApp == CHOWN_APP) {
145                         uid = strtoul(*argv, &p, 10);   /* if numeric ... */
146                         if (*argv == p)
147                                 uid = my_getpwnam(*argv);
148                         if (uid == -1) {
149                                 error_msg_and_die( "unknown user name: %s", *argv);
150                         }
151                 }
152         }
153
154         /* Ok, ready to do the deed now */
155         if (argc < 1) {
156                 error_msg_and_die(too_few_args);
157         }
158         while (argc-- > 1) {
159                 if (recursive_action (*(++argv), recursiveFlag, FALSE, FALSE, 
160                                         fileAction, fileAction, NULL) == FALSE)
161                         return EXIT_FAILURE;
162         }
163         return EXIT_SUCCESS;
164
165   bad_group:
166         error_msg_and_die( "unknown group name: %s", groupName);
167 }
168
169 /*
170 Local Variables:
171 c-file-style: "linux"
172 c-basic-offset: 4
173 tab-width: 4
174 End:
175 */