bool CNFSDirectory::ResolveSymlink( const CStdString &dirName, struct nfsdirent *dirent, CURL &resolvedUrl) { CSingleLock lock(gNfsConnection); int ret = 0; bool retVal = true; CStdString fullpath = dirName; char resolvedLink[MAX_PATH]; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(dirent->name); resolvedUrl.Reset(); resolvedUrl.SetPort(2049); resolvedUrl.SetProtocol("nfs"); resolvedUrl.SetHostName(gNfsConnection.GetConnectedIp()); ret = gNfsConnection.GetImpl()->nfs_readlink(gNfsConnection.GetNfsContext(), fullpath.c_str(), resolvedLink, MAX_PATH); if(ret == 0) { struct stat tmpBuffer = {0}; fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(resolvedLink); //special case - if link target is absolute it could be even another export //intervolume symlinks baby ... if(resolvedLink[0] == '/') { //use the special stat function for using an extra context //because we are inside of a dir traversation //and just can't change the global nfs context here //without destroying something... fullpath = resolvedLink; resolvedUrl.SetFileName(fullpath); ret = gNfsConnection.stat(resolvedUrl, &tmpBuffer); } else { ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), fullpath.c_str(), &tmpBuffer); resolvedUrl.SetFileName(gNfsConnection.GetConnectedExport() + fullpath); } if (ret != 0) { CLog::Log(LOGERROR, "NFS: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false;; } else { dirent->inode = tmpBuffer.st_ino; dirent->mode = tmpBuffer.st_mode; dirent->size = tmpBuffer.st_size; dirent->atime.tv_sec = tmpBuffer.st_atime; dirent->mtime.tv_sec = tmpBuffer.st_mtime; dirent->ctime.tv_sec = tmpBuffer.st_ctime; //map stat mode to nf3type if(S_ISBLK(tmpBuffer.st_mode)){ dirent->type = NF3BLK; } else if(S_ISCHR(tmpBuffer.st_mode)){ dirent->type = NF3CHR; } else if(S_ISDIR(tmpBuffer.st_mode)){ dirent->type = NF3DIR; } else if(S_ISFIFO(tmpBuffer.st_mode)){ dirent->type = NF3FIFO; } else if(S_ISREG(tmpBuffer.st_mode)){ dirent->type = NF3REG; } else if(S_ISLNK(tmpBuffer.st_mode)){ dirent->type = NF3LNK; } else if(S_ISSOCK(tmpBuffer.st_mode)){ dirent->type = NF3SOCK; } } } else { CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false; } return retVal; }