libite 2.6.1
dir.c
Go to the documentation of this file.
1/* Functions for operating on files in directories.
2 *
3 * Copyright (c) 2008-2021 Joachim Wiberg <troglobit@gmail.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
24
25#include <errno.h>
26#include <dirent.h>
27#include <stdlib.h>
28#include <string.h>
29
30static const char *matcher_type = NULL;
31static int (*matcher_filter) (const char *file) = NULL;
32
33static int matcher(const struct dirent *entry)
34{
35 char *pos = strrchr(entry->d_name, '.');
36
37 if (matcher_filter && !matcher_filter(entry->d_name))
38 /* User matcher overrides the rest. */
39 return 0;
40
41 /* Skip current dir "." from list of files. */
42 if ((1 == strlen(entry->d_name) && entry->d_name[0] == '.') ||
43 (2 == strlen(entry->d_name) && !strcmp(entry->d_name, "..")))
44 return 0;
45
46 /* filetype == "" */
47 if (matcher_type[0] == 0)
48 return 1;
49
50 /* Entry has no "." */
51 if (!pos)
52 return 0;
53
54 return !strcmp(pos, matcher_type);
55}
56
82int dir(const char *dir, const char *type, int (*filter) (const char *file), char ***list, int strip)
83{
84 int i, n, num = 0;
85 char **files;
86 struct dirent **namelist;
87
88 if (!list) {
89 errno = EINVAL;
90 return -1;
91 }
92
93 if (!dir)
94 /* Assuming current directory */
95 dir = ".";
96 if (!type)
97 /* Assuming all files. */
98 type = "";
99
100 matcher_type = type;
101 matcher_filter = filter;
102 n = scandir(dir, &namelist, matcher, alphasort);
103 if (n < 0)
104 return -1;
105
106 if (n > 0) {
107 files = (char **)malloc(n * sizeof(char *));
108 for (i = 0; i < n; i++) {
109 if (files) {
110 char *name = namelist[i]->d_name;
111 char *type = strrchr(name, '.');
112
113 if (type && strip)
114 *type = 0;
115
116 files[i] = strdup(name);
117 num++;
118 }
119 free(namelist[i]);
120 }
121 if (num)
122 *list = files;
123 }
124
125 if (namelist)
126 free(namelist);
127
128 return num;
129}
130
int dir(const char *dir, const char *type, int(*filter)(const char *file), char ***list, int strip)
Definition dir.c:82