static int streams_xattr_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { NTSTATUS status; int result = -1; char *xattr_name = NULL; if (!is_ntfs_stream_smb_fname(smb_fname)) { return SMB_VFS_NEXT_STAT(handle, smb_fname); } /* Note if lp_posix_paths() is true, we can never * get here as is_ntfs_stream_smb_fname() is * always false. So we never need worry about * not following links here. */ /* If the default stream is requested, just stat the base file. */ if (is_ntfs_default_stream_smb_fname(smb_fname)) { return streams_xattr_stat_base(handle, smb_fname, true); } /* Populate the stat struct with info from the base file. */ if (streams_xattr_stat_base(handle, smb_fname, true) == -1) { return -1; } /* Derive the xattr name to lookup. */ status = streams_xattr_get_name(handle, talloc_tos(), smb_fname->stream_name, &xattr_name); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } /* Augment the base file's stat information before returning. */ smb_fname->st.st_ex_size = get_xattr_size(handle->conn, smb_fname, xattr_name); if (smb_fname->st.st_ex_size == -1) { SET_STAT_INVALID(smb_fname->st); errno = ENOENT; result = -1; goto fail; } smb_fname->st.st_ex_ino = stream_inode(&smb_fname->st, xattr_name); smb_fname->st.st_ex_mode &= ~S_IFMT; smb_fname->st.st_ex_mode &= ~S_IFDIR; smb_fname->st.st_ex_mode |= S_IFREG; smb_fname->st.st_ex_blocks = smb_fname->st.st_ex_size / STAT_ST_BLOCKSIZE + 1; result = 0; fail: TALLOC_FREE(xattr_name); return result; }
static int streams_xattr_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { NTSTATUS status; int result = -1; char *xattr_name = NULL; if (!is_ntfs_stream_smb_fname(smb_fname)) { return SMB_VFS_NEXT_LSTAT(handle, smb_fname); } /* If the default stream is requested, just stat the base file. */ if (is_ntfs_default_stream_smb_fname(smb_fname)) { return streams_xattr_stat_base(handle, smb_fname, false); } /* Populate the stat struct with info from the base file. */ if (streams_xattr_stat_base(handle, sm