termux-app

Форк
0
418 строк · 12.5 Кб
1
/*
2
 * Copyright (c) 2008, 2013, 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 com.termux.shared.file.filesystem;
27

28
import android.os.Build;
29
import android.system.StructStat;
30

31
import androidx.annotation.NonNull;
32

33
import java.io.File;
34
import java.io.FileDescriptor;
35
import java.io.IOException;
36
import java.util.concurrent.TimeUnit;
37
import java.util.Set;
38
import java.util.HashSet;
39

40
/**
41
 * Unix implementation of PosixFileAttributes.
42
 * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/sun/nio/fs/UnixFileAttributes.java
43
 */
44

45
public class FileAttributes {
46
    private String filePath;
47
    private FileDescriptor fileDescriptor;
48

49
    private int st_mode;
50
    private long st_ino;
51
    private long st_dev;
52
    private long st_rdev;
53
    private long st_nlink;
54
    private int st_uid;
55
    private int st_gid;
56
    private long st_size;
57
    private long st_blksize;
58
    private long st_blocks;
59
    private long st_atime_sec;
60
    private long st_atime_nsec;
61
    private long st_mtime_sec;
62
    private long st_mtime_nsec;
63
    private long st_ctime_sec;
64
    private long st_ctime_nsec;
65

66
    // created lazily
67
    private volatile String owner;
68
    private volatile String group;
69
    private volatile FileKey key;
70

71
    private FileAttributes(String filePath) {
72
        this.filePath = filePath;
73
    }
74

75
    private FileAttributes(FileDescriptor fileDescriptor) {
76
        this.fileDescriptor = fileDescriptor;
77
    }
78

79
    // get the FileAttributes for a given file
80
    public static FileAttributes get(String filePath, boolean followLinks) throws IOException {
81
        FileAttributes fileAttributes;
82

83
        if (filePath == null || filePath.isEmpty())
84
            fileAttributes = new FileAttributes((String) null);
85
        else
86
            fileAttributes = new FileAttributes(new File(filePath).getAbsolutePath());
87

88
        if (followLinks) {
89
            NativeDispatcher.stat(filePath, fileAttributes);
90
        } else {
91
            NativeDispatcher.lstat(filePath, fileAttributes);
92
        }
93

94
        // Logger.logDebug(fileAttributes.toString());
95

96
        return fileAttributes;
97
    }
98

99
    // get the FileAttributes for an open file
100
    public static FileAttributes get(FileDescriptor fileDescriptor) throws IOException {
101
        FileAttributes fileAttributes = new FileAttributes(fileDescriptor);
102
        NativeDispatcher.fstat(fileDescriptor, fileAttributes);
103
        return fileAttributes;
104
    }
105

106
    public String file() {
107
        if (filePath != null)
108
            return filePath;
109
        else if (fileDescriptor != null)
110
            return fileDescriptor.toString();
111
        else
112
            return null;
113
    }
114

115
    // package-private
116
    public boolean isSameFile(FileAttributes attrs) {
117
        return ((st_ino == attrs.st_ino) && (st_dev == attrs.st_dev));
118
    }
119

120
    // package-private
121
    public int mode() {
122
        return st_mode;
123
    }
124

125
    public long blksize() {
126
        return st_blksize;
127
    }
128

129
    public long blocks() {
130
        return st_blocks;
131
    }
132

133
    public long ino() {
134
        return st_ino;
135
    }
136

137
    public long dev() {
138
        return st_dev;
139
    }
140

141
    public long rdev() {
142
        return st_rdev;
143
    }
144

145
    public long nlink() {
146
        return st_nlink;
147
    }
148

149
    public int uid() {
150
        return st_uid;
151
    }
152

153
    public int gid() {
154
        return st_gid;
155
    }
156

157
    private static FileTime toFileTime(long sec, long nsec) {
158
        if (nsec == 0) {
159
            return FileTime.from(sec, TimeUnit.SECONDS);
160
        } else {
161
            // truncate to microseconds to avoid overflow with timestamps
162
            // way out into the future. We can re-visit this if FileTime
163
            // is updated to define a from(secs,nsecs) method.
164
            long micro = sec * 1000000L + nsec / 1000L;
165
            return FileTime.from(micro, TimeUnit.MICROSECONDS);
166
        }
167
    }
168

169
    public FileTime lastAccessTime() {
170
        return toFileTime(st_atime_sec, st_atime_nsec);
171
    }
172

173
    public FileTime lastModifiedTime() {
174
        return toFileTime(st_mtime_sec, st_mtime_nsec);
175
    }
176

177
    public FileTime lastChangeTime() {
178
        return toFileTime(st_ctime_sec, st_ctime_nsec);
179
    }
180

181
    public FileTime creationTime() {
182
        return lastModifiedTime();
183
    }
184

185
    public boolean isRegularFile() {
186
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
187
    }
188

189
    public boolean isDirectory() {
190
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
191
    }
192

193
    public boolean isSymbolicLink() {
194
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFLNK);
195
    }
