diff -ru bindfs-1.12.3_orig/src/bindfs.c bindfs-1.12.3/src/bindfs.c --- bindfs-1.12.3_orig/src/bindfs.c 2013-09-23 22:59:23.000000000 +0200 +++ bindfs-1.12.3/src/bindfs.c 2013-11-09 02:31:54.000000000 +0100 @@ -132,7 +132,7 @@ int ctime_from_mtime; int hide_hard_links; - + int follow_symbolic_links; } settings; @@ -241,6 +241,13 @@ return path; } +static int lstat_wrap(const char *path, struct stat *stbuf) +{ + if (settings.follow_symbolic_links) + return stat(path, stbuf); + return lstat(path, stbuf); +} + static int getattr_common(const char *procpath, struct stat *stbuf) { struct fuse_context *fc = fuse_get_context(); @@ -309,7 +316,7 @@ path_copy = strdup(path); dir_path = my_dirname(path_copy); - if (lstat(dir_path, &stbuf) != -1 && stbuf.st_mode & S_ISGID) + if (lstat_wrap(dir_path, &stbuf) != -1 && stbuf.st_mode & S_ISGID) file_group = -1; free(path_copy); } else { @@ -362,7 +369,7 @@ { path = process_path(path); - if (lstat(path, stbuf) == -1) + if (lstat_wrap(path, stbuf) == -1) return -errno; return getattr_common(path, stbuf); } @@ -444,9 +451,13 @@ break; } - memset(&st, 0, sizeof(st)); - st.st_ino = de->d_ino; - st.st_mode = de->d_type << 12; + if (settings.follow_symbolic_links) { + lstat_wrap(de->d_name, &st); + } else { + memset(&st, 0, sizeof(st)); + st.st_ino = de->d_ino; + st.st_mode = de->d_type << 12; + } if (filler(buf, de->d_name, &st, telldir(dp))) break; } @@ -586,7 +597,7 @@ if (settings.chmod_allow_x) { /* Get the old permission bits and see which bits would change. */ - if (lstat(path, &st) == -1) + if (lstat_wrap(path, &st) == -1) return -errno; if (S_ISREG(st.st_mode)) { @@ -981,6 +992,7 @@ " --ctime-from-mtime Read file properties' change time\n" " from file content modification time.\n" " --hide-hard-links Always report a hard link count of 1.\n" + " --follow-symbolic-links Follow (hide) symbolic links.\n" " --multithreaded Enable multithreaded mode. See man page\n" " for security issue with current implementation.\n" "\n" @@ -1019,6 +1031,7 @@ OPTKEY_REALISTIC_PERMISSIONS, OPTKEY_CTIME_FROM_MTIME, OPTKEY_HIDE_HARD_LINKS, + OPTKEY_FOLLOW_SYMBOLIC_LINKS, OPTKEY_MULTITHREADED }; @@ -1100,6 +1113,9 @@ case OPTKEY_HIDE_HARD_LINKS: settings.hide_hard_links = 1; return 0; + case OPTKEY_FOLLOW_SYMBOLIC_LINKS: + settings.follow_symbolic_links = 1; + return 0; case OPTKEY_NONOPTION: if (!settings.mntsrc) { @@ -1400,6 +1416,7 @@ OPT2("--realistic-permissions", "realistic-permissions", OPTKEY_REALISTIC_PERMISSIONS), OPT2("--ctime-from-mtime", "ctime-from-mtime", OPTKEY_CTIME_FROM_MTIME), OPT2("--hide-hard-links", "hide-hard-links", OPTKEY_HIDE_HARD_LINKS), + OPT2("--follow-symbolic-links", "follow-symbolic-links", OPTKEY_FOLLOW_SYMBOLIC_LINKS), OPT_OFFSET2("--multithreaded", "multithreaded", multithreaded, -1), FUSE_OPT_END }; @@ -1436,6 +1453,7 @@ settings.realistic_permissions = 0; settings.ctime_from_mtime = 0; settings.hide_hard_links = 0; + settings.follow_symbolic_links = 0; atexit(&atexit_func); /* Parse options */