diff options
author | antirez <antirez@gmail.com> | 2013-07-02 11:56:52 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2013-07-02 11:56:52 +0200 |
commit | 0781ad68991171360becfc472c492861ba119c01 (patch) | |
tree | 08de1c1f8ff0d0f464da9431f19f3588c12d9fa9 /src/util.c | |
parent | de9a221749b10af3a408385056bb51255ca860f6 (diff) | |
download | redis-0781ad68991171360becfc472c492861ba119c01.tar.gz |
getAbsolutePath() moved into utils.c
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c index 24f936b66..4b77e9fef 100644 --- a/src/util.c +++ b/src/util.c @@ -405,6 +405,58 @@ void getRandomHexChars(char *p, unsigned int len) { fclose(fp); } +/* Given the filename, return the absolute path as an SDS string, or NULL + * if it fails for some reason. Note that "filename" may be an absolute path + * already, this will be detected and handled correctly. + * + * The function does not try to normalize everything, but only the obvious + * case of one or more "../" appearning at the start of "filename" + * relative path. */ +sds getAbsolutePath(char *filename) { + char cwd[1024]; + sds abspath; + sds relpath = sdsnew(filename); + + relpath = sdstrim(relpath," \r\n\t"); + if (relpath[0] == '/') return relpath; /* Path is already absolute. */ + + /* If path is relative, join cwd and relative path. */ + if (getcwd(cwd,sizeof(cwd)) == NULL) { + sdsfree(relpath); + return NULL; + } + abspath = sdsnew(cwd); + if (sdslen(abspath) && abspath[sdslen(abspath)-1] != '/') + abspath = sdscat(abspath,"/"); + + /* At this point we have the current path always ending with "/", and + * the trimmed relative path. Try to normalize the obvious case of + * trailing ../ elements at the start of the path. + * + * For every "../" we find in the filename, we remove it and also remove + * the last element of the cwd, unless the current cwd is "/". */ + while (sdslen(relpath) >= 3 && + relpath[0] == '.' && relpath[1] == '.' && relpath[2] == '/') + { + relpath = sdsrange(relpath,3,-1); + if (sdslen(abspath) > 1) { + char *p = abspath + sdslen(abspath)-2; + int trimlen = 1; + + while(*p != '/') { + p--; + trimlen++; + } + abspath = sdsrange(abspath,0,-(trimlen+1)); + } + } + + /* Finally glue the two parts together. */ + abspath = sdscatsds(abspath,relpath); + sdsfree(relpath); + return abspath; +} + #ifdef UTIL_TEST_MAIN #include <assert.h> |