aboutsummaryrefslogtreecommitdiff
path: root/coreutils/chmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/chmod.c')
-rw-r--r--coreutils/chmod.c85
1 files changed, 51 insertions, 34 deletions
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index ba80e020a..28c98552a 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -24,67 +24,84 @@
24 * 24 *
25 */ 25 */
26 26
27/* BB_AUDIT SUSv3 compliant */
28/* BB_AUDIT GNU defects - unsupported options -c, -f, -v, and long options. */
29/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
30
27#include <stdio.h> 31#include <stdio.h>
28#include <stdlib.h> 32#include <stdlib.h>
29#include <string.h> 33#include <string.h>
30#include <unistd.h> 34#include <unistd.h>
31#include <getopt.h> 35#include <sys/stat.h>
32#include "busybox.h" 36#include "busybox.h"
33 37
34static int fileAction(const char *fileName, struct stat *statbuf, void* junk) 38static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
35{ 39{
36 if (!parse_mode((char *)junk, &(statbuf->st_mode))) 40 if (!bb_parse_mode((char *)junk, &(statbuf->st_mode)))
37 error_msg_and_die( "unknown mode: %s", (char *)junk); 41 bb_error_msg_and_die( "unknown mode: %s", (char *)junk);
38 if (chmod(fileName, statbuf->st_mode) == 0) 42 if (chmod(fileName, statbuf->st_mode) == 0)
39 return (TRUE); 43 return (TRUE);
40 perror(fileName); 44 bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */
41 return (FALSE); 45 return (FALSE);
42} 46}
43 47
44int chmod_main(int argc, char **argv) 48int chmod_main(int argc, char **argv)
45{ 49{
46 int opt; 50 int retval = EXIT_SUCCESS;
47 int recursiveFlag = FALSE; 51 int recursiveFlag = FALSE;
48 int modeind = 0; /* Index of the mode argument in `argv'. */ 52 int count;
49 char *smode; 53 char *smode;
50 static const char chmod_modes[] = "Rrwxstugoa,+-="; 54 char **p;
55 char *p0;
56 char opt = '-';
51 57
52 /* do normal option parsing */ 58 ++argv;
53 while (1) { 59 count = 0;
54 int thisind = optind ? optind : 1;
55 60
56 opt = getopt(argc, argv, chmod_modes); 61 for (p = argv ; *p ; p++) {
57 if (opt == EOF) 62 p0 = p[0];
58 break; 63 if (p0[0] == opt) {
59 smode = strchr(chmod_modes, opt); 64 if ((p0[1] == '-') && !p0[2]) {
60 if(smode == NULL) 65 opt = 0; /* Disable further option processing. */
61 show_usage(); 66 continue;
62 if(smode == chmod_modes) { /* 'R' */ 67 }
63 recursiveFlag = TRUE; 68 if (p0[1] == 'R') {
64 } else { 69 char *s = p0 + 2;
65 if (modeind != 0 && modeind != thisind) 70 while (*s == 'R') {
66 show_usage(); 71 ++s;
67 modeind = thisind; 72 }
73 if (*s) {
74 bb_show_usage();
75 }
76 recursiveFlag = TRUE;
77 continue;
78 }
79 if (count) {
80 bb_show_usage();
81 }
68 } 82 }
83 argv[count] = p0;
84 ++count;
69 } 85 }
70 86
71 if (modeind == 0) 87 argv[count] = NULL;
72 modeind = optind++;
73 88
74 opt = optind; 89 if (count < 2) {
75 if (opt >= argc) { 90 bb_show_usage();
76 error_msg_and_die(too_few_args);
77 } 91 }
78 92
79 smode = argv[modeind]; 93 smode = *argv;
94 ++argv;
95
80 /* Ok, ready to do the deed now */ 96 /* Ok, ready to do the deed now */
81 for (; opt < argc; opt++) { 97 do {
82 if (! recursive_action (argv[opt], recursiveFlag, FALSE, FALSE, fileAction, 98 if (! recursive_action (*argv, recursiveFlag, FALSE, FALSE,
83 fileAction, smode)) { 99 fileAction, fileAction, smode)) {
84 return EXIT_FAILURE; 100 retval = EXIT_FAILURE;
85 } 101 }
86 } 102 } while (*++argv);
87 return EXIT_SUCCESS; 103
104 return retval;
88} 105}
89 106
90/* 107/*