-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatx.c
156 lines (133 loc) · 3.79 KB
/
statx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// SPDX-License-Identifier: Apache-2.0
/*
* based on https://github.com/torvalds/linux/blob/master/samples/vfs/test-statx.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <sys/stat.h>
#ifndef __NR_statx
#define __NR_statx -1
#endif
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);
}
int main(int argc, char **argv)
{
int ret;
char file_type = '?';
char symlink[10240];
int atflag = AT_SYMLINK_NOFOLLOW;
unsigned int mask = STATX_ALL;
struct statx stx;
int exit_code = EXIT_SUCCESS;
memset(&stx, 0xbf, sizeof(stx));
for (int i = 1; i < argc; i++) {
ret = statx(AT_FDCWD, argv[i], atflag, mask, &stx);
if (ret < 0)
{
perror(argv[i]);
exit_code = EXIT_FAILURE;
continue;
}
// MD5
printf("0");
// name
ret = readlink(argv[i], symlink, sizeof(symlink));
if (ret > 0)
printf("|%s -> %s", argv[i], symlink);
else
printf("|%s", argv[i]);
// inode
if (stx.stx_mask & STATX_INO)
printf("|%llu", (unsigned long long)stx.stx_ino);
else
printf("|0");
// type
if (stx.stx_mask & STATX_TYPE)
{
switch (stx.stx_mode & S_IFMT)
{
case S_IFIFO:
file_type = 'p';
break;
case S_IFCHR:
file_type = 'c';
break;
case S_IFDIR:
file_type = 'd';
break;
case S_IFBLK:
file_type = 'b';
break;
case S_IFREG:
file_type = '-';
break;
case S_IFLNK:
file_type = 'l';
break;
case S_IFSOCK:
file_type = 's';
break;
}
}
printf("|%c", file_type);
// mode as string
if (stx.stx_mask & STATX_MODE)
printf("%c%c%c%c%c%c%c%c%c",
stx.stx_mode & S_IRUSR ? 'r' : '-',
stx.stx_mode & S_IWUSR ? 'w' : '-',
stx.stx_mode & S_IXUSR ? 'x' : '-',
stx.stx_mode & S_IRGRP ? 'r' : '-',
stx.stx_mode & S_IWGRP ? 'w' : '-',
stx.stx_mode & S_IXGRP ? 'x' : '-',
stx.stx_mode & S_IROTH ? 'r' : '-',
stx.stx_mode & S_IWOTH ? 'w' : '-',
stx.stx_mode & S_IXOTH ? 'x' : '-');
else
printf("?????????");
// uid
if (stx.stx_mask & STATX_UID)
printf("|%d", stx.stx_uid);
else
printf("|0");
// gid
if (stx.stx_mask & STATX_GID)
printf("|%d", stx.stx_gid);
else
printf("|0");
// size
if (stx.stx_mask & STATX_SIZE)
printf("|%llu", (unsigned long long)stx.stx_size);
else
printf("|0");
// atime
if (stx.stx_mask & STATX_ATIME)
printf("|%llu", stx.stx_atime.tv_sec);
else
printf("|0");
// mtime
if (stx.stx_mask & STATX_MTIME)
printf("|%llu", stx.stx_mtime.tv_sec);
else
printf("|0");
// ctime
if (stx.stx_mask & STATX_CTIME)
printf("|%llu", stx.stx_ctime.tv_sec);
else
printf("|0");
// btime
if (stx.stx_mask & STATX_BTIME)
printf("|%llu", stx.stx_btime.tv_sec);
else
printf("|0");
printf("\n");
}
return exit_code;
}