diff options
author | Paul Fox <pgf@brightstareng.com> | 2007-11-08 01:11:41 +0000 |
---|---|---|
committer | Paul Fox <pgf@brightstareng.com> | 2007-11-08 01:11:41 +0000 |
commit | 459a2ba1efa9b84bf12c2f5b8a23fd89912b47ea (patch) | |
tree | 5c69b3f763a62d9dd394c1a36bfcfc0f96c07060 /libbb/xreadlink.c | |
parent | 49cce2b8384d2b425a91785ebf155a692df6986c (diff) | |
download | busybox-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/xreadlink.c')
-rw-r--r-- | libbb/xreadlink.c | 45 |
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 | */ | ||
42 | char *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 | |||
35 | char *xmalloc_readlink_or_warn(const char *path) | 80 | char *xmalloc_readlink_or_warn(const char *path) |
36 | { | 81 | { |
37 | char *buf = xmalloc_readlink(path); | 82 | char *buf = xmalloc_readlink(path); |