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