svn commit: trunk/busybox/coreutils

vda at busybox.net vda at busybox.net
Thu Mar 8 13:37:46 UTC 2007


Author: vda
Date: 2007-03-08 05:37:43 -0800 (Thu, 08 Mar 2007)
New Revision: 18036

Log:
chown: support -H -L -P if ENABLE_DESKTOP
chmod: cosmetic fixes
expr: smallish help for dumb compilers


Modified:
   trunk/busybox/coreutils/chmod.c
   trunk/busybox/coreutils/chown.c
   trunk/busybox/coreutils/expr.c


Changeset:
Modified: trunk/busybox/coreutils/chmod.c
===================================================================
--- trunk/busybox/coreutils/chmod.c	2007-03-08 08:55:52 UTC (rev 18035)
+++ trunk/busybox/coreutils/chmod.c	2007-03-08 13:37:43 UTC (rev 18036)
@@ -118,10 +118,12 @@
 /*
 Security: chmod is too important and too subtle.
 This is a test script (busybox chmod versus coreutils).
-Run it in empty dir. Probably requires bash.
+Run it in empty directory.
 
 #!/bin/sh
-function create() {
+t1="/tmp/busybox chmod"
+t2="/usr/bin/chmod"
+create() {
     rm -rf $1; mkdir $1
     (
     cd $1 || exit 1
@@ -134,17 +136,16 @@
     ln -s ../up dir/up
     )
 }
-function tst() {
+tst() {
     (cd test1; $t1 $1)
     (cd test2; $t2 $1)
     (cd test1; ls -lR) >out1
     (cd test2; ls -lR) >out2
     echo "chmod $1" >out.diff
     if ! diff -u out1 out2 >>out.diff; then exit 1; fi
-    mv out.diff out1.diff
+    rm out.diff
 }
-t1="/tmp/busybox chmod"
-t2="/usr/bin/chmod"
+echo "If script produced 'out.diff' file, then at least one testcase failed"
 create test1; create test2
 tst "a+w file"
 tst "a-w dir"

Modified: trunk/busybox/coreutils/chown.c
===================================================================
--- trunk/busybox/coreutils/chown.c	2007-03-08 08:55:52 UTC (rev 18035)
+++ trunk/busybox/coreutils/chown.c	2007-03-08 13:37:43 UTC (rev 18036)
@@ -17,25 +17,31 @@
 
 static int (*chown_func)(const char *, uid_t, gid_t) = chown;
 
+#define OPT_STR     ("Rh" USE_DESKTOP("vcfLHP"))
+#define BIT_RECURSE 1
+#define BIT_NODEREF 2
+#define BIT_TRAVERSE 0x20
+#define BIT_TRAVERSETOP (0x20|0x40)
 #define OPT_RECURSE (option_mask32 & 1)
 #define OPT_NODEREF (option_mask32 & 2)
-#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0))
-#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0))
+#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 0x04) SKIP_DESKTOP(0))
+#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 0x08) SKIP_DESKTOP(0))
 #define OPT_QUIET   (USE_DESKTOP(option_mask32 & 0x10) SKIP_DESKTOP(0))
-#define OPT_STR     ("Rh" USE_DESKTOP("vcf"))
-
-/* TODO:
+/* POSIX options
+ * -L traverse every symbolic link to a directory encountered
  * -H if a command line argument is a symbolic link to a directory, traverse it
- * -L traverse every symbolic link to a directory encountered
  * -P do not traverse any symbolic links (default)
- */
+ * We do not conform to the following:
+ * "Specifying more than one of -H, -L, and -P is not an error.
+ * The last option specified shall determine the behavior of the utility." */
+/* -L */
+#define OPT_TRAVERSE    (USE_DESKTOP(option_mask32 & BIT_TRAVERSE) SKIP_DESKTOP(0))
+/* -H or -L */
+#define OPT_TRAVERSETOP (USE_DESKTOP(option_mask32 & BIT_TRAVERSETOP) SKIP_DESKTOP(0))
 
 static int fileAction(const char *fileName, struct stat *statbuf,
 		void ATTRIBUTE_UNUSED *junk, int depth)
 {
-	// TODO: -H/-L/-P
-	// if (depth ... && S_ISLNK(statbuf->st_mode)) ....
-
 	if (!chown_func(fileName,
 			(ugid.uid == (uid_t)-1) ? statbuf->st_uid : ugid.uid,
 			(ugid.gid == (gid_t)-1) ? statbuf->st_gid : ugid.gid)
@@ -62,16 +68,31 @@
 	getopt32(argc, argv, OPT_STR);
 	argv += optind;
 
-	if (OPT_NODEREF) chown_func = lchown;
+	/* This matches coreutils behavior (almost - see below) */
+	if (OPT_NODEREF
+	    /* || (OPT_RECURSE && !OPT_TRAVERSETOP): */
+	    USE_DESKTOP( || (option_mask32 & (BIT_RECURSE|BIT_TRAVERSETOP)) == BIT_RECURSE)
+	) {
+		chown_func = lchown;
+	}
 
 	parse_chown_usergroup_or_die(&ugid, argv[0]);
 
 	/* Ok, ready to do the deed now */
 	argv++;
 	do {
-		if (!recursive_action(*argv,
-				OPT_RECURSE,	// recurse
-				FALSE,          // follow links: TODO: -H/-L/-P
+		char *arg = *argv;
+
+		if (OPT_TRAVERSETOP) {
+			/* resolves symlink (even recursive) */
+			arg = xmalloc_realpath(arg);
+			if (!arg)
+				continue;
+		}
+
+		if (!recursive_action(arg,
+				OPT_RECURSE,    // recurse
+				OPT_TRAVERSE,   // follow links if -L
 				FALSE,          // depth first
 				fileAction,     // file action
 				fileAction,     // dir action
@@ -80,7 +101,66 @@
 		) {
 			retval = EXIT_FAILURE;
 		}
+
+		if (OPT_TRAVERSETOP)
+			free(arg);
 	} while (*++argv);
 
 	return retval;
 }
+
+/*
+Testcase. Run in empty directory.
+
+#!/bin/sh
+t1="/tmp/busybox chown"
+t2="/usr/bin/chown"
+create() {
+    rm -rf $1; mkdir $1
+    (
+    cd $1 || exit 1
+    mkdir dir dir2
+    >up
+    >file
+    >dir/file
+    >dir2/file
+    ln -s dir linkdir
+    ln -s file linkfile
+    ln -s ../up dir/linkup
+    ln -s ../dir2 dir/linkupdir2
+    )
+    chown -R 0:0 $1
+}
+tst() {
+    create test1
+    create test2
+    (cd test1; $t1 $1)
+    (cd test2; $t2 $1)
+    (cd test1; ls -lnR) >out1
+    (cd test2; ls -lnR) >out2
+    echo "chown $1" >out.diff
+    if ! diff -u out1 out2 >>out.diff; then exit 1; fi
+    rm out.diff
+}
+tst_for_each() {
+    tst "$1 1:1 file"
+    tst "$1 1:1 dir"
+    tst "$1 1:1 linkdir"
+    tst "$1 1:1 linkfile"
+}
+echo "If script produced 'out.diff' file, then at least one testcase failed"
+# These match coreutils 6.8:
+tst_for_each ""
+tst_for_each "-R"
+tst_for_each "-RP"
+tst_for_each "-RL"
+tst_for_each "-RH"
+tst_for_each "-h"
+tst_for_each "-hR"
+tst_for_each "-hRP"
+# Below: with "chown linkdir" coreutils 6.8 will chown linkdir _target_,
+# we lchown _the link_. I believe we are "more correct".
+#tst_for_each "-hRL"
+#tst_for_each "-hRH"
+
+*/

Modified: trunk/busybox/coreutils/expr.c
===================================================================
--- trunk/busybox/coreutils/expr.c	2007-03-08 08:55:52 UTC (rev 18035)
+++ trunk/busybox/coreutils/expr.c	2007-03-08 13:37:43 UTC (rev 18036)
@@ -136,8 +136,8 @@
 {
 	if (v->type == integer)
 		return v->u.i == 0;
-	else				/* string: */
-		return v->u.s[0] == '\0' || LONE_CHAR(v->u.s, '0');
+	/* string: */
+	return v->u.s[0] == '\0' || LONE_CHAR(v->u.s, '0');
 }
 
 /* Coerce V to a string value (can't fail).  */
@@ -194,16 +194,16 @@
 		cmpval = l->u.i - r->u.i;
 	if (op == '<')
 		return cmpval < 0;
-	else if (op == ('L' + 'E'))
+	if (op == ('L' + 'E'))
 		return cmpval <= 0;
-	else if (op == '=')
+	if (op == '=')
 		return cmpval == 0;
-	else if (op == '!')
+	if (op == '!')
 		return cmpval != 0;
-	else if (op == '>')
+	if (op == '>')
 		return cmpval > 0;
-	else				/* >= */
-		return cmpval >= 0;
+	/* >= */
+	return cmpval >= 0;
 }
 
 /* The arithmetic operator handling functions.  */




More information about the busybox-cvs mailing list