/* statx.c -- part of Nemo file creation date extension * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #define _GNU_SOURCE #define _ATFILE_SOURCE #include #include #include // for memset #include // for syscall, ssize_t #include #include #if NATIVE_STATX /* native statx call */ #include // for AT_FDCWD, AT_NO_AUTOMOUNT #include // for statx, STATX_BTIME, statx_timestamp #include // for __NR_statx static __attribute__((unused)) ssize_t statx (int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) { return syscall (__NR_statx, dfd, filename, flags, mask, buffer); } #else /* statx wrapper/compatibility */ #define AT_FDCWD -100 /* Special value used to indicate openat should use the current working directory. */ #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ /* this code works ony with x86 and x86_64 */ #if __x86_64__ #define __NR_statx 332 #else #define __NR_statx 383 #endif #define STATX_BTIME 0x00000800U /* Want/got stx_btime */ struct statx_timestamp { int64_t tv_sec; uint32_t tv_nsec; int32_t __reserved; }; struct statx { /* 0x00 */ uint32_t stx_mask; /* What results were written [uncond] */ uint32_t stx_blksize; /* Preferred general I/O size [uncond] */ uint64_t stx_attributes; /* Flags conveying information about the file [uncond] */ /* 0x10 */ uint32_t stx_nlink; /* Number of hard links */ uint32_t stx_uid; /* User ID of owner */ uint32_t stx_gid; /* Group ID of owner */ uint16_t stx_mode; /* File mode */ uint16_t __spare0[1]; /* 0x20 */ uint64_t stx_ino; /* Inode number */ uint64_t stx_size; /* File size */ uint64_t stx_blocks; /* Number of 512-byte blocks allocated */ uint64_t stx_attributes_mask; /* Mask to show what's supported in stx_attributes */ /* 0x40 */ struct statx_timestamp stx_atime; /* Last access time */ struct statx_timestamp stx_btime; /* File creation time */ struct statx_timestamp stx_ctime; /* Last attribute change time */ struct statx_timestamp stx_mtime; /* Last data modification time */ /* 0x80 */ uint32_t stx_rdev_major; /* Device ID of special file [if bdev/cdev] */ uint32_t stx_rdev_minor; uint32_t stx_dev_major; /* ID of device containing file [uncond] */ uint32_t stx_dev_minor; /* 0x90 */ uint64_t __spare2[14]; /* Spare space for future expansion */ /* 0x100 */ }; #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e)) #endif // NATIVE_STATX time_t get_file_btime (const char *path) { static int not_implemented = 0; int flags = AT_NO_AUTOMOUNT; unsigned int mask = STATX_BTIME; struct statx stxbuf; long ret = 0; time_t btime; btime = 0; if (not_implemented) { return btime; } memset (&stxbuf, 0xbf, sizeof(stxbuf)); errno = 0; ret = statx (AT_FDCWD, path, flags, mask, &stxbuf); if (ret < 0) { if (errno == ENOSYS) { printf("nemo-creation-date: kernel needs to be (>= 4.15) - file creation dates not available\n"); not_implemented = 1; } return btime; } btime = (&stxbuf)->stx_btime.tv_sec; return btime; }