• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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