2007/11/28, Bernhard Fischer <[EMAIL PROTECTED]>:
> On Wed, Nov 28, 2007 at 09:52:09AM +0100, Roberto A. Foglietta wrote:
>
> >> $ ln -sf pippo pippa
> >> $ ./busybox readlink pippa
> >> pippo
> >> $ ./busybox readlink -f pippa; echo $?
> >> 1
>
> The big 'readlink -f /there/does_not_exist' does print the path (fully
> resolved "/there" plus all non-existing other components), though.
>

 Yes,  but it is nothing new because 1.2.2.1's readlink works in the
same manner.

 I recently posted a more complete readlink applet to toybox m-list
but it requires a little bit of love (test, size reduction, thinking
about some corner case). I do not think it could be used AS-IS for
busybox however I think would require not such effort to be integrated
in bb. Feel free to use it and if you like give a little credit to
toybox team because I had their support in developing that patch.

 Cheers,
-- 
/roberto
diff -pruN toybox-56034b162074/tests/readlink toybox/tests/readlink
--- toybox-56034b162074/tests/readlink	1970-01-01 01:00:00.000000000 +0100
+++ toybox/tests/readlink	2007-11-23 11:16:14.000000000 +0100
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+cd /tmp
+rm -rf toybox readlink pippo walrus thingy potato fruitbasket
+cd -
+
+touch /tmp/toybox
+ln -sf /tmp/toybox /tmp/readlink
+ln -sf /tmp/readlink /tmp/pippo
+ln -sf /tmp/walrus /tmp/thingy
+ln -sf /tmp/thingy /tmp/potato
+ln -s /tmp/potato /tmp/walrus
+mkdir /tmp/walrus
+ln -sf ../../../../.. /tmp/fruitbasket
+
+
+for j in "" "-e" "-m" "-f"; do for i in /tmp/pippo /tmp/plutino /tmp/thingy /tmp/walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; (./toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+pwd=$(pwd); cd /tmp
+
+for j in "" "-e" "-m" "-f"; do for i in pippo plutino thingy walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; ($pwd/toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+rm -rf toybox readlink pippo walrus thingy potato fruitbasket
+touch toybox
+ln -sf toybox readlink
+ln -sf readlink pippo
+ln -sf walrus thingy
+ln -sf thingy potato
+ln -s potato walrus
+mkdir walrus
+ln -sf ../../../../.. fruitbasket
+cd -
+
+for j in "" "-e" "-m" "-f"; do for i in /tmp/pippo /tmp/plutino /tmp/thingy /tmp/walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; (./toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+pwd=$(pwd); cd /tmp
+
+for j in "" "-e" "-m" "-f"; do for i in pippo plutino thingy walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; ($pwd/toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+cd - 
diff -pruN toybox-56034b162074/toys/Config.in toybox/toys/Config.in
--- toybox-56034b162074/toys/Config.in	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/Config.in	2007-11-22 12:14:31.000000000 +0100
@@ -238,20 +238,22 @@ config PWD
 
 config READLINK
 	bool "readlink"
-	default n
+	default y
 	help
 	  usage: readlink
 
 	  Show what a symbolic link points to.
 
-config READLINK_F
-	bool "readlink -f"
-	default n
+config READLINK_EM
+	bool "options -e, -f and -m"
+	default y
 	depends on READLINK
 	help
-	  usage: readlink [-f]
+	  usage: readlink [-e|-m|-f]
 
-	  -f	Show final location, including normal files and multiple symlinks.
+	  -m	Follow all symlinks to show final location.
+	  -e	Like -m, but only if each step exists. (Fail on broken link.)
+	  -f	Like -m, but check the existence only the last one.
 
 config SLEEP
 	bool "sleep"
diff -pruN toybox-56034b162074/toys/readlink.c toybox/toys/readlink.c
--- toybox-56034b162074/toys/readlink.c	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/readlink.c	2007-11-23 11:14:09.000000000 +0100
@@ -5,16 +5,74 @@
 // Note: Hardware in LINK_MAX as 127 since it was removed from glibc.
 
 #include "toys.h"
+#include <libgen.h>
 
 int readlink_main(void)
 {
+	struct stat st;
 	char *s = xreadlink(*toys.optargs);
+	if(!s) s = xabspath(*toys.optargs);
+	fprintf(stderr,"arg: %s, s: %s\n", *toys.optargs, s);
+	if(s[0] != '/' && *toys.optargs[0] == '/') {
+		char *t = xstrdup(*toys.optargs);
+		chdir(dirname(t));
+		fprintf(stderr,"t: %s\n", t);
+		if (CFG_TOYBOX_FREE) free(t);
+	}
+
+	if(CFG_READLINK_EM && toys.optflags) {	
+		char n = 0, *l = 0, *ol = s;
 
-	if (s) {
-		xputs(s);
+		ol = basename(s);
+		l = realpath(dirname(s), NULL);
+		if(!l) return 1;
+		snprintf(toybuf, sizeof(toybuf), "%s/%s", l, ol);
 		if (CFG_TOYBOX_FREE) free(s);
-		return 0;
+		s = xstrdup(toybuf);
+		ol = s;
+		fprintf(stderr,"s: %s\n", s);
+
+		do {
+			l = xreadlink(ol);
+			fprintf(stderr,"n: %d, l: %s, s: %s\n", n, l, s);
+			if(!l) break;
+			ol = xreadlink(l);
+			fprintf(stderr,"n: %d, ol: %s, s: %s\n", n, ol, s);
+		} while(++n < 99 && ol && strcmp(l, ol)); 
+
+		if(!l) {
+			if(ol != s) {
+				if (CFG_TOYBOX_FREE) 
+					free(s);
+				s = ol;
+			}
+		} else {
+			if (CFG_TOYBOX_FREE) {
+				if(!ol && ol != s)
+					free(ol);
+				free(s); 
+			}
+			s = l;
+		}
+
+		if (s[0] != '/') {
+			snprintf(toybuf, sizeof(toybuf), "%s/%s", xgetcwd(), s);
+			if (CFG_TOYBOX_FREE) free(s);
+			s = xabspath(toybuf);
+		}
+		
+		if (n >= 99 && (toys.optflags & 1)) {
+			if (CFG_TOYBOX_FREE) free(s);
+			s = xabspath(*toys.optargs);
+		} else 
+		if (n >= 99 || ((toys.optflags & 2) && lstat(s, &st))) {
+			return 1;
+		}
+	} else 
+	if(lstat(s, &st)) {
+		return 1;
 	}
 
-	return 1;
+	if(s) xputs(s);
+	return 0;
 }
diff -pruN toybox-56034b162074/toys/toylist.h toybox/toys/toylist.h
--- toybox-56034b162074/toys/toylist.h	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/toylist.h	2007-11-23 11:16:37.000000000 +0100
@@ -120,7 +120,7 @@ USE_MKE2FS(NEWTOY(mke2fs, MKE2FS_OPTSTRI
 USE_MKFIFO(NEWTOY(mkfifo, "<1m:", TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "+<1p", TOYFLAG_SBIN))
 USE_PWD(NEWTOY(pwd, NULL, TOYFLAG_BIN))
-USE_READLINK(NEWTOY(readlink, "<1f", TOYFLAG_BIN))
+USE_READLINK(NEWTOY(readlink, "<1" USE_READLINK_EM("fem"), TOYFLAG_BIN))
 USE_TOYSH(OLDTOY(sh, toysh, "c:i", TOYFLAG_BIN))
 USE_SLEEP(NEWTOY(sleep, "<1", TOYFLAG_BIN))
 USE_SYNC(NEWTOY(sync, NULL, TOYFLAG_BIN))
diff -pruN toybox-56034b162074/tests/readlink toybox/tests/readlink
--- toybox-56034b162074/tests/readlink	1970-01-01 01:00:00.000000000 +0100
+++ toybox/tests/readlink	2007-11-23 11:16:14.000000000 +0100
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+cd /tmp
+rm -rf toybox readlink pippo walrus thingy potato fruitbasket
+cd -
+
+touch /tmp/toybox
+ln -sf /tmp/toybox /tmp/readlink
+ln -sf /tmp/readlink /tmp/pippo
+ln -sf /tmp/walrus /tmp/thingy
+ln -sf /tmp/thingy /tmp/potato
+ln -s /tmp/potato /tmp/walrus
+mkdir /tmp/walrus
+ln -sf ../../../../.. /tmp/fruitbasket
+
+
+for j in "" "-e" "-m" "-f"; do for i in /tmp/pippo /tmp/plutino /tmp/thingy /tmp/walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; (./toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+pwd=$(pwd); cd /tmp
+
+for j in "" "-e" "-m" "-f"; do for i in pippo plutino thingy walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; ($pwd/toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+rm -rf toybox readlink pippo walrus thingy potato fruitbasket
+touch toybox
+ln -sf toybox readlink
+ln -sf readlink pippo
+ln -sf walrus thingy
+ln -sf thingy potato
+ln -s potato walrus
+mkdir walrus
+ln -sf ../../../../.. fruitbasket
+cd -
+
+for j in "" "-e" "-m" "-f"; do for i in /tmp/pippo /tmp/plutino /tmp/thingy /tmp/walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; (./toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+pwd=$(pwd); cd /tmp
+
+for j in "" "-e" "-m" "-f"; do for i in pippo plutino thingy walrus/../fruitbasket/usr/bin/ls; do echo DOING readlink $j $i; ($pwd/toybox readlink $j $i; echo $?) | tee /tmp/1; (readlink $j $i; echo $?) | tee /tmp/2; cmp /tmp/1 /tmp/2 || echo ERROR readlink $j $i; done; done
+
+cd - 
diff -pruN toybox-56034b162074/toys/Config.in toybox/toys/Config.in
--- toybox-56034b162074/toys/Config.in	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/Config.in	2007-11-22 12:14:31.000000000 +0100
@@ -238,20 +238,22 @@ config PWD
 
 config READLINK
 	bool "readlink"
-	default n
+	default y
 	help
 	  usage: readlink
 
 	  Show what a symbolic link points to.
 
-config READLINK_F
-	bool "readlink -f"
-	default n
+config READLINK_EM
+	bool "options -e, -f and -m"
+	default y
 	depends on READLINK
 	help
-	  usage: readlink [-f]
+	  usage: readlink [-e|-m|-f]
 
-	  -f	Show final location, including normal files and multiple symlinks.
+	  -m	Follow all symlinks to show final location.
+	  -e	Like -m, but only if each step exists. (Fail on broken link.)
+	  -f	Like -m, but check the existence only the last one.
 
 config SLEEP
 	bool "sleep"
diff -pruN toybox-56034b162074/toys/readlink.c toybox/toys/readlink.c
--- toybox-56034b162074/toys/readlink.c	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/readlink.c	2007-11-22 12:22:13.000000000 +0100
@@ -5,16 +5,69 @@
 // Note: Hardware in LINK_MAX as 127 since it was removed from glibc.
 
 #include "toys.h"
+#include <libgen.h>
 
 int readlink_main(void)
 {
+	struct stat st;
 	char *s = xreadlink(*toys.optargs);
+	if(!s) s = xabspath(*toys.optargs);
+	if(s[0] != '/' && *toys.optargs[0] == '/') {
+		char *t = xstrdup(*toys.optargs);
+		chdir(dirname(t));
+		if (CFG_TOYBOX_FREE) free(t);
+	}
+
+	if(CFG_READLINK_EM && toys.optflags) {	
+		char n = 0, *l = 0, *ol = s;
 
-	if (s) {
-		xputs(s);
+		ol = basename(s);
+		l = realpath(dirname(s), NULL);
+		if(!l) return 1;
+		snprintf(toybuf, sizeof(toybuf), "%s/%s", l, ol);
 		if (CFG_TOYBOX_FREE) free(s);
-		return 0;
+		s = xstrdup(toybuf);
+		ol = s;
+
+		do {
+			l = xreadlink(ol);
+			if(!l) break;
+			ol = xreadlink(l);
+		} while(++n < 99 && ol && strcmp(l, ol)); 
+
+		if(!l) {
+			if(ol != s) {
+				if (CFG_TOYBOX_FREE) 
+					free(s);
+				s = ol;
+			}
+		} else {
+			if (CFG_TOYBOX_FREE) {
+				if(!ol && ol != s)
+					free(ol);
+				free(s); 
+			}
+			s = l;
+		}
+
+		if (s[0] != '/') {
+			snprintf(toybuf, sizeof(toybuf), "%s/%s", xgetcwd(), s);
+			if (CFG_TOYBOX_FREE) free(s);
+			s = xabspath(toybuf);
+		}
+		
+		if (n >= 99 && (toys.optflags & 1)) {
+			if (CFG_TOYBOX_FREE) free(s);
+			s = xabspath(*toys.optargs);
+		} else 
+		if (n >= 99 || ((toys.optflags & 2) && lstat(s, &st))) {
+			return 1;
+		}
+	} else 
+	if(lstat(s, &st)) {
+		return 1;
 	}
 
-	return 1;
+	if(s) xputs(s);
+	return 0;
 }
diff -pruN toybox-56034b162074/toys/toylist.h toybox/toys/toylist.h
--- toybox-56034b162074/toys/toylist.h	2007-11-20 08:06:29.000000000 +0100
+++ toybox/toys/toylist.h	2007-11-23 11:16:37.000000000 +0100
@@ -120,7 +120,7 @@ USE_MKE2FS(NEWTOY(mke2fs, MKE2FS_OPTSTRI
 USE_MKFIFO(NEWTOY(mkfifo, "<1m:", TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "+<1p", TOYFLAG_SBIN))
 USE_PWD(NEWTOY(pwd, NULL, TOYFLAG_BIN))
-USE_READLINK(NEWTOY(readlink, "<1f", TOYFLAG_BIN))
+USE_READLINK(NEWTOY(readlink, "<1" USE_READLINK_EM("fem"), TOYFLAG_BIN))
 USE_TOYSH(OLDTOY(sh, toysh, "c:i", TOYFLAG_BIN))
 USE_SLEEP(NEWTOY(sleep, "<1", TOYFLAG_BIN))
 USE_SYNC(NEWTOY(sync, NULL, TOYFLAG_BIN))
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to