Last active
October 27, 2015 20:26
-
-
Save bcavagnolo/9437cca4338d9be7f5af to your computer and use it in GitHub Desktop.
Get creation time of an inode on linux if available
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Derived from debugfs.c in e2fsprogs and inspired by: | |
* http://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/50184 | |
* | |
* Copyright (C) 1993 Theodore Ts'o. This file may be redistributed | |
* under the terms of the GNU Public License. | |
* | |
* Modifications by Robert Sanders <[email protected]> | |
* | |
* To build: | |
* apt-get install e2fslibs-dev # or similar | |
* gcc -o crtime crtime.c -lext2fs | |
* | |
* To let non-root users get creation times of files: | |
* chown root ./crtime | |
* chmod u+s ./crtime | |
* | |
* To run: | |
* target=/path/to/some/file | |
* inode=$(ls -di "${target}" | cut -d ' ' -f 1); | |
* fs=$(df "${target}" | tail -1 | awk '{print $1}'); | |
* ./crtime ${fs} ${inode} | |
*/ | |
#include <ext2fs/ext2fs.h> | |
#include <stdio.h> | |
ext2_filsys current_fs; | |
static int open_filesystem(char *device) | |
{ | |
int retval; | |
io_manager io_ptr = unix_io_manager; | |
retval = ext2fs_open(device, 0, 0, 0, io_ptr, ¤t_fs); | |
if (retval) { | |
fprintf(stderr, "Error while opening filesystem: %d\n", retval); | |
return retval; | |
} | |
return 0; | |
} | |
int debugfs_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode, int bufsize) | |
{ | |
int retval; | |
return ext2fs_read_inode_full(current_fs, ino, inode, bufsize); | |
} | |
int main(int argc, char *argv[]) { | |
ext2_ino_t inode; | |
struct ext2_inode *inode_buf; | |
struct ext2_inode_large *large_inode; | |
int retval; | |
if (argc != 3) { | |
fprintf(stderr, "Usage: crtime <filesystem> <inode>\n"); | |
return -1; | |
} | |
retval = sscanf(argv[2], "%d", &inode); | |
if (retval != 1) { | |
fprintf(stderr, "Could not parse an integer from %s\n", argv[2]); | |
return -1; | |
} | |
retval = open_filesystem(argv[1]); | |
if (retval) { | |
return retval; | |
} | |
inode_buf = (struct ext2_inode *)malloc(EXT2_INODE_SIZE(current_fs->super)); | |
if (!inode_buf) { | |
fprintf(stderr, "Failed to allocate memory\n"); | |
return -1; | |
} | |
retval = ext2fs_read_inode_full(current_fs, inode, inode_buf, EXT2_INODE_SIZE(current_fs->super)); | |
if (retval) { | |
fprintf(stderr, "Failed to read inode\n"); | |
free(inode_buf); | |
return retval; | |
} | |
if (EXT2_INODE_SIZE(current_fs->super) <= EXT2_GOOD_OLD_INODE_SIZE) { | |
fprintf(stderr, "Create time unavailable"); | |
return -1; | |
} | |
large_inode = (struct ext2_inode_large *)inode_buf; | |
if (large_inode->i_extra_isize < 24) { | |
fprintf(stderr, "Create time unavailable"); | |
return -1; | |
} | |
printf("%d\n", large_inode->i_crtime); | |
free(inode_buf); | |
ext2fs_close(current_fs); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment