svn commit: trunk/busybox: include libbb

pgf at busybox.net pgf at busybox.net
Wed Nov 7 17:11:42 PST 2007


Author: pgf
Date: 2007-11-07 17:11:41 -0800 (Wed, 07 Nov 2007)
New Revision: 20382

Log:
new xmalloc_readlink_follow() routine to fully expand trailing symlinks
to get to a "real" file (or directory).


Modified:
   trunk/busybox/include/libbb.h
   trunk/busybox/libbb/xreadlink.c


Changeset:
Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2007-11-07 20:35:37 UTC (rev 20381)
+++ trunk/busybox/include/libbb.h	2007-11-08 01:11:41 UTC (rev 20382)
@@ -260,6 +260,7 @@
 
 /* UNUSED: char *xmalloc_realpath(const char *path); */
 char *xmalloc_readlink(const char *path);
+char *xmalloc_readlink_follow(const char *path);
 char *xmalloc_readlink_or_warn(const char *path);
 char *xrealloc_getcwd_or_warn(char *cwd);
 

Modified: trunk/busybox/libbb/xreadlink.c
===================================================================
--- trunk/busybox/libbb/xreadlink.c	2007-11-07 20:35:37 UTC (rev 20381)
+++ trunk/busybox/libbb/xreadlink.c	2007-11-08 01:11:41 UTC (rev 20382)
@@ -32,6 +32,51 @@
 	return buf;
 }
 
+/*
+ * this routine is not the same as realpath(), which canonicalizes
+ * the given path completely.  this routine only follows trailing
+ * symlinks until a real file is reached, and returns its name. 
+ * intermediate symlinks are not expanded.  as above, a malloced
+ * char* is returned, which must be freed.
+ */
+char *xmalloc_readlink_follow(const char *path)
+{
+	char *buf = NULL, *lpc, *linkpath;
+	int bufsize;
+	smallint looping = 0;
+
+	buf = strdup(path);
+	bufsize = strlen(path) + 1;
+
+	while(1) {
+		linkpath = xmalloc_readlink(buf);
+		if (!linkpath) {
+			if (errno == EINVAL) /* not a symlink */
+				return buf;
+			free(buf);
+			return NULL;
+		} 
+
+		if (*linkpath == '/') {
+			free(buf);
+			buf = linkpath;
+			bufsize = strlen(linkpath) + 1;
+		} else {
+			bufsize += strlen(linkpath);
+			if (looping++ > MAXSYMLINKS) {
+				free(linkpath);
+				free(buf);
+				return NULL;
+			}
+			buf = xrealloc(buf, bufsize);
+			lpc = bb_get_last_path_component_strip(buf);
+			strcpy(lpc, linkpath);
+			free(linkpath);
+		}
+	}
+
+}
+
 char *xmalloc_readlink_or_warn(const char *path)
 {
 	char *buf = xmalloc_readlink(path);



More information about the busybox-cvs mailing list