struct file_info;
struct xattr_DosEAs;
+struct xattr_DosStreams;
struct test_join;
uint16 num_eas;
[size_is(num_eas)] xattr_EA *eas;
} xattr_DosEAs;
+
+ /* we store stream information in this xattr structure. Then
+ the streams themselves are stored in
+ user.DosStream.STREAMNAME or in external files, according
+ to the flags */
+ const string XATTR_DOSSTREAMS_NAME = "user.DosStreams";
+
+ const int XATTR_STREAM_FLAG_INTERNAL = 0x00000001;
+
+ typedef struct {
+ utf8string name;
+ uint64 size;
+ uint32 flags;
+ } xattr_DosStream;
+
+ typedef [public] struct {
+ uint32 num_streams;
+ [size_is(num_streams)] xattr_DosStream *streams;
+ } xattr_DosStreams;
}
ntvfs/posix/pvfs_seek.o \
ntvfs/posix/pvfs_ioctl.o \
ntvfs/posix/pvfs_xattr.o \
+ ntvfs/posix/pvfs_streams.o \
ntvfs/common/opendb.o \
ntvfs/common/brlock.o
# End MODULE ntvfs_posix
}
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
struct pvfs_filename *name;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, rd->in.path,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, rd->in.path, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
NTSTATUS status;
uint32_t create_action;
+ if (name->stream_name) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
/* if the client says it must be a directory, and it isn't,
then fail */
if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
if (mkdir(name->full_name, mode) == -1) {
return pvfs_map_errno(pvfs,errno);
}
- status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
struct pvfs_filename *name;
NTSTATUS status;
- status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
+ PVFS_RESOLVE_STREAMS, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
/* try re-resolving the name */
- status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
NTSTATUS status;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, info->generic.in.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
struct pvfs_filename *name1, *name2;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1);
+ status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1,
+ PVFS_RESOLVE_WILDCARD, &name1);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 0, &name2);
+ status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2,
+ PVFS_RESOLVE_WILDCARD, &name2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return status;
}
- if (name1->has_wildcard || name2->has_wildcard) {
- return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
- }
-
if (!name1->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
case '<':
case '?':
case '"':
- if (flags & PVFS_RESOLVE_NO_WILDCARD) {
+ if (!(flags & PVFS_RESOLVE_WILDCARD)) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
name->has_wildcard = True;
}
}
if (err_count) {
- if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--;
+ if (flags & PVFS_RESOLVE_WILDCARD) err_count--;
if (err_count==1) {
return NT_STATUS_OBJECT_NAME_INVALID;
pattern = io->search_first.in.pattern;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
+ status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
max_count = io->t2ffirst.in.max_count;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
+ status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
/* resolve the new name */
- status = pvfs_resolve_name(pvfs, name, new_name, PVFS_RESOLVE_NO_WILDCARD, &name2);
+ status = pvfs_resolve_name(pvfs, name, new_name, 0, &name2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
ealist->num_eas++;
save:
+ /* pull out any null EAs */
+ for (i=0;i<ealist->num_eas;i++) {
+ if (ealist->eas[i].value.length == 0) {
+ memmove(&ealist->eas[i],
+ &ealist->eas[i+1],
+ (ealist->num_eas-(i+1)) * sizeof(ealist->eas[i]));
+ ealist->num_eas--;
+ i--;
+ }
+ }
+
status = pvfs_doseas_save(pvfs, name, fd, ealist);
if (!NT_STATUS_IS_OK(status)) {
return status;
struct utimbuf unix_times;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, info->generic.file.fname,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ POSIX NTVFS backend - alternate data streams
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
uint_t ofs;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name);
+ status = pvfs_resolve_name(pvfs, req, unl->in.pattern,
+ PVFS_RESOLVE_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSEAS_NAME, eas,
(ndr_push_flags_fn_t)ndr_push_xattr_DosEAs);
}
+
+
+/*
+ load the set of streams from extended attributes
+*/
+NTSTATUS pvfs_streams_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+ struct xattr_DosStreams *streams)
+{
+ NTSTATUS status;
+ ZERO_STRUCTP(streams);
+ if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+ return NT_STATUS_OK;
+ }
+ status = pvfs_xattr_ndr_load(pvfs, streams, name->full_name, fd,
+ XATTR_DOSSTREAMS_NAME,
+ streams,
+ (ndr_pull_flags_fn_t)ndr_pull_xattr_DosStreams);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return NT_STATUS_OK;
+ }
+ return status;
+}
+
+/*
+ save the set of streams into filesystem xattr
+*/
+NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+ struct xattr_DosStreams *streams)
+{
+ if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+ return NT_STATUS_OK;
+ }
+ return pvfs_xattr_ndr_save(pvfs, name->full_name, fd,
+ XATTR_DOSSTREAMS_NAME,
+ streams,
+ (ndr_push_flags_fn_t)ndr_push_xattr_DosStreams);
+}
NTSTATUS status;
/* resolve the cifs name to a posix name */
- status = pvfs_resolve_name(pvfs, req, cp->in.path,
- PVFS_RESOLVE_NO_WILDCARD, &name);
+ status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* flags to pvfs_resolve_name() */
-#define PVFS_RESOLVE_NO_WILDCARD (1<<0)
+#define PVFS_RESOLVE_WILDCARD (1<<0)
#define PVFS_RESOLVE_STREAMS (1<<1)
/* flags in pvfs->flags */