diff options
author | Matt Kraai <kraai@debian.org> | 2001-02-07 03:52:38 +0000 |
---|---|---|
committer | Matt Kraai <kraai@debian.org> | 2001-02-07 03:52:38 +0000 |
commit | 096370d349fb6be0f5754a9f1d1ca2910d33d78c (patch) | |
tree | 9a5c0ca1d70fdc842b949e3c59a2c59f5f889711 /findutils/find.c | |
parent | a164c647acc613fe199a646dc5075c097f51a4a4 (diff) | |
download | busybox-w32-096370d349fb6be0f5754a9f1d1ca2910d33d78c.tar.gz busybox-w32-096370d349fb6be0f5754a9f1d1ca2910d33d78c.tar.bz2 busybox-w32-096370d349fb6be0f5754a9f1d1ca2910d33d78c.zip |
Reworked find with David Douthitt to support -type, -perm, -mtime, and
other improvements.
Diffstat (limited to 'findutils/find.c')
-rw-r--r-- | findutils/find.c | 200 |
1 files changed, 144 insertions, 56 deletions
diff --git a/findutils/find.c b/findutils/find.c index f60c45a4e..a4d056b54 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -5,6 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 1999,2000,2001 by Lineo, inc. | 6 | * Copyright (C) 1999,2000,2001 by Lineo, inc. |
7 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | 7 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> |
8 | * Reworked by David Douthitt <n9ubh@callsign.net> and | ||
9 | * Matt Kraai <kraai@alumni.carnegiemellon.edu>. | ||
8 | * | 10 | * |
9 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
@@ -28,82 +30,168 @@ | |||
28 | #include <dirent.h> | 30 | #include <dirent.h> |
29 | #include <string.h> | 31 | #include <string.h> |
30 | #include <stdlib.h> | 32 | #include <stdlib.h> |
33 | #include <fnmatch.h> | ||
34 | #include <time.h> | ||
35 | #include <ctype.h> | ||
31 | 36 | ||
32 | 37 | ||
33 | static char *pattern = NULL; | 38 | static char *pattern; |
34 | static char *directory = "."; | 39 | |
35 | static int dereferenceFlag = FALSE; | 40 | #ifdef BB_FEATURE_FIND_TYPE |
41 | static int type_mask = 0; | ||
42 | #endif | ||
43 | |||
44 | #ifdef BB_FEATURE_FIND_PERM | ||
45 | static char perm_char = 0; | ||
46 | static int perm_mask = 0; | ||
47 | #endif | ||
48 | |||
49 | #ifdef BB_FEATURE_FIND_MTIME | ||
50 | static char mtime_char; | ||
51 | static int mtime_days; | ||
52 | #endif | ||
36 | 53 | ||
37 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) | 54 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) |
38 | { | 55 | { |
39 | if (pattern == NULL) | 56 | if (pattern != NULL) { |
40 | puts(fileName); | 57 | const char *tmp = strrchr(fileName, '/'); |
41 | else { | ||
42 | char *tmp = strrchr(fileName, '/'); | ||
43 | 58 | ||
44 | if (tmp == NULL) | 59 | if (tmp == NULL) |
45 | tmp = (char *) fileName; | 60 | tmp = fileName; |
46 | else | 61 | else |
47 | tmp++; | 62 | tmp++; |
48 | if (check_wildcard_match(tmp, pattern) == TRUE) | 63 | if (!(fnmatch(pattern, tmp, FNM_PERIOD) == 0)) |
49 | puts(fileName); | 64 | goto no_match; |
65 | } | ||
66 | #ifdef BB_FEATURE_FIND_TYPE | ||
67 | if (type_mask != 0) { | ||
68 | if (!((statbuf->st_mode & S_IFMT) == type_mask)) | ||
69 | goto no_match; | ||
50 | } | 70 | } |
71 | #endif | ||
72 | #ifdef BB_FEATURE_FIND_PERM | ||
73 | if (perm_mask != 0) { | ||
74 | if (!((isdigit(perm_char) && (statbuf->st_mode & 07777) == perm_mask) || | ||
75 | (perm_char == '-' && (statbuf->st_mode & perm_mask) == perm_mask) || | ||
76 | (perm_char == '+' && (statbuf->st_mode & perm_mask) != 0))) | ||
77 | goto no_match; | ||
78 | } | ||
79 | #endif | ||
80 | #ifdef BB_FEATURE_FIND_MTIME | ||
81 | if (mtime_days != 0) { | ||
82 | time_t file_age = time(NULL) - statbuf->st_mtime; | ||
83 | time_t mtime_secs = mtime_days * 24 * 60 * 60; | ||
84 | if (!((isdigit(mtime_char) && mtime_secs >= file_age && | ||
85 | mtime_secs < file_age + 24 * 60 * 60) || | ||
86 | (mtime_char == '+' && mtime_secs >= file_age) || | ||
87 | (mtime_char == '-' && mtime_secs < file_age))) | ||
88 | goto no_match; | ||
89 | } | ||
90 | #endif | ||
91 | puts(fileName); | ||
92 | no_match: | ||
51 | return (TRUE); | 93 | return (TRUE); |
52 | } | 94 | } |
53 | 95 | ||
96 | #ifdef BB_FEATURE_FIND_TYPE | ||
97 | static int find_type(char *type) | ||
98 | { | ||
99 | int mask = 0; | ||
100 | |||
101 | switch (type[0]) { | ||
102 | case 'b': | ||
103 | mask = S_IFBLK; | ||
104 | break; | ||
105 | case 'c': | ||
106 | mask = S_IFCHR; | ||
107 | break; | ||
108 | case 'd': | ||
109 | mask = S_IFDIR; | ||
110 | break; | ||
111 | case 'p': | ||
112 | mask = S_IFIFO; | ||
113 | break; | ||
114 | case 'f': | ||
115 | mask = S_IFREG; | ||
116 | break; | ||
117 | case 'l': | ||
118 | mask = S_IFLNK; | ||
119 | break; | ||
120 | case 's': | ||
121 | mask = S_IFSOCK; | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | if (mask == 0 || type[1] != '\0') | ||
126 | error_msg_and_die("invalid argument `%s' to `-type'", type); | ||
127 | |||
128 | return mask; | ||
129 | } | ||
130 | #endif | ||
131 | |||
54 | int find_main(int argc, char **argv) | 132 | int find_main(int argc, char **argv) |
55 | { | 133 | { |
56 | /* peel off the "find" */ | 134 | int dereference = FALSE; |
57 | argc--; | 135 | int i, firstopt, status = EXIT_SUCCESS; |
58 | argv++; | 136 | |
59 | 137 | for (firstopt = 1; firstopt < argc; firstopt++) { | |
60 | if (argc > 0 && **argv != '-') { | 138 | if (argv[firstopt][0] == '-') |
61 | directory = *argv; | 139 | break; |
62 | argc--; | ||
63 | argv++; | ||
64 | } | 140 | } |
65 | 141 | ||
66 | /* Parse any options */ | 142 | /* Parse any options */ |
67 | while (argc > 0 && **argv == '-') { | 143 | for (i = firstopt; i < argc; i++) { |
68 | int stopit = FALSE; | 144 | if (strcmp(argv[i], "-follow") == 0) |
69 | 145 | dereference = TRUE; | |
70 | while (*++(*argv) && stopit == FALSE) | 146 | else if (strcmp(argv[i], "-name") == 0) { |
71 | switch (**argv) { | 147 | if (++i == argc) |
72 | case 'f': | 148 | error_msg_and_die("option `-name' requires an argument"); |
73 | if (strcmp(*argv, "follow") == 0) { | 149 | pattern = argv[i]; |
74 | argc--; | 150 | #ifdef BB_FEATURE_FIND_TYPE |
75 | argv++; | 151 | } else if (strcmp(argv[i], "-type") == 0) { |
76 | dereferenceFlag = TRUE; | 152 | if (++i == argc) |
77 | } | 153 | error_msg_and_die("option `-type' requires an argument"); |
78 | break; | 154 | type_mask = find_type(argv[i]); |
79 | case 'n': | 155 | #endif |
80 | if (strcmp(*argv, "name") == 0) { | 156 | #ifdef BB_FEATURE_FIND_PERM |
81 | if (argc-- > 1) { | 157 | } else if (strcmp(argv[i], "-perm") == 0) { |
82 | pattern = *(++argv); | 158 | char *end; |
83 | stopit = TRUE; | 159 | if (++i == argc) |
84 | } else { | 160 | error_msg_and_die("option `-perm' requires an argument"); |
85 | usage(find_usage); | 161 | perm_mask = strtol(argv[i], &end, 8); |
86 | } | 162 | if (end[0] != '\0') |
87 | } | 163 | error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]); |
88 | break; | 164 | if (perm_mask > 07777) |
89 | case '-': | 165 | error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]); |
90 | /* Ignore all long options */ | 166 | if ((perm_char = argv[i][0]) == '-') |
91 | break; | 167 | perm_mask = -perm_mask; |
92 | default: | 168 | #endif |
93 | usage(find_usage); | 169 | #ifdef BB_FEATURE_FIND_MTIME |
94 | } | 170 | } else if (strcmp(argv[i], "-mtime") == 0) { |
95 | if (argc-- > 1) | 171 | char *end; |
96 | argv++; | 172 | if (++i == argc) |
97 | if (**argv != '-') | 173 | error_msg_and_die("option `-mtime' requires an argument"); |
98 | break; | 174 | mtime_days = strtol(argv[i], &end, 10); |
99 | else | 175 | if (end[0] != '\0') |
100 | break; | 176 | error_msg_and_die("invalid argument `%s' to `-mtime'", argv[i]); |
177 | if ((mtime_char = argv[i][0]) == '-') | ||
178 | mtime_days = -mtime_days; | ||
179 | #endif | ||
180 | } else | ||
181 | usage(find_usage); | ||
101 | } | 182 | } |
102 | 183 | ||
103 | if (recursive_action(directory, TRUE, FALSE, FALSE, | 184 | if (firstopt == 1) { |
104 | fileAction, fileAction, NULL) == FALSE) { | 185 | if (recursive_action(".", TRUE, dereference, FALSE, fileAction, |
105 | return EXIT_FAILURE; | 186 | fileAction, NULL) == FALSE) |
187 | status = EXIT_FAILURE; | ||
188 | } else { | ||
189 | for (i = 1; i < firstopt; i++) { | ||
190 | if (recursive_action(argv[i], TRUE, dereference, FALSE, fileAction, | ||
191 | fileAction, NULL) == FALSE) | ||
192 | status = EXIT_FAILURE; | ||
193 | } | ||
106 | } | 194 | } |
107 | 195 | ||
108 | return EXIT_SUCCESS; | 196 | return status; |
109 | } | 197 | } |