196

197
    public boolean isCharacter() {
198
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFCHR);
199
    }
200

201
    public boolean isFifo() {
202
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFIFO);
203
    }
204

205
    public boolean isSocket() {
206
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFSOCK);
207
    }
208

209
    public boolean isBlock() {
210
        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFBLK);
211
    }
212

213
    public boolean isOther() {
214
        int type = st_mode & UnixConstants.S_IFMT;
215
        return (type != UnixConstants.S_IFREG &&
216
            type != UnixConstants.S_IFDIR &&
217
            type != UnixConstants.S_IFLNK);
218
    }
219

220
    public boolean isDevice() {
221
        int type = st_mode & UnixConstants.S_IFMT;
222
        return (type == UnixConstants.S_IFCHR ||
223
            type == UnixConstants.S_IFBLK ||
224
            type == UnixConstants.S_IFIFO);
225
    }
226

227
    public long size() {
228
        return st_size;
229
    }
230

231
    public FileKey fileKey() {
232
        if (key == null) {
233
            synchronized (this) {
234
                if (key == null) {
235
                    key = new FileKey(st_dev, st_ino);
236
                }
237
            }
238
        }
239
        return key;
240
    }
241

242
    public String owner() {
243
        if (owner == null) {
244
            synchronized (this) {
245
                if (owner == null) {
246
                    owner = Integer.toString(st_uid);
247
                }
248
            }
249
        }
250
        return owner;
251
    }
252

253
    public String group() {
254
        if (group == null) {
255
            synchronized (this) {
256
                if (group == null) {
257
                    group = Integer.toString(st_gid);
258
                }
259
            }
260
        }
261
        return group;
262
    }
263

264
    public Set<FilePermission> permissions() {
265
        int bits = (st_mode & UnixConstants.S_IAMB);
266
        HashSet<FilePermission> perms = new HashSet<>();
267

268
        if ((bits & UnixConstants.S_IRUSR) > 0)
269
            perms.add(FilePermission.OWNER_READ);
270
        if ((bits & UnixConstants.S_IWUSR) > 0)
271
            perms.add(FilePermission.OWNER_WRITE);
272
        if ((bits & UnixConstants.S_IXUSR) > 0)
273
            perms.add(FilePermission.OWNER_EXECUTE);
274

275
        if ((bits & UnixConstants.S_IRGRP) > 0)
276
            perms.add(FilePermission.GROUP_READ);
277
        if ((bits & UnixConstants.S_IWGRP) > 0)
278
            perms.add(FilePermission.GROUP_WRITE);
279
        if ((bits & UnixConstants.S_IXGRP) > 0)
280
            perms.add(FilePermission.GROUP_EXECUTE);
281

282
        if ((bits & UnixConstants.S_IROTH) > 0)
283
            perms.add(FilePermission.OTHERS_READ);
284
        if ((bits & UnixConstants.S_IWOTH) > 0)
285
            perms.add(FilePermission.OTHERS_WRITE);
286
        if ((bits & UnixConstants.S_IXOTH) > 0)
287
            perms.add(FilePermission.OTHERS_EXECUTE);
288

289
        return perms;
290
    }
291

