1 /* statx.c -- part of Nemo file creation date extension
2 *
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA.
17 *
18 */
19
20 #define _GNU_SOURCE
21 #define _ATFILE_SOURCE
22 #include <config.h>
23 #include <time.h>
24 #include <string.h> // for memset
25 #include <unistd.h> // for syscall, ssize_t
26 #include <stdio.h>
27 #include <errno.h>
28
29 #if NATIVE_STATX
30 /* native statx call */
31 #include <linux/fcntl.h> // for AT_FDCWD, AT_NO_AUTOMOUNT
32 #include <linux/stat.h> // for statx, STATX_BTIME, statx_timestamp
33 #include <syscall.h> // for __NR_statx
34
35 static __attribute__((unused))
statx(int dfd,const char * filename,unsigned flags,unsigned int mask,struct statx * buffer)36 ssize_t statx (int dfd, const char *filename, unsigned flags,
37 unsigned int mask, struct statx *buffer)
38 {
39 return syscall (__NR_statx, dfd, filename, flags, mask, buffer);
40 }
41
42 #else
43 /* statx wrapper/compatibility */
44
45 #define AT_FDCWD -100 /* Special value used to indicate
46 openat should use the current
47 working directory. */
48 #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
49
50 /* this code works ony with x86 and x86_64 */
51 #if __x86_64__
52 #define __NR_statx 332
53 #else
54 #define __NR_statx 383
55 #endif
56
57 #define STATX_BTIME 0x00000800U /* Want/got stx_btime */
58
59 struct statx_timestamp {
60 int64_t tv_sec;
61 uint32_t tv_nsec;
62 int32_t __reserved;
63 };
64
65 struct statx {
66 /* 0x00 */
67 uint32_t stx_mask; /* What results were written [uncond] */
68 uint32_t stx_blksize; /* Preferred general I/O size [uncond] */
69 uint64_t stx_attributes; /* Flags conveying information about the file [uncond] */
70 /* 0x10 */
71 uint32_t stx_nlink; /* Number of hard links */
72 uint32_t stx_uid; /* User ID of owner */
73 uint32_t stx_gid; /* Group ID of owner */
74 uint16_t stx_mode; /* File mode */
75 uint16_t __spare0[1];
76 /* 0x20 */
77 uint64_t stx_ino; /* Inode number */
78 uint64_t stx_size; /* File size */
79 uint64_t stx_blocks; /* Number of 512-byte blocks allocated */
80 uint64_t stx_attributes_mask; /* Mask to show what's supported in stx_attributes */
81 /* 0x40 */
82 struct statx_timestamp stx_atime; /* Last access time */
83 struct statx_timestamp stx_btime; /* File creation time */
84 struct statx_timestamp stx_ctime; /* Last attribute change time */
85 struct statx_timestamp stx_mtime; /* Last data modification time */
86 /* 0x80 */
87 uint32_t stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
88 uint32_t stx_rdev_minor;
89 uint32_t stx_dev_major; /* ID of device containing file [uncond] */
90 uint32_t stx_dev_minor;
91 /* 0x90 */
92 uint64_t __spare2[14]; /* Spare space for future expansion */
93 /* 0x100 */
94 };
95
96 #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))
97
98 #endif // NATIVE_STATX
99
100
101 time_t
get_file_btime(const char * path)102 get_file_btime (const char *path)
103 {
104 static int not_implemented = 0;
105
106 int flags = AT_NO_AUTOMOUNT;
107 unsigned int mask = STATX_BTIME;
108 struct statx stxbuf;
109 long ret = 0;
110 time_t btime;
111
112 btime = 0;
113
114 if (not_implemented)
115 {
116 return btime;
117 }
118
119 memset (&stxbuf, 0xbf, sizeof(stxbuf));
120 errno = 0;
121
122 ret = statx (AT_FDCWD, path, flags, mask, &stxbuf);
123
124 if (ret < 0)
125 {
126 if (errno == ENOSYS)
127 {
128 printf("nemo-creation-date: kernel needs to be (>= 4.15) - file creation dates not available\n");
129 not_implemented = 1;
130 }
131
132 return btime;
133 }
134
135 btime = (&stxbuf)->stx_btime.tv_sec;
136
137 return btime;
138 }
139