ls. level — это количество каталогов под текущим каталогом. Если ls был найден в nftw(), начинающемся с /usr, уровень будет равен 1. Если поиск начался с /usr/bin, уровень будет равен 0.
14.7.3. Реализация find
Команда find выполняет в одном или нескольких деревьях каталогов поиск файлов, соответствующих определенным характеристикам. Ниже приведена простая реализация find, реализованная на основе nftw(). Она использует fnmatch() (см. главу 23) для реализации переключателя -name и иллюстрирует многие флаги, воспринимаемые nftw().
1: /* find.с */
2:
3: #define _XOPEN_SOURCE 600
4:
5: #include <fnmatch.h>
6: #include <ftw.h>
7: #include <limits.h>
8: #include <stdio.h>
9: #include <stdlib.h>
10: #include <string.h>
11:
12: const char * name = NULL;
13: int minDepth = 0, maxDepth = INT_MAX;
14:
15: int find (const char * file, const struct stat * sb, int flags,
16: struct FTW * f) {
17: if (f->level < minDepth) return 0;
18: if (f->level > maxDepth) return 0;
19: if (name && fnmatch(name, file + f->base, FNM_PERIOD)) return 0;
20:
21: if (flags == FTW_DNR) {
22: fprintf(stderr, 'find: %s: недопустимые полномочия
', file);
23: } else {
24: printf('%s
', file);
25: }
26:
27: return 0;
28: }
29:
30: int main(int argc, const char ** argv) {
31: int flags = FTW_PHYS;
32: int i;
33: int problem = 0;
34: int tmp;
35: int rc;
36: char * chptr;
37:
38: /* поиск первого параметры командной строки (который должен
39: находиться после списка путей */
40: i = 1;
41: while (i < argc && *argv[i] != '-') i++;
42:
43: /* обработать опции командной строки */
44: while (i < argc && !problem) {
45: if (!strcmp(argv[i], '-name')) {
46: i++;
47: if (i == argc)
48: problem = 1;
49: else
50: name = argv[i++];
51: } else if (!strcmp(argv[i], '-depth')) {
52: i++;
53: flags |= FTW_DEPTH;
54: } else if (!strcmp (argv[i], '-mount') ||
55: !strcmp(argv[i], '-xdev')) {
56: i++;
57: flags |= FTW_MOUNT;
58: } else if (!strcmp (argv[i], '-mindepth') ||
59: !strcmp (argv[i], '-maxdepth')) {
60: i++;
61: if (i == argc)
62: problem = 1;
63: else {
64: tmp = strtoul(argv[i++], &chptr, 10);
65: if (*chptr)
66: problem = 1;
67: else if (!strcmp(argv[i - 2], '-mindepth'))
68: minDepth = tmp;
69: else
70: maxDepth = tmp;
71: }
72: }
73: }
74:
75: if (problem) {
76: fprintf(stderr, 'использование: find <пути> [-name <строка>]'
77: '[-mindepth <целое>] [-maxdepth <целое>]
');
78: fprintf(stderr, ' [-xdev] [-depth]
');
79: return 1;
80: }
81:
82: if (argc == 1 || *argv[1] == '-') {
83: argv[1] = '.';
84: argc = 2;
85: }
