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