chiark / gitweb /
tree-wide: remove Lennart's copyright lines
[elogind.git] / src / basic / dirent-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <fcntl.h>
4 #include <sys/stat.h>
5
6 #include "dirent-util.h"
7 #include "path-util.h"
8 #include "string-util.h"
9
10 int dirent_ensure_type(DIR *d, struct dirent *de) {
11         struct stat st;
12
13         assert(d);
14         assert(de);
15
16         if (de->d_type != DT_UNKNOWN)
17                 return 0;
18
19         if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
20                 return -errno;
21
22         de->d_type =
23                 S_ISREG(st.st_mode)  ? DT_REG  :
24                 S_ISDIR(st.st_mode)  ? DT_DIR  :
25                 S_ISLNK(st.st_mode)  ? DT_LNK  :
26                 S_ISFIFO(st.st_mode) ? DT_FIFO :
27                 S_ISSOCK(st.st_mode) ? DT_SOCK :
28                 S_ISCHR(st.st_mode)  ? DT_CHR  :
29                 S_ISBLK(st.st_mode)  ? DT_BLK  :
30                                        DT_UNKNOWN;
31
32         return 0;
33 }
34
35 bool dirent_is_file(const struct dirent *de) {
36         assert(de);
37
38         if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
39                 return false;
40
41         if (hidden_or_backup_file(de->d_name))
42                 return false;
43
44         return true;
45 }
46
47 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
48         assert(de);
49
50         if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
51                 return false;
52
53         if (de->d_name[0] == '.')
54                 return false;
55
56         if (!suffix)
57                 return true;
58
59         return endswith(de->d_name, suffix);
60 }
61
62 struct dirent* readdir_no_dot(DIR *dirp) {
63         struct dirent* d;
64
65         for (;;) {
66                 d = readdir(dirp);
67                 if (d && dot_or_dot_dot(d->d_name))
68                         continue;
69                 return d;
70         }
71 }