build: list source of FNAME_UTIL directly in def, remove vars=locals()
[Samba/wip.git] / source4 / ntvfs / posix / pvfs_util.c
blob6afb928d73c5a125477ef367d25c308d860b4647
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 3 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, see <http://www.gnu.org/licenses/>.
20 utility functions for posix backend
23 #include "includes.h"
24 #include "vfs_posix.h"
27 return true if a string contains one of the CIFS wildcard characters
29 bool pvfs_has_wildcard(const char *str)
31 if (strpbrk(str, "*?<>\"")) {
32 return true;
34 return false;
38 map a unix errno to a NTSTATUS
40 NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno)
42 NTSTATUS status;
43 status = map_nt_error_from_unix_common(unix_errno);
44 DEBUG(10,(__location__ " mapped unix errno %d -> %s\n", unix_errno, nt_errstr(status)));
45 return status;
50 check if a filename has an attribute matching the given attribute search value
51 this is used by calls like unlink and search which take an attribute
52 and only include special files if they match the given attribute
54 NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name,
55 uint32_t attrib, uint32_t must_attrib)
57 if ((name->dos.attrib & ~attrib) & FILE_ATTRIBUTE_DIRECTORY) {
58 return NT_STATUS_FILE_IS_A_DIRECTORY;
60 if ((name->dos.attrib & ~attrib) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
61 return NT_STATUS_NO_SUCH_FILE;
63 if (must_attrib & ~name->dos.attrib) {
64 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
66 return NT_STATUS_OK;
71 normalise a file attribute
73 uint32_t pvfs_attrib_normalise(uint32_t attrib, mode_t mode)
75 if (attrib != FILE_ATTRIBUTE_NORMAL) {
76 attrib &= ~FILE_ATTRIBUTE_NORMAL;
78 if (S_ISDIR(mode)) {
79 attrib |= FILE_ATTRIBUTE_DIRECTORY;
80 } else {
81 attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
83 return attrib;
88 copy a file. Caller is supposed to have already ensured that the
89 operation is allowed. The destination file must not exist.
91 NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
92 struct pvfs_filename *name1,
93 struct pvfs_filename *name2,
94 bool allow_override)
96 int fd1, fd2;
97 mode_t mode;
98 NTSTATUS status;
99 size_t buf_size = 0x10000;
100 uint8_t *buf = talloc_array(name2, uint8_t, buf_size);
102 if (buf == NULL) {
103 return NT_STATUS_NO_MEMORY;
106 fd1 = pvfs_sys_open(pvfs, name1->full_name, O_RDONLY, 0, allow_override);
107 if (fd1 == -1) {
108 talloc_free(buf);
109 return pvfs_map_errno(pvfs, errno);
112 fd2 = pvfs_sys_open(pvfs, name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0, allow_override);
113 if (fd2 == -1) {
114 close(fd1);
115 talloc_free(buf);
116 return pvfs_map_errno(pvfs, errno);
119 while (1) {
120 ssize_t ret2, ret = read(fd1, buf, buf_size);
121 if (ret == -1 &&
122 (errno == EINTR || errno == EAGAIN)) {
123 continue;
125 if (ret <= 0) break;
127 ret2 = write(fd2, buf, ret);
128 if (ret2 == -1 &&
129 (errno == EINTR || errno == EAGAIN)) {
130 continue;
133 if (ret2 != ret) {
134 close(fd1);
135 close(fd2);
136 talloc_free(buf);
137 pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
138 if (ret2 == -1) {
139 return pvfs_map_errno(pvfs, errno);
141 return NT_STATUS_DISK_FULL;
145 talloc_free(buf);
146 close(fd1);
148 mode = pvfs_fileperms(pvfs, name1->dos.attrib);
149 if (pvfs_sys_fchmod(pvfs, fd2, mode, allow_override) == -1) {
150 status = pvfs_map_errno(pvfs, errno);
151 close(fd2);
152 pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
153 return status;
156 name2->st.st_mode = mode;
157 name2->dos = name1->dos;
159 status = pvfs_dosattrib_save(pvfs, name2, fd2);
160 if (!NT_STATUS_IS_OK(status)) {
161 close(fd2);
162 pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
163 return status;
166 close(fd2);
168 return NT_STATUS_OK;
173 hash a string of the specified length. The string does not need to be
174 null terminated
176 hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce).
177 see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a
178 discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors
180 uint32_t pvfs_name_hash(const char *key, size_t length)
182 const uint32_t fnv1_prime = 0x01000193;
183 const uint32_t fnv1_init = 0xa6b93095;
184 uint32_t value = fnv1_init;
186 while (*key && length--) {
187 size_t c_size;
188 codepoint_t c = next_codepoint(key, &c_size);
189 c = toupper_m(c);
190 value *= fnv1_prime;
191 value ^= (uint32_t)c;
192 key += c_size;
195 return value;
200 file allocation size rounding. This is required to pass ifstest
202 uint64_t pvfs_round_alloc_size(struct pvfs_state *pvfs, uint64_t size)
204 const uint32_t round_value = pvfs->alloc_size_rounding;
205 return round_value * ((size + round_value - 1)/round_value);