Mercurial > hg > toybox
comparison toys/pending/find.c @ 848:feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 10 Apr 2013 19:58:21 -0500 |
parents | 2506cbdccd20 |
children | 917d6e051b82 |
comparison
equal
deleted
inserted
replaced
847:2506cbdccd20 | 848:feea7a8ecbb1 |
---|---|
7 * See http://opengroup.org/onlinepubs/9699919799/utilities/find.html | 7 * See http://opengroup.org/onlinepubs/9699919799/utilities/find.html |
8 | 8 |
9 USE_FIND(NEWTOY(find, "?", TOYFLAG_USR|TOYFLAG_BIN)) | 9 USE_FIND(NEWTOY(find, "?", TOYFLAG_USR|TOYFLAG_BIN)) |
10 | 10 |
11 config FIND | 11 config FIND |
12 bool "find" | 12 bool "find" |
13 default n | 13 default n |
14 help | 14 help |
15 usage: find [<dir>] [<options] | 15 usage: find [<dir>] [<options] |
16 | 16 |
17 -name <pattern> match pattern | 17 -name <pattern> match pattern |
18 -type [fcdl] match file type | 18 -type [fcdl] match file type |
19 !, -a, -o not, and , or | 19 !, -a, -o not, and , or |
20 (, ) group expressions | 20 (, ) group expressions |
21 -mtime [-+]n match file modification time (to within 24 hours) | 21 -mtime [-+]n match file modification time (to within 24 hours) |
22 \t\t +=greater (older) than, -=less (younger) than | 22 \t\t +=greater (older) than, -=less (younger) than |
23 */ | 23 */ |
24 | 24 |
25 /* To Do: | 25 /* To Do: |
26 * -exec action | 26 * -exec action |
27 */ | 27 */ |
31 #define SECONDS_PER_DAY (24*60*60) | 31 #define SECONDS_PER_DAY (24*60*60) |
32 | 32 |
33 int have_action; | 33 int have_action; |
34 | 34 |
35 struct filter_node { | 35 struct filter_node { |
36 struct filter_node *next; | 36 struct filter_node *next; |
37 int op; | 37 int op; |
38 union { | 38 union { |
39 char *name_regex; | 39 char *name_regex; |
40 struct { | 40 struct { |
41 char time_op; | 41 char time_op; |
42 time_t time; | 42 time_t time; |
43 } t; | 43 } t; |
44 mode_t type; | 44 mode_t type; |
45 struct { | 45 struct { |
46 int arg_path_index; | 46 int arg_path_index; |
47 char **exec_args; | 47 char **exec_args; |
48 } e; | 48 } e; |
49 } data; | 49 } data; |
50 }; | 50 }; |
51 | 51 |
52 static struct filter_node *filter_root; | 52 static struct filter_node *filter_root; |
53 | 53 |
54 /* filter operation types */ | 54 /* filter operation types */ |
75 /* executes the command for a filter node | 75 /* executes the command for a filter node |
76 * return the program return value (0=success) | 76 * return the program return value (0=success) |
77 */ | 77 */ |
78 static int do_exec(struct filter_node *filter, struct dirtree *node) | 78 static int do_exec(struct filter_node *filter, struct dirtree *node) |
79 { | 79 { |
80 char *path; | 80 char *path; |
81 int plen; | 81 int plen; |
82 char **arg_array; | 82 char **arg_array; |
83 pid_t pid; | 83 pid_t pid; |
84 int ccode; | 84 int ccode; |
85 int status; | 85 int status; |
86 | 86 |
87 arg_array = filter->data.e.exec_args; | 87 arg_array = filter->data.e.exec_args; |
88 if (filter->data.e.arg_path_index) { | 88 if (filter->data.e.arg_path_index) { |
89 path = dirtree_path(node, &plen); | 89 path = dirtree_path(node, &plen); |
90 arg_array[filter->data.e.arg_path_index] = path; | 90 arg_array[filter->data.e.arg_path_index] = path; |
91 } else { | 91 } else { |
92 path = NULL; | 92 path = NULL; |
93 } | 93 } |
94 | 94 |
95 pid = fork(); | 95 pid = fork(); |
96 if (!pid) { | 96 if (!pid) { |
97 /* child */ | 97 /* child */ |
98 xexec(arg_array); | 98 xexec(arg_array); |
99 } else { | 99 } else { |
100 /* parent */ | 100 /* parent */ |
101 /* wait for child */ | 101 /* wait for child */ |
102 waitpid(pid, &status, 0); | 102 waitpid(pid, &status, 0); |
103 ccode = WEXITSTATUS(status); | 103 ccode = WEXITSTATUS(status); |
104 } | 104 } |
105 free(path); | 105 free(path); |
106 | 106 |
107 return ccode; | 107 return ccode; |
108 } | 108 } |
109 | 109 |
110 /* prefix evaluator */ | 110 /* prefix evaluator */ |
111 /* returns 0 for failure or 1 for success */ | 111 /* returns 0 for failure or 1 for success */ |
112 static int evaluate(struct filter_node *filter, struct dirtree *node, | 112 static int evaluate(struct filter_node *filter, struct dirtree *node, |
113 struct filter_node **fnext) | 113 struct filter_node **fnext) |
114 { | 114 { |
115 int result; | 115 int result; |
116 char *path; | 116 char *path; |
117 int plen = 0; | 117 int plen = 0; |
118 struct stat st_buf; | 118 struct stat st_buf; |
119 time_t node_time; | 119 time_t node_time; |
120 char terminator; | 120 char terminator; |
121 | 121 |
122 /* if no filters, success */ | 122 /* if no filters, success */ |
123 if (!filter) { | 123 if (!filter) { |
124 *fnext = NULL; | 124 *fnext = NULL; |
125 return 1; | 125 return 1; |
126 } | 126 } |
127 | 127 |
128 if (filter->op==OP_NOT) { | 128 if (filter->op==OP_NOT) { |
129 return !evaluate(filter->next, node, fnext); | 129 return !evaluate(filter->next, node, fnext); |
130 } | 130 } |
131 if (filter->op==OP_OR) { | 131 if (filter->op==OP_OR) { |
132 return evaluate(filter->next, node, fnext) || evaluate(*fnext, node, fnext); | 132 return evaluate(filter->next, node, fnext) || evaluate(*fnext, node, fnext); |
133 } | 133 } |
134 if (filter->op==OP_AND) { | 134 if (filter->op==OP_AND) { |
135 return evaluate(filter->next, node, fnext) && evaluate(*fnext, node, fnext); | 135 return evaluate(filter->next, node, fnext) && evaluate(*fnext, node, fnext); |
136 } | 136 } |
137 /* we're down to single operations, mark our position */ | 137 /* we're down to single operations, mark our position */ |
138 *fnext = filter->next; | 138 *fnext = filter->next; |
139 if (filter->op==CHECK_NAME) { | 139 if (filter->op==CHECK_NAME) { |
140 // TODO: Do a regex comparison | 140 // TODO: Do a regex comparison |
141 return !strcmp(filter->data.name_regex, node->name); | 141 return !strcmp(filter->data.name_regex, node->name); |
142 } | 142 } |
143 if (filter->op==CHECK_MTIME) { | 143 if (filter->op==CHECK_MTIME) { |
144 /* do mtime check */ | 144 /* do mtime check */ |
145 path = dirtree_path(node, &plen); | 145 path = dirtree_path(node, &plen); |
146 result = stat(path, &st_buf); | 146 result = stat(path, &st_buf); |
147 free(path); | 147 free(path); |
148 if (result<0) { | 148 if (result<0) { |
149 return 0; | 149 return 0; |
150 } | 150 } |
151 node_time = st_buf.st_mtime/SECONDS_PER_DAY; | 151 node_time = st_buf.st_mtime/SECONDS_PER_DAY; |
152 result = 1; | 152 result = 1; |
153 switch (filter->data.t.time_op) { | 153 switch (filter->data.t.time_op) { |
154 /* do time compare here */ | 154 /* do time compare here */ |
155 case TEST_LT: | 155 case TEST_LT: |
156 /* FIXTHIS - should result be < or <= ?*/ | 156 /* FIXTHIS - should result be < or <= ?*/ |
157 if (node_time > filter->data.t.time) | 157 if (node_time > filter->data.t.time) |
158 result = 0; | 158 result = 0; |
159 break; | 159 break; |
160 case TEST_GT: | 160 case TEST_GT: |
161 if (node_time < filter->data.t.time) | 161 if (node_time < filter->data.t.time) |
162 result = 0; | 162 result = 0; |
163 break; | 163 break; |
164 case TEST_EQ: | 164 case TEST_EQ: |
165 if (node_time != filter->data.t.time) | 165 if (node_time != filter->data.t.time) |
166 result = 0; | 166 result = 0; |
167 break; | 167 break; |
168 default: | 168 default: |
169 /* how'd I get here? */ | 169 /* how'd I get here? */ |
170 result = 0; | 170 result = 0; |
171 break; | 171 break; |
172 } | 172 } |
173 return result; | 173 return result; |
174 | 174 |
175 } | 175 } |
176 if (filter->op==CHECK_TYPE) { | 176 if (filter->op==CHECK_TYPE) { |
177 path = dirtree_path(node, &plen); | 177 path = dirtree_path(node, &plen); |
178 result = lstat(path, &st_buf); | 178 result = lstat(path, &st_buf); |
179 free(path); | 179 free(path); |
180 if (result<0) { | 180 if (result<0) { |
181 return 0; | 181 return 0; |
182 } | 182 } |
183 return (st_buf.st_mode & S_IFMT) == filter->data.type; | 183 return (st_buf.st_mode & S_IFMT) == filter->data.type; |
184 } | 184 } |
185 | 185 |
186 | 186 |
187 if (filter->op==ACTION_PRINT || filter->op==ACTION_PRINT0) { | 187 if (filter->op==ACTION_PRINT || filter->op==ACTION_PRINT0) { |
188 if (filter->op==ACTION_PRINT) { | 188 if (filter->op==ACTION_PRINT) { |
189 terminator = '\n'; | 189 terminator = '\n'; |
190 } else { | 190 } else { |
191 terminator = 0; | 191 terminator = 0; |
192 } | 192 } |
193 path = dirtree_path(node, &plen); | 193 path = dirtree_path(node, &plen); |
194 printf("%s%c", path, terminator); | 194 printf("%s%c", path, terminator); |
195 free(path); | 195 free(path); |
196 return 1; | 196 return 1; |
197 } | 197 } |
198 | 198 |
199 if (filter->op==ACTION_EXEC) { | 199 if (filter->op==ACTION_EXEC) { |
200 return !do_exec(filter, node); | 200 return !do_exec(filter, node); |
201 } | 201 } |
202 error_msg("Ran out of operations in filter list!"); | 202 error_msg("Ran out of operations in filter list!"); |
203 return 1; | 203 return 1; |
204 } | 204 } |
205 | 205 |
206 static int check_node_callback(struct dirtree *node) | 206 static int check_node_callback(struct dirtree *node) |
207 { | 207 { |
208 char *path; | 208 char *path; |
209 int plen = 0; | 209 int plen = 0; |
210 int result; | 210 int result; |
211 struct filter_node *junk; | 211 struct filter_node *junk; |
212 | 212 |
213 /* only recurse on "." at the root */ | 213 /* only recurse on "." at the root */ |
214 /* so, don't recurse on 1) non-root "." and 2) any ".." */ | 214 /* so, don't recurse on 1) non-root "." and 2) any ".." */ |
215 | 215 |
216 if (node->name[0] == '.' && | 216 if (node->name[0] == '.' && |
217 ((!node->name[1] && node->parent) || | 217 ((!node->name[1] && node->parent) || |
218 (node->name[1]=='.' && !node->name[2]))) | 218 (node->name[1]=='.' && !node->name[2]))) |
219 return 0; | 219 return 0; |
220 | 220 |
221 result = evaluate(filter_root, node, &junk); | 221 result = evaluate(filter_root, node, &junk); |
222 if (result & !have_action) { | 222 if (result & !have_action) { |
223 /* default action is just print the path */ | 223 /* default action is just print the path */ |
224 path = dirtree_path(node, &plen); | 224 path = dirtree_path(node, &plen); |
225 printf("%s\n", path); | 225 printf("%s\n", path); |
226 free(path); | 226 free(path); |
227 } | 227 } |
228 return DIRTREE_RECURSE; | 228 return DIRTREE_RECURSE; |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 static void build_filter_list(void) | 232 static void build_filter_list(void) |
233 { | 233 { |
234 struct filter_node *node_list; | 234 struct filter_node *node_list; |
235 struct filter_node *op_stack; | 235 struct filter_node *op_stack; |
236 struct filter_node *node, *op_node; | 236 struct filter_node *node, *op_node; |
237 struct filter_node *next; | 237 struct filter_node *next; |
238 | 238 |
239 char *arg, **arg_array; | 239 char *arg, **arg_array; |
240 int i, j; | 240 int i, j; |
241 | 241 |
242 /* part optargs here and build a filter list in prefix format */ | 242 /* part optargs here and build a filter list in prefix format */ |
243 | 243 |
244 node_list = NULL; | 244 node_list = NULL; |
245 toybuf[0] = 0; | 245 toybuf[0] = 0; |
246 have_action = 0; | 246 have_action = 0; |
247 for(i=0; toys.optargs[i]; i++) { | 247 for(i=0; toys.optargs[i]; i++) { |
248 node = (struct filter_node *) | 248 node = (struct filter_node *) |
249 xmalloc(sizeof(struct filter_node)); | 249 xmalloc(sizeof(struct filter_node)); |
250 node->op = OP_UNKNOWN; | 250 node->op = OP_UNKNOWN; |
251 arg = toys.optargs[i]; | 251 arg = toys.optargs[i]; |
252 if (!strcmp(arg, "-o")) { | 252 if (!strcmp(arg, "-o")) { |
253 node->op = OP_OR; | 253 node->op = OP_OR; |
254 } | 254 } |
255 if (!strcmp(arg, "-a")) { | 255 if (!strcmp(arg, "-a")) { |
256 node->op = OP_AND; | 256 node->op = OP_AND; |
257 } | 257 } |
258 if (!strcmp(arg, "!")) { | 258 if (!strcmp(arg, "!")) { |
259 node->op = OP_NOT; | 259 node->op = OP_NOT; |
260 } | 260 } |
261 if (!strcmp(arg, "(")) { | 261 if (!strcmp(arg, "(")) { |
262 node->op = LPAREN; | 262 node->op = LPAREN; |
263 } | 263 } |
264 if (!strcmp(arg, ")")) { | 264 if (!strcmp(arg, ")")) { |
265 node->op = RPAREN; | 265 node->op = RPAREN; |
266 } | 266 } |
267 | 267 |
268 if (!strcmp(arg, "-name")) { | 268 if (!strcmp(arg, "-name")) { |
269 node->op = CHECK_NAME; | 269 node->op = CHECK_NAME; |
270 arg = toys.optargs[++i]; | 270 arg = toys.optargs[++i]; |
271 if (!arg) error_exit("Missing argument to -name\n"); | 271 if (!arg) error_exit("Missing argument to -name\n"); |
272 node->data.name_regex = arg; | 272 node->data.name_regex = arg; |
273 } | 273 } |
274 | 274 |
275 if (!strcmp(arg, "-mtime")) { | 275 if (!strcmp(arg, "-mtime")) { |
276 node->op = CHECK_MTIME; | 276 node->op = CHECK_MTIME; |
277 arg = toys.optargs[++i]; | 277 arg = toys.optargs[++i]; |
278 if (!arg) error_exit("Missing argument to -mtime\n"); | 278 if (!arg) error_exit("Missing argument to -mtime\n"); |
279 switch(arg[0]) { | 279 switch(arg[0]) { |
280 case '+': | 280 case '+': |
281 node->data.t.time_op=TEST_GT; | 281 node->data.t.time_op=TEST_GT; |
282 arg++; | 282 arg++; |
283 break; | 283 break; |
284 case '-': | 284 case '-': |
285 node->data.t.time_op=TEST_LT; | 285 node->data.t.time_op=TEST_LT; |
286 arg++; | 286 arg++; |
287 break; | 287 break; |
288 default: | 288 default: |
289 node->data.t.time_op=TEST_EQ; | 289 node->data.t.time_op=TEST_EQ; |
290 break; | 290 break; |
291 } | 291 } |
292 /* convert to days (very crudely) */ | 292 /* convert to days (very crudely) */ |
293 node->data.t.time = atoi(arg)/SECONDS_PER_DAY; | 293 node->data.t.time = atoi(arg)/SECONDS_PER_DAY; |
294 } | 294 } |
295 | 295 |
296 if (!strcmp(arg, "-type")) { | 296 if (!strcmp(arg, "-type")) { |
297 node->op = CHECK_TYPE; | 297 node->op = CHECK_TYPE; |
298 arg = toys.optargs[++i]; | 298 arg = toys.optargs[++i]; |
299 if (!arg) error_exit("Missing argument to -type\n"); | 299 if (!arg) error_exit("Missing argument to -type\n"); |
300 switch(arg[0]) { | 300 switch(arg[0]) { |
301 case 'f': | 301 case 'f': |
302 node->data.type = S_IFREG; | 302 node->data.type = S_IFREG; |
303 break; | 303 break; |
304 case 'd': | 304 case 'd': |
305 node->data.type = S_IFDIR; | 305 node->data.type = S_IFDIR; |
306 break; | 306 break; |
307 case 'c': | 307 case 'c': |
308 node->data.type = S_IFCHR; | 308 node->data.type = S_IFCHR; |
309 break; | 309 break; |
310 case 'b': | 310 case 'b': |
311 node->data.type = S_IFBLK; | 311 node->data.type = S_IFBLK; |
312 break; | 312 break; |
313 case 'l': | 313 case 'l': |
314 node->data.type = S_IFLNK; | 314 node->data.type = S_IFLNK; |
315 break; | 315 break; |
316 case 's': | 316 case 's': |
317 node->data.type = S_IFSOCK; | 317 node->data.type = S_IFSOCK; |
318 break; | 318 break; |
319 case 'p': | 319 case 'p': |
320 /* named pipe */ | 320 /* named pipe */ |
321 node->data.type = S_IFIFO; | 321 node->data.type = S_IFIFO; |
322 break; | 322 break; |
323 default: | 323 default: |
324 error_exit("Unknown file type '%s'\n", arg); | 324 error_exit("Unknown file type '%s'\n", arg); |
325 } | 325 } |
326 } | 326 } |
327 if (!strcmp(arg, "-print")) { | 327 if (!strcmp(arg, "-print")) { |
328 node->op = ACTION_PRINT; | 328 node->op = ACTION_PRINT; |
329 have_action = 1; | 329 have_action = 1; |
330 } | 330 } |
331 if (!strcmp(arg, "-print0")) { | 331 if (!strcmp(arg, "-print0")) { |
332 node->op = ACTION_PRINT0; | 332 node->op = ACTION_PRINT0; |
333 have_action = 1; | 333 have_action = 1; |
334 } | 334 } |
335 if (!strcmp(arg, "-exec")) { | 335 if (!strcmp(arg, "-exec")) { |
336 node->op = ACTION_EXEC; | 336 node->op = ACTION_EXEC; |
337 have_action = 1; | 337 have_action = 1; |
338 arg_array = xmalloc(sizeof(char *)); | 338 arg_array = xmalloc(sizeof(char *)); |
339 arg = toys.optargs[++i]; | 339 arg = toys.optargs[++i]; |
340 for (j = 0; arg && strcmp(arg, ";"); j++) { | 340 for (j = 0; arg && strcmp(arg, ";"); j++) { |
341 /* new method */ | 341 /* new method */ |
342 arg_array = xrealloc(arg_array, sizeof(char *) * (j+2)); | 342 arg_array = xrealloc(arg_array, sizeof(char *) * (j+2)); |
343 arg_array[j] = arg; | 343 arg_array[j] = arg; |
344 if (!strcmp(arg, "{}")) { | 344 if (!strcmp(arg, "{}")) { |
345 node->data.e.arg_path_index = j; | 345 node->data.e.arg_path_index = j; |
346 } | 346 } |
347 | 347 |
348 arg = toys.optargs[++i]; | 348 arg = toys.optargs[++i]; |
349 } | 349 } |
350 if (!arg) error_exit("Missing ';' in exec command\n"); | 350 if (!arg) error_exit("Missing ';' in exec command\n"); |
351 arg_array[j] = 0; | 351 arg_array[j] = 0; |
352 node->data.e.exec_args = arg_array; | 352 node->data.e.exec_args = arg_array; |
353 } | 353 } |
354 if (node->op == OP_UNKNOWN) { | 354 if (node->op == OP_UNKNOWN) { |
355 if (arg[0] == '-') error_exit("Unknown option '%s'\n", arg); | 355 if (arg[0] == '-') error_exit("Unknown option '%s'\n", arg); |
356 else { | 356 else { |
357 /* use toybuf as start directory */ | 357 /* use toybuf as start directory */ |
358 strcpy(toybuf, arg); | 358 strcpy(toybuf, arg); |
359 } | 359 } |
360 } else { | 360 } else { |
361 /* push node */ | 361 /* push node */ |
362 node->next = node_list;; | 362 node->next = node_list;; |
363 node_list = node; | 363 node_list = node; |
364 } | 364 } |
365 | 365 |
366 } | 366 } |
367 | 367 |
368 /* now convert from infix to prefix */ | 368 /* now convert from infix to prefix */ |
369 filter_root = NULL; | 369 filter_root = NULL; |
370 op_stack = NULL; | 370 op_stack = NULL; |
371 node = node_list; | 371 node = node_list; |
372 while( node ) { | 372 while( node ) { |
373 next = node->next; | 373 next = node->next; |
374 switch( node->op ) { | 374 switch( node->op ) { |
375 case OP_AND: | 375 case OP_AND: |
376 case OP_OR: | 376 case OP_OR: |
377 case OP_NOT: | 377 case OP_NOT: |
378 case RPAREN: | 378 case RPAREN: |
379 /* push to opstack */ | 379 /* push to opstack */ |
380 node->next = op_stack; | 380 node->next = op_stack; |
381 op_stack = node; | 381 op_stack = node; |
382 break; | 382 break; |
383 case LPAREN: | 383 case LPAREN: |
384 free(node); | 384 free(node); |
385 /* pop opstack to output (up to rparen) */ | 385 /* pop opstack to output (up to rparen) */ |
386 op_node = op_stack; | 386 op_node = op_stack; |
387 while (op_node && op_node->op != RPAREN) { | 387 while (op_node && op_node->op != RPAREN) { |
388 /* remove from op_stack */ | 388 /* remove from op_stack */ |
389 op_stack = op_node->next; | 389 op_stack = op_node->next; |
390 /* push to output */ | 390 /* push to output */ |
391 op_node->next = filter_root; | 391 op_node->next = filter_root; |
392 filter_root = op_node; | 392 filter_root = op_node; |
393 /* get next node */ | 393 /* get next node */ |
394 op_node = op_stack; | 394 op_node = op_stack; |
395 } | 395 } |
396 /* rparen should be on op_stack */ | 396 /* rparen should be on op_stack */ |
397 if (!op_stack) error_exit("Missing right paren\n"); | 397 if (!op_stack) error_exit("Missing right paren\n"); |
398 /* remove rparen from op_stack */ | 398 /* remove rparen from op_stack */ |
399 op_stack = op_stack->next; | 399 op_stack = op_stack->next; |
400 free(op_node); | 400 free(op_node); |
401 break; | 401 break; |
402 default: | 402 default: |
403 /* push to output */ | 403 /* push to output */ |
404 node->next = filter_root; | 404 node->next = filter_root; |
405 filter_root = node; | 405 filter_root = node; |
406 break; | 406 break; |
407 } | 407 } |
408 node = next; | 408 node = next; |
409 } | 409 } |
410 /* end of input - push opstack to output */ | 410 /* end of input - push opstack to output */ |
411 /* pop opstack to output till empty */ | 411 /* pop opstack to output till empty */ |
412 op_node = op_stack; | 412 op_node = op_stack; |
413 while (op_node) { | 413 while (op_node) { |
414 /*if (op_node->op == RPAREN || op_node->op == LPAREN) { | 414 /*if (op_node->op == RPAREN || op_node->op == LPAREN) { |
415 error_exit("Error: extra paren found\n"); | 415 error_exit("Error: extra paren found\n"); |
416 } | 416 } |
417 */ | 417 */ |
418 op_stack = op_node->next; | 418 op_stack = op_node->next; |
419 op_node->next = filter_root; | 419 op_node->next = filter_root; |
420 filter_root = op_node; | 420 filter_root = op_node; |
421 op_node = op_stack; | 421 op_node = op_stack; |
422 } | 422 } |
423 } | 423 } |
424 | 424 |
425 void find_main(void) | 425 void find_main(void) |
426 { | 426 { |
427 /* parse filters, if present */ | 427 /* parse filters, if present */ |
428 /* also, fill toybuf with the directory to start in, if present */ | 428 /* also, fill toybuf with the directory to start in, if present */ |
429 build_filter_list(); | 429 build_filter_list(); |
430 | 430 |
431 /* FIXTHIS - parse actions, if present */ | 431 /* FIXTHIS - parse actions, if present */ |
432 | 432 |
433 if (!toybuf[0]) { | 433 if (!toybuf[0]) { |
434 strcpy(toybuf, "."); | 434 strcpy(toybuf, "."); |
435 } | 435 } |
436 dirtree_read(toybuf, check_node_callback); | 436 dirtree_read(toybuf, check_node_callback); |
437 } | 437 } |