Commit aec508fa authored by Ramon Nou's avatar Ramon Nou Committed by Ramon Nou
Browse files

non-recursive follow_links with libc

parent 0d6e1588
Loading
Loading
Loading
Loading
+14 −17
Original line number Diff line number Diff line
@@ -112,16 +112,24 @@ match_components(const string& path, unsigned int& path_components,
    return matched;
}

static char*(*real_realpath) (const char* path, char* resolved_path) = nullptr;

string
follow_symlinks(const string& path) {
    struct stat st{};
    if(lstat(path.c_str(), &st) < 0) {
    auto res = syscall_no_intercept(SYS_lstat, path.c_str(), &st);
    if(res < 0) {
        LOG(DEBUG, "path \"{}\" does not exist", path);
        return path;
    }
    if(S_ISLNK(st.st_mode)) {
        auto link_resolved = ::unique_ptr<char[]>(new char[PATH_MAX]);
        if(realpath(path.c_str(), link_resolved.get()) == nullptr) {
	if (real_realpath == nullptr) {
		real_realpath = reinterpret_cast<char* (*) (const char* path, char* resolved_path)>(
                    dlsym(((void*) -1l), "realpath"));
	}

	if(real_realpath(path.c_str(), link_resolved.get()) == nullptr) {

            LOG(ERROR,
                "Failed to get realpath for link \"{}\". "
@@ -199,7 +207,6 @@ resolve_new(const string& path, bool resolve_last_link) {
        }
#endif
    }

   if(resolved.substr(0, CTX->mountdir().size()) == CTX->mountdir()) {
        resolved.erase(1, CTX->mountdir().size());
        LOG(DEBUG, "internal: \"{}\"", resolved);
@@ -209,19 +216,9 @@ resolve_new(const string& path, bool resolve_last_link) {
    if(resolved.empty()) {
        resolved.push_back(path::separator);
    }
    // TODO: redo
    auto real =
            reinterpret_cast<char* (*) (const char* path, char* resolved_path)>(
                    dlsym(((void*) -1l), "realpath"));
    auto link_resolved = ::unique_ptr<char[]>(new char[PATH_MAX]);
    if(real(path.c_str(), link_resolved.get()) == nullptr) {
        LOG(DEBUG, "nonresolved: \"{}\"", resolved);
        return make_pair(false, resolved);
    } else {
        resolved = link_resolved.get();
    LOG(DEBUG, "external: \"{}\"", resolved);
    return make_pair(false, resolved);
    }

}

/** Resolve path to its canonical representation