From: Andrew Tridgell Date: Sun, 31 Mar 2002 05:01:05 +0000 (+0200) Subject: use realpath() to handle multiple levels of symlinks X-Git-Tag: v1.1~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b82aa4f7254dd1539534faffbe84983fe5d792f;p=thirdparty%2Fccache.git use realpath() to handle multiple levels of symlinks --- diff --git a/README b/README index 4baf89eab..8cd244bdf 100644 --- a/README +++ b/README @@ -151,9 +151,5 @@ please let me know. =================== Andrew Tridgell http://samba.org/~tridge/ +bugs@ccache.samba.org March 2002 - -PS: I get far too much email to answer, so don't be surprised if you -have a hard time getting hold of me. You might try the -#samba-technical IRC channel on irc.openprojects.net if you need me -quickly. diff --git a/ccache.c b/ccache.c index 265aa0c10..d4270124f 100644 --- a/ccache.c +++ b/ccache.c @@ -368,22 +368,19 @@ static void find_compiler(int argc, char **argv) lstat(fname, &st1) == 0 && stat(fname, &st2) == 0 && S_ISREG(st2.st_mode)) { - char buf[1024]; - int len; - /* if its a symlink then ensure it doesn't point at something called "ccache" */ if (S_ISLNK(st1.st_mode)) { - char *p; - len = readlink(fname, buf, sizeof(buf)); - if (len != -1 && len < (int)sizeof(buf)) { - buf[len] = 0; - p = basename(buf); + char *buf = x_realpath(fname); + if (buf) { + char *p = basename(buf); if (strcmp(p, MYNAME) == 0) { /* its a link to "ccache" ! */ free(p); + free(buf); continue; } + free(buf); free(p); } } diff --git a/ccache.h b/ccache.h index 354b47324..908bc30b4 100644 --- a/ccache.h +++ b/ccache.h @@ -18,6 +18,7 @@ #include #include #include +#include #define STATUS_NOTFOUND 3 #define STATUS_FATAL 4 @@ -76,6 +77,7 @@ char *dirname(char *s); int lock_fd(int fd); size_t file_size(struct stat *st); int safe_open(const char *fname); +char *x_realpath(const char *path); void stats_update(enum stats stat); void stats_zero(void); diff --git a/util.c b/util.c index 7ef5baee4..2a155d219 100644 --- a/util.c +++ b/util.c @@ -295,3 +295,33 @@ size_t value_units(const char *s) } return v; } + + +/* + a sane realpath() function, trying to cope with stupid path limits and + a broken API +*/ +char *x_realpath(const char *path) +{ + int maxlen; + char *ret, *p; +#ifdef PATH_MAX + maxlen = PATH_MAX; +#elif defined(MAXPATHLEN) + maxlen = MAXPATHLEN; +#elif defined(_PC_PATH_MAX) + maxlen = pathconf(path, _PC_PATH_MAX); +#endif + if (maxlen < 4096) maxlen = 4096; + + ret = x_malloc(maxlen); + + p = realpath(path, ret); + if (p) { + p = x_strdup(p); + free(ret); + return p; + } + free(ret); + return NULL; +}