r13355: check controls are correctly exported
[Samba/aatanasov.git] / source4 / ntvfs / posix / pvfs_util.c
blobf286dfdc48c8acbd5e4e8f39fdafda8c7f436fda
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 utility functions for posix backend
24 #include "includes.h"
25 #include "vfs_posix.h"
28 return True if a string contains one of the CIFS wildcard characters
30 BOOL pvfs_has_wildcard(const char *str)
32 if (strpbrk(str, "*?<>\"")) {
33 return True;
35 return False;
39 map a unix errno to a NTSTATUS
41 NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno)
43 return map_nt_error_from_unix(unix_errno);
48 check if a filename has an attribute matching the given attribute search value
49 this is used by calls like unlink and search which take an attribute
50 and only include special files if they match the given attribute
52 NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name,
53 uint32_t attrib, uint32_t must_attrib)
55 if ((name->dos.attrib & ~attrib) & FILE_ATTRIBUTE_DIRECTORY) {
56 return NT_STATUS_FILE_IS_A_DIRECTORY;
58 if ((name->dos.attrib & ~attrib) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
59 return NT_STATUS_NO_SUCH_FILE;
61 if (must_attrib & ~name->dos.attrib) {
62 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
64 return NT_STATUS_OK;
69 normalise a file attribute
71 uint32_t pvfs_attrib_normalise(uint32_t attrib, mode_t mode)
73 if (attrib != FILE_ATTRIBUTE_NORMAL) {
74 attrib &= ~FILE_ATTRIBUTE_NORMAL;
76 if (S_ISDIR(mode)) {
77 attrib |= FILE_ATTRIBUTE_DIRECTORY;
78 } else {
79 attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
81 return attrib;
86 copy a file. Caller is supposed to have already ensured that the
87 operation is allowed. The destination file must not exist.
89 NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
90 struct pvfs_filename *name1,
91 struct pvfs_filename *name2)
93 int fd1, fd2;
94 mode_t mode;
95 NTSTATUS status;
96 size_t buf_size = 0x10000;
97 char *buf = talloc_size(name2, buf_size);
99 if (buf == NULL) {
100 return NT_STATUS_NO_MEMORY;
103 fd1 = open(name1->full_name, O_RDONLY);
104 if (fd1 == -1) {
105 talloc_free(buf);
106 return pvfs_map_errno(pvfs, errno);
109 fd2 = open(name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0);
110 if (fd2 == -1) {
111 close(fd1);
112 talloc_free(buf);
113 return pvfs_map_errno(pvfs, errno);
116 while (1) {
117 ssize_t ret2, ret = read(fd1, buf, buf_size);
118 if (ret == -1 &&
119 (errno == EINTR || errno == EAGAIN)) {
120 continue;
122 if (ret <= 0) break;
124 ret2 = write(fd2, buf, ret);
125 if (ret2 == -1 &&
126 (errno == EINTR || errno == EAGAIN)) {
127 continue;
130 if (ret2 != ret) {
131 close(fd1);
132 close(fd2);
133 talloc_free(buf);
134 unlink(name2->full_name);
135 if (ret2 == -1) {
136 return pvfs_map_errno(pvfs, errno);
138 return NT_STATUS_DISK_FULL;
142 talloc_free(buf);
143 close(fd1);
145 mode = pvfs_fileperms(pvfs, name1->dos.attrib);
146 if (fchmod(fd2, mode) == -1) {
147 status = pvfs_map_errno(pvfs, errno);
148 close(fd2);
149 unlink(name2->full_name);
150 return status;
153 name2->st.st_mode = mode;
154 name2->dos = name1->dos;
156 status = pvfs_dosattrib_save(pvfs, name2, fd2);
157 if (!NT_STATUS_IS_OK(status)) {
158 close(fd2);
159 unlink(name2->full_name);
160 return status;
163 close(fd2);
165 return NT_STATUS_OK;
170 hash a string of the specified length. The string does not need to be
171 null terminated
173 hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce).
174 see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a
175 discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors
177 uint32_t pvfs_name_hash(const char *key, size_t length)
179 const uint32_t fnv1_prime = 0x01000193;
180 const uint32_t fnv1_init = 0xa6b93095;
181 uint32_t value = fnv1_init;
183 while (*key && length--) {
184 size_t c_size;
185 codepoint_t c = next_codepoint(key, &c_size);
186 c = toupper_w(c);
187 value *= fnv1_prime;
188 value ^= (uint32_t)c;
189 key += c_size;
192 return value;
197 file allocation size rounding. This is required to pass ifstest
199 uint64_t pvfs_round_alloc_size(struct pvfs_state *pvfs, uint64_t size)
201 const uint32_t round_value = pvfs->alloc_size_rounding;
202 return round_value * ((size + round_value - 1)/round_value);