aboutsummaryrefslogtreecommitdiff
path: root/findutils/find.c
diff options
context:
space:
mode:
authorMatt Kraai <kraai@debian.org>2001-02-07 03:52:38 +0000
committerMatt Kraai <kraai@debian.org>2001-02-07 03:52:38 +0000
commit096370d349fb6be0f5754a9f1d1ca2910d33d78c (patch)
tree9a5c0ca1d70fdc842b949e3c59a2c59f5f889711 /findutils/find.c
parenta164c647acc613fe199a646dc5075c097f51a4a4 (diff)
downloadbusybox-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.c200
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
33static char *pattern = NULL; 38static char *pattern;
34static char *directory = "."; 39
35static int dereferenceFlag = FALSE; 40#ifdef BB_FEATURE_FIND_TYPE
41static int type_mask = 0;
42#endif
43
44#ifdef BB_FEATURE_FIND_PERM
45static char perm_char = 0;
46static int perm_mask = 0;
47#endif
48
49#ifdef BB_FEATURE_FIND_MTIME
50static char mtime_char;
51static int mtime_days;
52#endif
36 53
37static int fileAction(const char *fileName, struct stat *statbuf, void* junk) 54static 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);
92no_match:
51 return (TRUE); 93 return (TRUE);
52} 94}
53 95
96#ifdef BB_FEATURE_FIND_TYPE
97static 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
54int find_main(int argc, char **argv) 132int 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}