diff options
author | Stefan Metzmacher <metze@samba.org> | 2008-12-01 14:10:27 -0800 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-12-11 10:27:12 +0100 |
commit | 789384d58e8a282dd1a47ffc6ec65c838038e6b3 (patch) | |
tree | 9efc4c78413bc85f023910e7b6f2b4130462ad6b | |
parent | 9ffcedb2eb580d67ae4890052a1013dfa89e26a2 (diff) | |
download | samba-789384d58e8a282dd1a47ffc6ec65c838038e6b3.tar.gz |
s3:streams_depot: add support for stream renames
metze
(cherry picked from commit 2e401bf868ba04285e58945a2dd5bf10605fc6d9)
-rw-r--r-- | source/modules/vfs_streams_depot.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/source/modules/vfs_streams_depot.c b/source/modules/vfs_streams_depot.c index ccb0a2ec89b..3f5231a1449 100644 --- a/source/modules/vfs_streams_depot.c +++ b/source/modules/vfs_streams_depot.c @@ -497,6 +497,78 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) return SMB_VFS_NEXT_UNLINK(handle, fname); } +static int streams_depot_rename(vfs_handle_struct *handle, + const char *oldname, + const char *newname) +{ + TALLOC_CTX *frame = NULL; + int ret = -1; + bool old_is_stream; + bool new_is_stream; + char *obase = NULL; + char *osname = NULL; + char *nbase = NULL; + char *nsname = NULL; + char *ostream_fname = NULL; + char *nstream_fname = NULL; + + DEBUG(10, ("streams_depot_rename called for %s => %s\n", + oldname, newname)); + + old_is_stream = is_ntfs_stream_name(oldname); + new_is_stream = is_ntfs_stream_name(newname); + + if (!old_is_stream && !new_is_stream) { + return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + } + + if (!(old_is_stream && new_is_stream)) { + errno = ENOSYS; + return -1; + } + + frame = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname, + &obase, &osname))) { + errno = ENOMEM; + goto done; + } + + if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname, + &nbase, &nsname))) { + errno = ENOMEM; + goto done; + } + + /* for now don't allow renames from or to the default stream */ + if (!osname || !nsname) { + errno = ENOSYS; + goto done; + } + + if (StrCaseCmp(obase, nbase) != 0) { + errno = ENOSYS; + goto done; + } + + ostream_fname = stream_name(handle, oldname, false); + if (ostream_fname == NULL) { + return -1; + } + + nstream_fname = stream_name(handle, newname, false); + if (nstream_fname == NULL) { + return -1; + } + + ret = SMB_VFS_NEXT_RENAME(handle, ostream_fname, nstream_fname); + +done: + TALLOC_FREE(frame); + return ret; +} + static bool add_one_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams, struct stream_struct **streams, const char *name, SMB_OFF_T size, @@ -647,6 +719,8 @@ static vfs_op_tuple streams_depot_ops[] = { SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(streams_depot_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_rename), SMB_VFS_OP_RENAME, + SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(streams_depot_streaminfo), SMB_VFS_OP_STREAMINFO, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} |