summaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorPaul Fox <pgf@brightstareng.com>2007-11-08 01:11:41 +0000
committerPaul Fox <pgf@brightstareng.com>2007-11-08 01:11:41 +0000
commit459a2ba1efa9b84bf12c2f5b8a23fd89912b47ea (patch)
tree5c69b3f763a62d9dd394c1a36bfcfc0f96c07060 /libbb
parent49cce2b8384d2b425a91785ebf155a692df6986c (diff)
downloadbusybox-w32-459a2ba1efa9b84bf12c2f5b8a23fd89912b47ea.tar.gz
busybox-w32-459a2ba1efa9b84bf12c2f5b8a23fd89912b47ea.tar.bz2
busybox-w32-459a2ba1efa9b84bf12c2f5b8a23fd89912b47ea.zip
new xmalloc_readlink_follow() routine to fully expand trailing symlinks
to get to a "real" file (or directory).
Diffstat (limited to 'libbb')
-rw-r--r--libbb/xreadlink.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 98b795f56..2f6b1e237 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -32,6 +32,51 @@ char *xmalloc_readlink(const char *path)
32 return buf; 32 return buf;
33} 33}
34 34
35/*
36 * this routine is not the same as realpath(), which canonicalizes
37 * the given path completely. this routine only follows trailing
38 * symlinks until a real file is reached, and returns its name.
39 * intermediate symlinks are not expanded. as above, a malloced
40 * char* is returned, which must be freed.
41 */
42char *xmalloc_readlink_follow(const char *path)
43{
44 char *buf = NULL, *lpc, *linkpath;
45 int bufsize;
46 smallint looping = 0;
47
48 buf = strdup(path);
49 bufsize = strlen(path) + 1;
50
51 while(1) {
52 linkpath = xmalloc_readlink(buf);
53 if (!linkpath) {
54 if (errno == EINVAL) /* not a symlink */
55 return buf;
56 free(buf);
57 return NULL;
58 }
59
60 if (*linkpath == '/') {
61 free(buf);
62 buf = linkpath;
63 bufsize = strlen(linkpath) + 1;
64 } else {
65 bufsize += strlen(linkpath);
66 if (looping++ > MAXSYMLINKS) {
67 free(linkpath);
68 free(buf);
69 return NULL;
70 }
71 buf = xrealloc(buf, bufsize);
72 lpc = bb_get_last_path_component_strip(buf);
73 strcpy(lpc, linkpath);
74 free(linkpath);
75 }
76 }
77
78}
79
35char *xmalloc_readlink_or_warn(const char *path) 80char *xmalloc_readlink_or_warn(const char *path)
36{ 81{
37 char *buf = xmalloc_readlink(path); 82 char *buf = xmalloc_readlink(path);