Set permissions of created file
[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         /* Don't use lchown for libc5 or glibc older then 2.1.x */
53 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
54                 if (lchown
55                         (fileName, (whichApp == CHOWN_APP) ? uid : statbuf->st_uid,
56                          (gid == -1) ? statbuf->st_gid : gid) == 0)
57 #else
58                 if (chown
59                         (fileName, (whichApp == CHOWN_APP) ? uid : statbuf->st_uid,
60                          (gid == -1) ? statbuf->st_gid : gid) == 0)
61 #endif
62                 {
63                         return (TRUE);
64                 }
65                 break;
66         case CHMOD_APP:
67                 /* Parse the specified modes */
68                 if (parse_mode(theMode, &(statbuf->st_mode)) == FALSE) {
69                         error_msg_and_die( "unknown mode: %s", theMode);
70                 }
71                 if (chmod(fileName, statbuf->st_mode) == 0)
72                         return (TRUE);
73                 break;
74         }
75         perror(fileName);
76         return (FALSE);
77 }
78
79 int chmod_chown_chgrp_main(int argc, char **argv)
80 {
81         int stopIt = FALSE;
82         int recursiveFlag = FALSE;
83         char *groupName=NULL;
84         char *p=NULL;
85
86         whichApp = (applet_name[2]=='o')?           /* chown */
87                 CHOWN_APP : (applet_name[2]=='m')?      /* chmod */
88                 CHMOD_APP : CHGRP_APP;
89
90         if (argc < 2)
91                 show_usage();
92         argv++;
93
94         /* Parse options */
95         while (--argc >= 0 && *argv && (**argv == '-')) {
96                 while (stopIt==FALSE && *++(*argv)) {
97                         switch (**argv) {
98                                 case 'R':
99                                         recursiveFlag = TRUE;
100                                         break;
101                                 default:
102                                         theMode=*argv-1;
103                                         stopIt = TRUE;
104                         }
105                 }
106                 if (stopIt==TRUE)
107                         break;
108                 argv++;
109         }
110
111         if (argc == 0 || *argv == NULL) {
112                 error_msg(too_few_args);
113         }
114
115         if (whichApp == CHMOD_APP) {
116                 if (theMode==NULL)
117                         theMode = *argv;
118         } else {
119
120                 /* Find the selected group */
121                 if (whichApp == CHGRP_APP) {
122                         groupName = *argv;
123                         gid = strtoul(groupName, &p, 10);       /* maybe it's already numeric */
124                         if (groupName == p)
125                                 gid = my_getgrnam(groupName);
126                 } else {
127                         groupName = strchr(*argv, '.');
128                         if (groupName == NULL)
129                                 groupName = strchr(*argv, ':');
130                         if (groupName) {
131                                 *groupName++ = '\0';
132                                 gid = strtoul(groupName, &p, 10);
133                                 if (groupName == p)
134                                         gid = my_getgrnam(groupName);
135                         } else
136                                 gid = -1;
137                 }
138
139
140                 /* Find the selected user (if appropriate)  */
141                 if (whichApp == CHOWN_APP) {
142                         uid = strtoul(*argv, &p, 10);   /* if numeric ... */
143                         if (*argv == p)
144                                 uid = my_getpwnam(*argv);
145                 }
146         }
147
148         /* Ok, ready to do the deed now */
149         if (argc < 1) {
150                 error_msg_and_die(too_few_args);
151         }
152         while (argc-- > 1) {
153                 if (recursive_action (*(++argv), recursiveFlag, FALSE, FALSE, 
154                                         fileAction, fileAction, NULL) == FALSE)
155                         return EXIT_FAILURE;
156         }
157         return EXIT_SUCCESS;
158
159 }
160
161 /*
162 Local Variables:
163 c-file-style: "linux"
164 c-basic-offset: 4
165 tab-width: 4
166 End:
167 */