First it strips /sysroot and then finds common prefix aligned on slashes. Next it produces ../ for each slash found in common prefix and concatenates them with the rest of resolved link. Fixes RHBZ#604041 --- src/fuse.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/fuse.c b/src/fuse.c index 3fdb1d4..6c7eee1 100644 --- a/src/fuse.c +++ b/src/fuse.c @@ -386,7 +386,38 @@ mount_local_readlink (const char *path, char *buf, size_t size) if (len > size - 1) len = size - 1; - memcpy (buf, r, len); + buf[0] = '\0'; + size_t offset = 0; + if (STRPREFIX (r, "/sysroot")) { + offset = strlen ("/sysroot") + 1; + size_t i; + for (i = 0; (i < strlen (r+offset)) && (path[i] == r[i+offset-1]); i++); + /* Now i contains index where paths starts to differ + * (n.b. needs to be aligned on last slash). */ + + for (; path[i] != '/'; --i); + /* i is now aligned */ + + /* Count slashes in original path, so we can generate + * right amount of ../ */ + size_t j; int cnt = 0; + for (j = i+1; j < strlen (r+offset); j++) { + if (path[j] == '/') cnt++; + } + + /* For each slash create ../ in path */ + for (int z = 0; z < cnt; z++) { + strcat (buf, "../"); + } + + /* In addition to /sysroot ne need to remove common path + * aligned on slashes */ + offset += i; + } + + /* There might already be something in buf (such as ../) + * so let's concatenate the rest of path */ + strncat (buf, r + offset, len - offset + 1); buf[len] = '\0'; if (free_it) { -- 1.9.3