diff options
author | Paul Fox <pgf@brightstareng.com> | 2007-11-08 20:00:36 +0000 |
---|---|---|
committer | Paul Fox <pgf@brightstareng.com> | 2007-11-08 20:00:36 +0000 |
commit | 599bbfbd9be0073c262319a120174fad5a60113e (patch) | |
tree | d1145b8f98fd138241c72ac4601389d748b5d580 | |
parent | abbd363261cf3a9b18e611c524f8103fb68f539b (diff) | |
download | busybox-w32-599bbfbd9be0073c262319a120174fad5a60113e.tar.gz busybox-w32-599bbfbd9be0073c262319a120174fad5a60113e.tar.bz2 busybox-w32-599bbfbd9be0073c262319a120174fad5a60113e.zip |
xmalloc_follow_symlinks() -- fix ELOOP issue with absolute paths,
return full path in cases where path doesn't resolve to a link.
change name to better differentiate from xmalloc_readlink().
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | libbb/update_passwd.c | 2 | ||||
-rw-r--r-- | libbb/xreadlink.c | 37 |
3 files changed, 24 insertions, 17 deletions
diff --git a/include/libbb.h b/include/libbb.h index 0170085cb..1adac8443 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -260,10 +260,10 @@ DIR *warn_opendir(const char *path); | |||
260 | 260 | ||
261 | /* UNUSED: char *xmalloc_realpath(const char *path); */ | 261 | /* UNUSED: char *xmalloc_realpath(const char *path); */ |
262 | char *xmalloc_readlink(const char *path); | 262 | char *xmalloc_readlink(const char *path); |
263 | char *xmalloc_readlink_follow(const char *path); | ||
264 | char *xmalloc_readlink_or_warn(const char *path); | 263 | char *xmalloc_readlink_or_warn(const char *path); |
265 | char *xrealloc_getcwd_or_warn(char *cwd); | 264 | char *xrealloc_getcwd_or_warn(char *cwd); |
266 | 265 | ||
266 | char *xmalloc_follow_symlinks(const char *path); | ||
267 | 267 | ||
268 | //TODO: signal(sid, f) is the same? then why? | 268 | //TODO: signal(sid, f) is the same? then why? |
269 | extern void sig_catch(int,void (*)(int)); | 269 | extern void sig_catch(int,void (*)(int)); |
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c index e99db40c0..d10e863c6 100644 --- a/libbb/update_passwd.c +++ b/libbb/update_passwd.c | |||
@@ -52,7 +52,7 @@ int update_passwd(const char *filename, const char *username, | |||
52 | int cnt = 0; | 52 | int cnt = 0; |
53 | int ret = -1; /* failure */ | 53 | int ret = -1; /* failure */ |
54 | 54 | ||
55 | filename = xmalloc_readlink_follow(filename); | 55 | filename = xmalloc_follow_symlinks(filename); |
56 | if (filename == NULL) | 56 | if (filename == NULL) |
57 | return -1; | 57 | return -1; |
58 | 58 | ||
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index f7948cbf3..a5f7eb8be 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -33,13 +33,16 @@ char *xmalloc_readlink(const char *path) | |||
33 | } | 33 | } |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * this routine is not the same as realpath(), which canonicalizes | 36 | * this routine is not the same as realpath(), which |
37 | * the given path completely. this routine only follows trailing | 37 | * canonicalizes the given path completely. this routine only |
38 | * symlinks until a real file is reached, and returns its name. | 38 | * follows trailing symlinks until a real file is reached, and |
39 | * intermediate symlinks are not expanded. as above, a malloced | 39 | * returns its name. if the path ends in a dangling link, or if |
40 | * char* is returned, which must be freed. | 40 | * the target doesn't exist, the path is returned in any case. |
41 | * intermediate symlinks in the path are not expanded -- only | ||
42 | * those at the tail. | ||
43 | * a malloced char* is returned, which must be freed by the caller. | ||
41 | */ | 44 | */ |
42 | char *xmalloc_readlink_follow(const char *path) | 45 | char *xmalloc_follow_symlinks(const char *path) |
43 | { | 46 | { |
44 | char *buf; | 47 | char *buf; |
45 | char *lpc; | 48 | char *lpc; |
@@ -47,23 +50,27 @@ char *xmalloc_readlink_follow(const char *path) | |||
47 | int bufsize; | 50 | int bufsize; |
48 | int looping = MAXSYMLINKS + 1; | 51 | int looping = MAXSYMLINKS + 1; |
49 | 52 | ||
50 | linkpath = xstrdup(path); | 53 | buf = xstrdup(path); |
51 | goto jump_in; | 54 | goto jump_in; |
52 | 55 | ||
53 | while (1) { | 56 | while (1) { |
54 | if (!--looping) { | 57 | |
55 | free(linkpath); | ||
56 | free(buf); | ||
57 | return NULL; | ||
58 | } | ||
59 | linkpath = xmalloc_readlink(buf); | 58 | linkpath = xmalloc_readlink(buf); |
60 | if (!linkpath) { | 59 | if (!linkpath) { |
61 | if (errno == EINVAL) /* not a symlink */ | 60 | /* not a symlink, or doesn't exist */ |
61 | if (errno == EINVAL || errno == ENOENT) | ||
62 | return buf; | 62 | return buf; |
63 | free(buf); | 63 | free(buf); |
64 | return NULL; | 64 | return NULL; |
65 | } | 65 | } |
66 | if (linkpath[0] != '/') { | 66 | |
67 | if (!--looping) { | ||
68 | free(linkpath); | ||
69 | free(buf); | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | if (*linkpath != '/') { | ||
67 | bufsize += strlen(linkpath); | 74 | bufsize += strlen(linkpath); |
68 | buf = xrealloc(buf, bufsize); | 75 | buf = xrealloc(buf, bufsize); |
69 | lpc = bb_get_last_path_component_strip(buf); | 76 | lpc = bb_get_last_path_component_strip(buf); |
@@ -71,8 +78,8 @@ char *xmalloc_readlink_follow(const char *path) | |||
71 | free(linkpath); | 78 | free(linkpath); |
72 | } else { | 79 | } else { |
73 | free(buf); | 80 | free(buf); |
74 | jump_in: | ||
75 | buf = linkpath; | 81 | buf = linkpath; |
82 | jump_in: | ||
76 | bufsize = strlen(buf) + 1; | 83 | bufsize = strlen(buf) + 1; |
77 | } | 84 | } |
78 | } | 85 | } |