1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <assert.h>
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <time.h>
8
9 #if defined MAJOR_IN_SYSMACROS
10 # include <sys/sysmacros.h>
11 #elif defined MAJOR_IN_MKDEV
12 # include <sys/mkdev.h>
13 #else
14 # include <sys/types.h>
15 #endif
16
17 #undef STAT_PREFIX
18 #undef NR_stat
19
20 #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
21 # include <sys/stat.h>
22 # define STAT_PREFIX "(stat(64)?\\(|newfstatat\\(AT_FDCWD, )"
23 #else
24 # include <sys/syscall.h>
25 # if defined __NR_stat
26 # define NR_stat __NR_stat
27 # define STAT_PREFIX "stat\\("
28 # elif defined __NR_newstat
29 # define NR_stat __NR_newstat
30 # define STAT_PREFIX "newstat\\("
31 # endif
32 # ifdef STAT_PREFIX
33 /* for S_IFMT */
34 # define stat libc_stat
35 # define stat64 libc_stat64
36 # include <sys/stat.h>
37 # undef stat
38 # undef stat64
39 # undef st_atime
40 # undef st_mtime
41 # undef st_ctime
42
43 # undef dev_t
44 # undef ino_t
45 # undef mode_t
46 # undef nlink_t
47 # undef uid_t
48 # undef gid_t
49 # undef off_t
50 # undef loff_t
51 # define dev_t __kernel_dev_t
52 # define ino_t __kernel_ino_t
53 # define mode_t __kernel_mode_t
54 # define nlink_t __kernel_nlink_t
55 # define uid_t __kernel_uid_t
56 # define gid_t __kernel_gid_t
57 # define off_t __kernel_off_t
58 # define loff_t __kernel_loff_t
59 # include <asm/stat.h>
60 # endif /* STAT_PREFIX */
61 #endif /* _FILE_OFFSET_BITS */
62
63 #ifdef STAT_PREFIX
64
65 static void
print_ftype(unsigned int mode)66 print_ftype(unsigned int mode)
67 {
68 if (S_ISREG(mode))
69 printf("S_IFREG");
70 else if (S_ISDIR(mode))
71 printf("S_IFDIR");
72 else if (S_ISCHR(mode))
73 printf("S_IFCHR");
74 else if (S_ISBLK(mode))
75 printf("S_IFBLK");
76 else
77 printf("%#o", mode & S_IFMT);
78 }
79
80 static void
print_perms(unsigned int mode)81 print_perms(unsigned int mode)
82 {
83 printf("%#o", mode & ~S_IFMT);
84 }
85
86 static void
print_time(time_t t)87 print_time(time_t t)
88 {
89 if (!t) {
90 printf("0");
91 return;
92 }
93
94 struct tm *p = localtime(&t);
95
96 if (p)
97 printf("%02d/%02d/%02d-%02d:%02d:%02d",
98 p->tm_year + 1900, p->tm_mon + 1, p->tm_mday,
99 p->tm_hour, p->tm_min, p->tm_sec);
100 else
101 printf("%llu", (unsigned long long) t);
102 }
103
104 int
main(int ac,const char ** av)105 main(int ac, const char **av)
106 {
107 assert(ac == 2);
108 struct stat stb;
109
110 #ifdef NR_stat
111 if (sizeof(stb.st_size) > 4)
112 return 77;
113 assert(syscall(NR_stat, av[1], &stb) == 0);
114 #else
115 assert(stat(av[1], &stb) == 0);
116 #endif
117
118 printf(STAT_PREFIX "\"%s\", \\{", av[1]);
119 printf("st_dev=makedev\\(%u, %u\\)",
120 (unsigned int) major(stb.st_dev),
121 (unsigned int) minor(stb.st_dev));
122 printf(", st_ino=%llu", (unsigned long long) stb.st_ino);
123 printf(", st_mode=");
124 print_ftype(stb.st_mode);
125 printf("\\|");
126 print_perms(stb.st_mode);
127 printf(", st_nlink=%u", (unsigned int) stb.st_nlink);
128 printf(", st_uid=%u", (unsigned int) stb.st_uid);
129 printf(", st_gid=%u", (unsigned int) stb.st_gid);
130 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
131 printf(", st_blksize=%u", (unsigned int) stb.st_blksize);
132 #endif
133 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
134 printf(", st_blocks=%u", (unsigned int) stb.st_blocks);
135 #endif
136
137 switch (stb.st_mode & S_IFMT) {
138 case S_IFCHR: case S_IFBLK:
139 #ifdef HAVE_STRUCT_STAT_ST_RDEV
140 printf(", st_rdev=makedev\\(%u, %u\\)",
141 (unsigned int) major(stb.st_rdev),
142 (unsigned int) minor(stb.st_rdev));
143 #else
144 printf(", st_size=makedev\\(%u, %u\\)",
145 (unsigned int) major(stb.st_size),
146 (unsigned int) minor(stb.st_size));
147 #endif
148 break;
149 default:
150 printf(", st_size=%llu", (unsigned long long) stb.st_size);
151 }
152
153 printf(", st_atime=");
154 print_time(stb.st_atime);
155 printf(", st_mtime=");
156 print_time(stb.st_mtime);
157 printf(", st_ctime=");
158 print_time(stb.st_ctime);
159 printf("(, st_flags=[0-9]+)?");
160 printf("(, st_fstype=[^,]*)?");
161 printf("(, st_gen=[0-9]+)?");
162 printf("\\}");
163 #ifndef NR_stat
164 printf("(, 0)?");
165 #endif
166 printf("\\) += 0\n");
167 return 0;
168 }
169
170 #else /* !STAT_PREFIX */
main(void)171 int main(void)
172 {
173 return 77;
174 }
175 #endif
176