fscrypt-crypt-util: fix IV incrementing for --iv-ino-lblk-32
[xfstests-dev.git] / src / t_dir_type.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016 CTERA Networks. All Rights Reserved.
4  * Author: Amir Goldstein <amir73il@gmail.com>
5  */
6
7 /*
8  * t_dir_type
9  *
10  * print directory entries and their file type, optionally filtered by d_type
11  * or by inode number.
12  *
13  * ./t_dir_type <path> [u|f|d|c|b|l|p|s|w|<ino>]
14  */
15
16 #include <fcntl.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <dirent.h>
22 #include <sys/stat.h>
23 #include <sys/syscall.h>
24
25 struct linux_dirent64 {
26         uint64_t        d_ino;
27         int64_t         d_off;
28         unsigned short  d_reclen;
29         unsigned char   d_type;
30         char            d_name[0];
31 };
32
33 #define DT_MASK 15
34 #define DT_MAX 15
35 unsigned char type_to_char[DT_MAX] = {
36         [DT_UNKNOWN] = 'u',
37         [DT_DIR] = 'd',
38         [DT_REG] = 'f',
39         [DT_LNK] = 'l',
40         [DT_CHR] = 'c',
41         [DT_BLK] = 'b',
42         [DT_FIFO] = 'p',
43         [DT_SOCK] = 's',
44         [DT_WHT] = 'w',
45 };
46
47 #define DT_CHAR(t) type_to_char[(t)&DT_MASK]
48
49 #define BUF_SIZE 4096
50
51 int
52 main(int argc, char *argv[])
53 {
54         int fd, nread;
55         char buf[BUF_SIZE];
56         struct linux_dirent64 *d;
57         int bpos;
58         int type = -1; /* -1 means all types */
59         uint64_t ino = 0;
60         int ret = 1;
61
62         fd = open(argv[1], O_RDONLY | O_DIRECTORY);
63         if (fd < 0) {
64                 perror("open");
65                 exit(EXIT_FAILURE);
66         }
67
68         if (argc > 2 && argv[2][0]) {
69                 char t = argv[2][0];
70
71                 for (type = DT_MAX-1; type >= 0; type--)
72                         if (DT_CHAR(type) == t)
73                                 break;
74                 /* no match ends up with type = -1 */
75                 if (type < 0)
76                         ino = strtoul(argv[2], NULL, 10);
77         }
78
79         for ( ; ; ) {
80                 nread = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
81                 if (nread == -1) {
82                         perror("getdents");
83                         exit(EXIT_FAILURE);
84                 }
85
86                 if (nread == 0)
87                         break;
88
89                 for (bpos = 0; bpos < nread;) {
90                         d = (struct linux_dirent64 *) (buf + bpos);
91                         if ((type < 0 || type == (int)d->d_type) &&
92                             (!ino || ino == d->d_ino)) {
93                                 ret = 0;
94                                 printf("%s %c\n", d->d_name, DT_CHAR(d->d_type));
95                         }
96                         bpos += d->d_reclen;
97                 }
98         }
99
100         return ret;
101 }