Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java
40948 views
1
/*
2
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.nio.fs;
27
28
import java.nio.file.attribute.*;
29
import java.util.Map;
30
import java.util.Set;
31
import java.io.IOException;
32
import jdk.internal.misc.Unsafe;
33
34
import static sun.nio.fs.UnixNativeDispatcher.*;
35
import static sun.nio.fs.UnixConstants.*;
36
37
/**
38
* Linux implementation of DosFileAttributeView for use on file systems such
39
* as ext3 that have extended attributes enabled and SAMBA configured to store
40
* DOS attributes.
41
*/
42
43
class LinuxDosFileAttributeView
44
extends UnixFileAttributeViews.Basic implements DosFileAttributeView
45
{
46
private static final Unsafe unsafe = Unsafe.getUnsafe();
47
48
private static final String READONLY_NAME = "readonly";
49
private static final String ARCHIVE_NAME = "archive";
50
private static final String SYSTEM_NAME = "system";
51
private static final String HIDDEN_NAME = "hidden";
52
53
private static final String DOS_XATTR_NAME = "user.DOSATTRIB";
54
private static final byte[] DOS_XATTR_NAME_AS_BYTES = Util.toBytes(DOS_XATTR_NAME);
55
56
private static final int DOS_XATTR_READONLY = 0x01;
57
private static final int DOS_XATTR_HIDDEN = 0x02;
58
private static final int DOS_XATTR_SYSTEM = 0x04;
59
private static final int DOS_XATTR_ARCHIVE = 0x20;
60
61
// the names of the DOS attributes (includes basic)
62
private static final Set<String> dosAttributeNames =
63
Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME);
64
65
LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {
66
super(file, followLinks);
67
}
68
69
@Override
70
public String name() {
71
return "dos";
72
}
73
74
@Override
75
public void setAttribute(String attribute, Object value)
76
throws IOException
77
{
78
if (attribute.equals(READONLY_NAME)) {
79
setReadOnly((Boolean)value);
80
return;
81
}
82
if (attribute.equals(ARCHIVE_NAME)) {
83
setArchive((Boolean)value);
84
return;
85
}
86
if (attribute.equals(SYSTEM_NAME)) {
87
setSystem((Boolean)value);
88
return;
89
}
90
if (attribute.equals(HIDDEN_NAME)) {
91
setHidden((Boolean)value);
92
return;
93
}
94
super.setAttribute(attribute, value);
95
}
96
97
@Override
98
public Map<String,Object> readAttributes(String[] attributes)
99
throws IOException
100
{
101
AttributesBuilder builder =
102
AttributesBuilder.create(dosAttributeNames, attributes);
103
DosFileAttributes attrs = readAttributes();
104
addRequestedBasicAttributes(attrs, builder);
105
if (builder.match(READONLY_NAME))
106
builder.add(READONLY_NAME, attrs.isReadOnly());
107
if (builder.match(ARCHIVE_NAME))
108
builder.add(ARCHIVE_NAME, attrs.isArchive());
109
if (builder.match(SYSTEM_NAME))
110
builder.add(SYSTEM_NAME, attrs.isSystem());
111
if (builder.match(HIDDEN_NAME))
112
builder.add(HIDDEN_NAME, attrs.isHidden());
113
return builder.unmodifiableMap();
114
}
115
116
@Override
117
public DosFileAttributes readAttributes() throws IOException {
118
file.checkRead();
119
120
int fd = -1;
121
try {
122
fd = file.openForAttributeAccess(followLinks);
123
final UnixFileAttributes attrs = UnixFileAttributes.get(fd);
124
final int dosAttribute = getDosAttribute(fd);
125
126
return new DosFileAttributes() {
127
@Override
128
public FileTime lastModifiedTime() {
129
return attrs.lastModifiedTime();
130
}
131
@Override
132
public FileTime lastAccessTime() {
133
return attrs.lastAccessTime();
134
}
135
@Override
136
public FileTime creationTime() {
137
return attrs.creationTime();
138
}
139
@Override
140
public boolean isRegularFile() {
141
return attrs.isRegularFile();
142
}
143
@Override
144
public boolean isDirectory() {
145
return attrs.isDirectory();
146
}
147
@Override
148
public boolean isSymbolicLink() {
149
return attrs.isSymbolicLink();
150
}
151
@Override
152
public boolean isOther() {
153
return attrs.isOther();
154
}
155
@Override
156
public long size() {
157
return attrs.size();
158
}
159
@Override
160
public Object fileKey() {
161
return attrs.fileKey();
162
}
163
@Override
164
public boolean isReadOnly() {
165
return (dosAttribute & DOS_XATTR_READONLY) != 0;
166
}
167
@Override
168
public boolean isHidden() {
169
return (dosAttribute & DOS_XATTR_HIDDEN) != 0;
170
}
171
@Override
172
public boolean isArchive() {
173
return (dosAttribute & DOS_XATTR_ARCHIVE) != 0;
174
}
175
@Override
176
public boolean isSystem() {
177
return (dosAttribute & DOS_XATTR_SYSTEM) != 0;
178
}
179
};
180
181
} catch (UnixException x) {
182
x.rethrowAsIOException(file);
183
return null; // keep compiler happy
184
} finally {
185
close(fd);
186
}
187
}
188
189
@Override
190
public void setReadOnly(boolean value) throws IOException {
191
updateDosAttribute(DOS_XATTR_READONLY, value);
192
}
193
194
@Override
195
public void setHidden(boolean value) throws IOException {
196
updateDosAttribute(DOS_XATTR_HIDDEN, value);
197
}
198
199
@Override
200
public void setArchive(boolean value) throws IOException {
201
updateDosAttribute(DOS_XATTR_ARCHIVE, value);
202
}
203
204
@Override
205
public void setSystem(boolean value) throws IOException {
206
updateDosAttribute(DOS_XATTR_SYSTEM, value);
207
}
208
209
/**
210
* Reads the value of the user.DOSATTRIB extended attribute
211
*/
212
private int getDosAttribute(int fd) throws UnixException {
213
final int size = 24;
214
215
NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
216
try {
217
int len = LinuxNativeDispatcher
218
.fgetxattr(fd, DOS_XATTR_NAME_AS_BYTES, buffer.address(), size);
219
220
if (len > 0) {
221
// ignore null terminator
222
if (unsafe.getByte(buffer.address()+len-1) == 0)
223
len--;
224
225
// convert to String and parse
226
byte[] buf = new byte[len];
227
unsafe.copyMemory(null, buffer.address(), buf,
228
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
229
String value = Util.toString(buf);
230
231
// should be something like 0x20
232
if (value.length() >= 3 && value.startsWith("0x")) {
233
try {
234
return Integer.parseInt(value.substring(2), 16);
235
} catch (NumberFormatException x) {
236
// ignore
237
}
238
}
239
}
240
throw new UnixException("Value of " + DOS_XATTR_NAME + " attribute is invalid");
241
} catch (UnixException x) {
242
// default value when attribute does not exist
243
if (x.errno() == ENODATA)
244
return 0;
245
throw x;
246
} finally {
247
buffer.release();
248
}
249
}
250
251
/**
252
* Updates the value of the user.DOSATTRIB extended attribute
253
*/
254
private void updateDosAttribute(int flag, boolean enable) throws IOException {
255
file.checkWrite();
256
257
int fd = -1;
258
try {
259
fd = file.openForAttributeAccess(followLinks);
260
int oldValue = getDosAttribute(fd);
261
int newValue = oldValue;
262
if (enable) {
263
newValue |= flag;
264
} else {
265
newValue &= ~flag;
266
}
267
if (newValue != oldValue) {
268
byte[] value = Util.toBytes("0x" + Integer.toHexString(newValue));
269
NativeBuffer buffer = NativeBuffers.asNativeBuffer(value);
270
try {
271
LinuxNativeDispatcher.fsetxattr(fd, DOS_XATTR_NAME_AS_BYTES,
272
buffer.address(), value.length+1);
273
} finally {
274
buffer.release();
275
}
276
}
277
} catch (UnixException x) {
278
x.rethrowAsIOException(file);
279
} finally {
280
close(fd);
281
}
282
}
283
}
284
285