s3:streams_depot: add support for stream renames
authorStefan Metzmacher <metze@samba.org>
Mon, 1 Dec 2008 22:10:04 +0000 (14:10 -0800)
committerJeremy Allison <jra@samba.org>
Mon, 1 Dec 2008 22:10:04 +0000 (14:10 -0800)
metze

source3/modules/vfs_streams_depot.c

index 80c693190cf3e3241bd58f236e84a364397acdc5..f8a8d97743a0558e851a4f65e9d25a0fc975d889 100644 (file)
@@ -498,6 +498,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,
@@ -648,6 +720,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}