292
    public void loadFromStructStat(StructStat structStat) {
293
        this.st_mode = structStat.st_mode;
294
        this.st_ino = structStat.st_ino;
295
        this.st_dev = structStat.st_dev;
296
        this.st_rdev = structStat.st_rdev;
297
        this.st_nlink = structStat.st_nlink;
298
        this.st_uid = structStat.st_uid;
299
        this.st_gid = structStat.st_gid;
300
        this.st_size = structStat.st_size;
301
        this.st_blksize = structStat.st_blksize;
302
        this.st_blocks = structStat.st_blocks;
303

304
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
305
            this.st_atime_sec = structStat.st_atim.tv_sec;
306
            this.st_atime_nsec = structStat.st_atim.tv_nsec;
307
            this.st_mtime_sec = structStat.st_mtim.tv_sec;
308
            this.st_mtime_nsec = structStat.st_mtim.tv_nsec;
309
            this.st_ctime_sec = structStat.st_ctim.tv_sec;
310
            this.st_ctime_nsec = structStat.st_ctim.tv_nsec;
311
        } else {
312
            this.st_atime_sec = structStat.st_atime;
313
            this.st_atime_nsec = 0;
314
            this.st_mtime_sec = structStat.st_mtime;
315
            this.st_mtime_nsec = 0;
316
            this.st_ctime_sec = structStat.st_ctime;
317
            this.st_ctime_nsec = 0;
318
        }
319
    }
320

321
    public String getFileString() {
322
        return "File: `" + file() + "`";
323
    }
324

325
    public String getTypeString() {
326
        return "Type: `" + FileTypes.getFileType(this).getName() + "`";
327
    }
328

329
    public String getSizeString() {
330
        return "Size: `" + size() + "`";
331
    }
332

333
    public String getBlocksString() {
334
        return "Blocks: `" + blocks() + "`";
335
    }
336

337
    public String getIOBlockString() {
338
        return "IO Block: `" + blksize() + "`";
339
    }
340

341
    public String getDeviceString() {
342
        return "Device: `" + Long.toHexString(st_dev) + "`";
343
    }
344

345
    public String getInodeString() {
346
        return "Inode: `" + st_ino + "`";
347
    }
348

349
    public String getLinksString() {
350
        return "Links: `" + nlink() + "`";
351
    }
352

353
    public String getDeviceTypeString() {
354
        return "Device Type: `" + rdev() + "`";
355
    }
356

357
    public String getOwnerString() {
358
        return "Owner: `" + owner() + "`";
359
    }
360

361
    public String getGroupString() {
362
        return "Group: `" + group() + "`";
363
    }
364

365
    public String getPermissionString() {
366
        return "Permissions: `" + FilePermissions.toString(permissions()) + "`";
367
    }
368

369
    public String getAccessTimeString() {
370
        return "Access Time: `" + lastAccessTime() + "`";
371
    }
372

373
    public String getModifiedTimeString() {
374
        return "Modified Time: `" + lastModifiedTime() + "`";
375
    }
376

377
    public String getChangeTimeString() {
378
        return "Change Time: `" + lastChangeTime() + "`";
379
    }
380

381
    @NonNull
382
    @Override
383
    public String toString() {
384
        return getFileAttributesLogString(this);
385
    }
386

387
    public static String getFileAttributesLogString(final FileAttributes fileAttributes) {
388
        if (fileAttributes == null) return "null";
389

390
        StringBuilder logString = new StringBuilder();
391

392
        logString.append(fileAttributes.getFileString());
393

394
        logString.append("\n").append(fileAttributes.getTypeString());
395

396
        logString.append("\n").append(fileAttributes.getSizeString());
397
        logString.append("\n").append(fileAttributes.getBlocksString());
398
        logString.append("\n").append(fileAttributes.getIOBlockString());
399

400
        logString.append("\n").append(fileAttributes.getDeviceString());
401
        logString.append("\n").append(fileAttributes.getInodeString());
402
        logString.append("\n").append(fileAttributes.getLinksString());
403

404
        if (fileAttributes.isBlock() || fileAttributes.isCharacter())
405
            logString.append("\n").append(fileAttributes.getDeviceTypeString());
406

407
        logString.append("\n").append(fileAttributes.getOwnerString());
408
        logString.append("\n").append(fileAttributes.getGroupString());
409
        logString.append("\n").append(fileAttributes.getPermissionString());
410

411
        logString.append("\n").append(fileAttributes.getAccessTimeString());
412
        logString.append("\n").append(fileAttributes.getModifiedTimeString());
413
        logString.append("\n").append(fileAttributes.getChangeTimeString());
414

415
        return logString.toString();
416
    }
417

418
}
419

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.