summaryrefslogtreecommitdiff
path: root/source3/modules/onefs_streams.c
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-06-25 11:20:36 -0700
committerTim Prouty <tprouty@samba.org>2009-06-25 18:25:47 -0700
commit2ccd50122058df1fb5da0ab4d30085bb4ef5e867 (patch)
treefdfadb3295f1f8c2a0bc8d3f56f29f0f78ae5c7e /source3/modules/onefs_streams.c
parent358ccc3282681b3df0ba76fecc114ad4376c8ff1 (diff)
downloadsamba-2ccd50122058df1fb5da0ab4d30085bb4ef5e867.tar.gz
samba-2ccd50122058df1fb5da0ab4d30085bb4ef5e867.tar.bz2
samba-2ccd50122058df1fb5da0ab4d30085bb4ef5e867.zip
s3 onefs: Plumb smb_filename through onefs createfile path
Diffstat (limited to 'source3/modules/onefs_streams.c')
-rw-r--r--source3/modules/onefs_streams.c137
1 files changed, 106 insertions, 31 deletions
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 284e199fc5..a4c6146fb0 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -54,6 +54,52 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
return NT_STATUS_OK;
}
+NTSTATUS onefs_stream_prep_smb_fname(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname_in,
+ struct smb_filename **smb_fname_out)
+{
+ char *stream_name = NULL;
+ NTSTATUS status;
+
+ /*
+ * Only attempt to strip off the trailing :$DATA if there is an actual
+ * stream there. If it is the default stream, the smb_fname_out will
+ * just have a NULL stream so the base file is opened.
+ */
+ if (smb_fname_in->stream_name &&
+ !is_ntfs_default_stream_smb_fname(smb_fname_in)) {
+ char *str_tmp = smb_fname_in->stream_name;
+
+ /* First strip off the leading ':' */
+ if (str_tmp[0] == ':') {
+ str_tmp++;
+ }
+
+ /* Create a new copy of the stream_name. */
+ stream_name = talloc_strdup(ctx, str_tmp);
+ if (stream_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Strip off the :$DATA if one exists. */
+ str_tmp = strrchr_m(stream_name, ':');
+ if (str_tmp) {
+ str_tmp[0] = '\0';
+ }
+ }
+
+ /*
+ * If there was a stream that wasn't the default stream the leading
+ * colon and trailing :$DATA has now been stripped off. Create a new
+ * smb_filename to pass back.
+ */
+ status = create_synthetic_smb_fname(ctx, smb_fname_in->base_name,
+ stream_name, &smb_fname_in->st,
+ smb_fname_out);
+ TALLOC_FREE(stream_name);
+ return status;
+}
+
int onefs_is_stream(const char *path, char **pbase, char **pstream,
bool *is_stream)
{
@@ -312,28 +358,37 @@ static int stat_stream(struct connection_struct *conn, const char *base,
return ret;
}
-int onefs_stat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+int onefs_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
+ struct smb_filename *smb_fname_onefs = NULL;
+ NTSTATUS status;
int ret;
- bool is_stream;
- char *base = NULL;
- char *stream = NULL;
- ret = onefs_is_stream(path, &base, &stream, &is_stream);
- if (ret)
- return ret;
+ status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+ &smb_fname_onefs);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
- if (!is_stream) {
- ret = onefs_sys_stat(path, sbuf);
- } else if (!stream) {
- /* If it's the ::$DATA stream just stat the base file name. */
- ret = onefs_sys_stat(base, sbuf);
+ /*
+ * If the smb_fname has no stream or is :$DATA, then just stat the
+ * base stream. Otherwise stat the stream.
+ */
+ if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
+ ret = onefs_sys_stat(smb_fname_onefs->base_name,
+ &smb_fname->st);
} else {
- ret = stat_stream(handle->conn, base, stream, sbuf, 0);
+ ret = stat_stream(handle->conn, smb_fname_onefs->base_name,
+ smb_fname_onefs->stream_name, &smb_fname->st,
+ 0);
}
- onefs_adjust_stat_time(handle->conn, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, smb_fname->base_name,
+ &smb_fname->st);
+
+ TALLOC_FREE(smb_fname_onefs);
+
return ret;
}
@@ -361,29 +416,37 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
return ret;
}
-int onefs_lstat(vfs_handle_struct *handle, const char *path,
- SMB_STRUCT_STAT *sbuf)
+int onefs_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
+ struct smb_filename *smb_fname_onefs = NULL;
+ NTSTATUS status;
int ret;
- bool is_stream;
- char *base = NULL;
- char *stream = NULL;
- ret = onefs_is_stream(path, &base, &stream, &is_stream);
- if (ret)
- return ret;
+ status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+ &smb_fname_onefs);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
- if (!is_stream) {
- ret = onefs_sys_lstat(path, sbuf);
- } else if (!stream) {
- /* If it's the ::$DATA stream just stat the base file name. */
- ret = onefs_sys_lstat(base, sbuf);
+ /*
+ * If the smb_fname has no stream or is :$DATA, then just stat the
+ * base stream. Otherwise stat the stream.
+ */
+ if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
+ ret = onefs_sys_lstat(smb_fname_onefs->base_name,
+ &smb_fname->st);
} else {
- ret = stat_stream(handle->conn, base, stream, sbuf,
+ ret = stat_stream(handle->conn, smb_fname_onefs->base_name,
+ smb_fname_onefs->stream_name, &smb_fname->st,
AT_SYMLINK_NOFOLLOW);
}
- onefs_adjust_stat_time(handle->conn, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, smb_fname->base_name,
+ &smb_fname->st);
+
+ TALLOC_FREE(smb_fname_onefs);
+
return ret;
}
@@ -661,10 +724,22 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
}
ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
+ struct smb_filename *smb_fname = NULL;
+
if (is_ntfs_stream_name(fname)) {
return NT_STATUS_INVALID_PARAMETER;
}
- ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
+
+ sbuf = smb_fname->st;
+
+ TALLOC_FREE(smb_fname);
}
if (ret == -1) {