tftp: optional tftp-hpa compat
[oweals/busybox.git] / coreutils / chmod.c
index 9a73218a1a324daa9c71fd0526da9c104a445a0c..27e9b6b863ebfeeae8c56c6ae7b92fe125602244 100644 (file)
@@ -7,20 +7,54 @@
  * Reworked by (C) 2002 Vladimir Oleynik <dzo@simtreas.ru>
  *  to correctly parse '-rwxgoa'
  *
- * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
+//config:config CHMOD
+//config:      bool "chmod (5.5 kb)"
+//config:      default y
+//config:      help
+//config:      chmod is used to change the access permission of files.
+
+//applet:IF_CHMOD(APPLET_NOEXEC(chmod, chmod, BB_DIR_BIN, BB_SUID_DROP, chmod))
+
+//kbuild:lib-$(CONFIG_CHMOD) += chmod.o
 
 /* BB_AUDIT SUSv3 compliant */
 /* BB_AUDIT GNU defects - unsupported long options. */
 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
 
-#include "busybox.h"
+//usage:#define chmod_trivial_usage
+//usage:       "[-R"IF_DESKTOP("cvf")"] MODE[,MODE]... FILE..."
+//usage:#define chmod_full_usage "\n\n"
+//usage:       "Each MODE is one or more of the letters ugoa, one of the\n"
+//usage:       "symbols +-= and one or more of the letters rwxst\n"
+//usage:     "\n       -R      Recurse"
+//usage:       IF_DESKTOP(
+//usage:     "\n       -c      List changed files"
+//usage:     "\n       -v      List all files"
+//usage:     "\n       -f      Hide errors"
+//usage:       )
+//usage:
+//usage:#define chmod_example_usage
+//usage:       "$ ls -l /tmp/foo\n"
+//usage:       "-rw-rw-r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n"
+//usage:       "$ chmod u+x /tmp/foo\n"
+//usage:       "$ ls -l /tmp/foo\n"
+//usage:       "-rwxrw-r--    1 root     root            0 Apr 12 18:25 /tmp/foo*\n"
+//usage:       "$ chmod 444 /tmp/foo\n"
+//usage:       "$ ls -l /tmp/foo\n"
+//usage:       "-r--r--r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n"
+
+#include "libbb.h"
+
+/* This is a NOEXEC applet. Be very careful! */
+
 
 #define OPT_RECURSE (option_mask32 & 1)
-#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 2) SKIP_DESKTOP(0))
-#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0))
-#define OPT_QUIET   (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0))
-#define OPT_STR     "R" USE_DESKTOP("vcf")
+#define OPT_VERBOSE (IF_DESKTOP(option_mask32 & 2) IF_NOT_DESKTOP(0))
+#define OPT_CHANGED (IF_DESKTOP(option_mask32 & 4) IF_NOT_DESKTOP(0))
+#define OPT_QUIET   (IF_DESKTOP(option_mask32 & 8) IF_NOT_DESKTOP(0))
+#define OPT_STR     "R" IF_DESKTOP("vcf")
 
 /* coreutils:
  * chmod never changes the permissions of symbolic links; the chmod
@@ -31,7 +65,7 @@
  * symbolic links encountered during recursive directory traversals.
  */
 
-static int fileAction(const char *fileName, struct stat *statbuf, void* param, int depth)
+static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void* param, int depth)
 {
        mode_t newmode;
 
@@ -44,10 +78,10 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* param, i
                if (S_ISLNK(statbuf->st_mode))
                        return TRUE;
        }
-       newmode = statbuf->st_mode;
 
-       if (!bb_parse_mode((char *)param, &newmode))
-               bb_error_msg_and_die("invalid mode: %s", (char *)param);
+       newmode = bb_parse_mode((char *)param, statbuf->st_mode);
+       if (newmode == (mode_t)-1)
+               bb_error_msg_and_die("invalid mode '%s'", (char *)param);
 
        if (chmod(fileName, newmode) == 0) {
                if (OPT_VERBOSE
@@ -60,12 +94,12 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* param, i
        }
  err:
        if (!OPT_QUIET)
-               bb_perror_msg("%s", fileName);
+               bb_simple_perror_msg(fileName);
        return FALSE;
 }
 
-int chmod_main(int argc, char **argv);
-int chmod_main(int argc, char **argv)
+int chmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int chmod_main(int argc UNUSED_PARAM, char **argv)
 {
        int retval = EXIT_SUCCESS;
        char *arg, **argp;
@@ -89,8 +123,7 @@ int chmod_main(int argc, char **argv)
        }
 
        /* Parse options */
-       opt_complementary = "-2";
-       getopt32(argc, argv, ("-"OPT_STR) + 1); /* Reuse string */
+       getopt32(argv, "^" OPT_STR "\0" "-2");
        argv += optind;
 
        /* Restore option-like mode if needed */