files created by new automake/autoconf.
[findutils.git] / find / find.c
blob1de229f00567edcb46c58dcb8f5a6f670793d147
1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* GNU find was written by Eric Decker <cire@cisco.com>,
19 with enhancements by David MacKenzie <djm@gnu.ai.mit.edu>,
20 Jay Plett <jay@silence.princeton.nj.us>,
21 and Tim Wood <axolotl!tim@toad.com>.
22 The idea for -print0 and xargs -0 came from
23 Dan Bernstein <brnstnd@kramden.acf.nyu.edu>. */
25 #include "defs.h"
27 #ifdef HAVE_FCNTL_H
28 #include <fcntl.h>
29 #else
30 #include <sys/file.h>
31 #endif
32 #include <human.h>
33 #include <modetype.h>
34 #include <savedir.h>
36 #ifdef HAVE_LOCALE_H
37 #include <locale.h>
38 #endif
40 #if ENABLE_NLS
41 # include <libintl.h>
42 # define _(Text) gettext (Text)
43 #else
44 # define _(Text) Text
45 #define textdomain(Domain)
46 #define bindtextdomain(Package, Directory)
47 #endif
48 #ifdef gettext_noop
49 # define N_(String) gettext_noop (String)
50 #else
51 # define N_(String) (String)
52 #endif
54 #define apply_predicate(pathname, stat_buf_ptr, node) \
55 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
57 static void process_top_path PARAMS((char *pathname));
58 static int process_path PARAMS((char *pathname, char *name, boolean leaf, char *parent));
59 static void process_dir PARAMS((char *pathname, char *name, int pathlen, struct stat *statp, char *parent));
60 static boolean no_side_effects PARAMS((struct predicate *pred));
61 static boolean default_prints PARAMS((struct predicate *pred));
63 /* Name this program was run with. */
64 char *program_name;
66 /* All predicates for each path to process. */
67 struct predicate *predicates;
69 /* The last predicate allocated. */
70 struct predicate *last_pred;
72 /* The root of the evaluation tree. */
73 static struct predicate *eval_tree;
75 /* If true, process directory before contents. True unless -depth given. */
76 boolean do_dir_first;
78 /* If >=0, don't descend more than this many levels of subdirectories. */
79 int maxdepth;
81 /* If >=0, don't process files above this level. */
82 int mindepth;
84 /* Current depth; 0 means current path is a command line arg. */
85 int curdepth;
87 /* Output block size. */
88 int output_block_size;
90 /* Time at start of execution. */
91 time_t start_time;
93 /* Seconds between 00:00 1/1/70 and either one day before now
94 (the default), or the start of today (if -daystart is given). */
95 time_t cur_day_start;
97 /* If true, cur_day_start has been adjusted to the start of the day. */
98 boolean full_days;
100 /* If true, do not assume that files in directories with nlink == 2
101 are non-directories. */
102 boolean no_leaf_check;
104 /* If true, don't cross filesystem boundaries. */
105 boolean stay_on_filesystem;
107 /* If true, don't descend past current directory.
108 Can be set by -prune, -maxdepth, and -xdev/-mount. */
109 boolean stop_at_current_level;
111 /* The full path of the initial working directory, or "." if
112 STARTING_DESC is nonnegative. */
113 char const *starting_dir = ".";
115 /* A file descriptor open to the initial working directory.
116 Doing it this way allows us to work when the i.w.d. has
117 unreadable parents. */
118 int starting_desc;
120 /* The stat buffer of the initial working directory. */
121 struct stat starting_stat_buf;
123 /* If true, we have called stat on the current path. */
124 boolean have_stat;
126 /* The file being operated on, relative to the current directory.
127 Used for stat, readlink, remove, and opendir. */
128 char *rel_pathname;
130 /* Length of current path. */
131 int path_length;
133 /* true if following symlinks. Should be consistent with xstat. */
134 boolean dereference;
136 /* Pointer to the function used to stat files. */
137 int (*xstat) ();
139 /* Status value to return to system. */
140 int exit_status;
142 #ifdef DEBUG_STAT
143 static int
144 debug_stat (file, bufp)
145 char *file;
146 struct stat *bufp;
148 fprintf (stderr, "debug_stat (%s)\n", file);
149 return lstat (file, bufp);
151 #endif /* DEBUG_STAT */
154 main (int argc, char **argv)
156 int i;
157 PFB parse_function; /* Pointer to the function which parses. */
158 struct predicate *cur_pred;
159 char *predicate_name; /* Name of predicate being parsed. */
161 program_name = argv[0];
163 #ifdef HAVE_SETLOCALE
164 setlocale (LC_ALL, "");
165 #endif
166 bindtextdomain (PACKAGE, LOCALEDIR);
167 textdomain (PACKAGE);
169 predicates = NULL;
170 last_pred = NULL;
171 do_dir_first = true;
172 maxdepth = mindepth = -1;
173 start_time = time (NULL);
174 cur_day_start = start_time - DAYSECS;
175 full_days = false;
176 no_leaf_check = false;
177 stay_on_filesystem = false;
178 exit_status = 0;
179 dereference = false;
180 #ifdef DEBUG_STAT
181 xstat = debug_stat;
182 #else /* !DEBUG_STAT */
183 xstat = lstat;
184 #endif /* !DEBUG_STAT */
186 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size);
188 #ifdef DEBUG
189 printf ("cur_day_start = %s", ctime (&cur_day_start));
190 #endif /* DEBUG */
192 /* Find where in ARGV the predicates begin. */
193 for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
194 /* Do nothing. */ ;
196 /* Enclose the expression in `( ... )' so a default -print will
197 apply to the whole expression. */
198 parse_open (argv, &argc);
199 /* Build the input order list. */
200 while (i < argc)
202 if (strchr ("-!(),", argv[i][0]) == NULL)
203 usage (_("paths must precede expression"));
204 predicate_name = argv[i];
205 parse_function = find_parser (predicate_name);
206 if (parse_function == NULL)
207 /* Command line option not recognized */
208 error (1, 0, _("invalid predicate `%s'"), predicate_name);
209 i++;
210 if (!(*parse_function) (argv, &i))
212 if (argv[i] == NULL)
213 /* Command line option requires an argument */
214 error (1, 0, _("missing argument to `%s'"), predicate_name);
215 else
216 error (1, 0, _("invalid argument `%s' to `%s'"),
217 argv[i], predicate_name);
220 if (predicates->pred_next == NULL)
222 /* No predicates that do something other than set a global variable
223 were given; remove the unneeded initial `(' and add `-print'. */
224 cur_pred = predicates;
225 predicates = last_pred = predicates->pred_next;
226 free ((char *) cur_pred);
227 parse_print (argv, &argc);
229 else if (!default_prints (predicates->pred_next))
231 /* One or more predicates that produce output were given;
232 remove the unneeded initial `('. */
233 cur_pred = predicates;
234 predicates = predicates->pred_next;
235 free ((char *) cur_pred);
237 else
239 /* `( user-supplied-expression ) -print'. */
240 parse_close (argv, &argc);
241 parse_print (argv, &argc);
244 #ifdef DEBUG
245 printf (_("Predicate List:\n"));
246 print_list (predicates);
247 #endif /* DEBUG */
249 /* Done parsing the predicates. Build the evaluation tree. */
250 cur_pred = predicates;
251 eval_tree = get_expr (&cur_pred, NO_PREC);
252 #ifdef DEBUG
253 printf (_("Eval Tree:\n"));
254 print_tree (eval_tree, 0);
255 #endif /* DEBUG */
257 /* Rearrange the eval tree in optimal-predicate order. */
258 opt_expr (&eval_tree);
260 /* Determine the point, if any, at which to stat the file. */
261 mark_stat (eval_tree);
263 #ifdef DEBUG
264 printf (_("Optimized Eval Tree:\n"));
265 print_tree (eval_tree, 0);
266 #endif /* DEBUG */
268 starting_desc = open (".", O_RDONLY);
269 if (0 <= starting_desc && fchdir (starting_desc) != 0)
271 close (starting_desc);
272 starting_desc = -1;
274 if (starting_desc < 0)
276 starting_dir = xgetcwd ();
277 if (! starting_dir)
278 error (1, errno, _("cannot get current directory"));
280 if ((*xstat) (".", &starting_stat_buf) != 0)
281 error (1, errno, _("cannot get current directory"));
283 /* If no paths are given, default to ".". */
284 for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
285 process_top_path (argv[i]);
286 if (i == 1)
287 process_top_path (".");
289 exit (exit_status);
292 /* Safely go back to the starting directory. */
293 static void
294 chdir_back (void)
296 struct stat stat_buf;
298 if (starting_desc < 0)
300 if (chdir (starting_dir) != 0)
301 error (1, errno, "%s", starting_dir);
302 if ((*xstat) (".", &stat_buf) != 0)
303 error (1, errno, "%s", starting_dir);
304 if (stat_buf.st_dev != starting_stat_buf.st_dev ||
305 stat_buf.st_ino != starting_stat_buf.st_ino)
306 error (1, 0, _("%s changed during execution of %s"), starting_dir, program_name);
308 else
310 if (fchdir (starting_desc) != 0)
311 error (1, errno, "%s", starting_dir);
315 /* Descend PATHNAME, which is a command-line argument. */
317 static void
318 process_top_path (char *pathname)
320 struct stat stat_buf, cur_stat_buf;
322 curdepth = 0;
323 path_length = strlen (pathname);
325 /* We stat each pathname given on the command-line twice --
326 once here and once in process_path. It's not too bad, though,
327 since the kernel can read the stat information out of its inode
328 cache the second time. */
329 if ((*xstat) (pathname, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
331 if (chdir (pathname) < 0)
333 error (0, errno, "%s", pathname);
334 exit_status = 1;
335 return;
338 /* Check that we are where we should be. */
339 if ((*xstat) (".", &cur_stat_buf) != 0)
340 error (1, errno, "%s", pathname);
341 if (cur_stat_buf.st_dev != stat_buf.st_dev ||
342 cur_stat_buf.st_ino != stat_buf.st_ino)
343 error (1, 0, _("%s changed during execution of %s"), pathname, program_name);
345 process_path (pathname, ".", false, ".");
346 chdir_back ();
348 else
349 process_path (pathname, pathname, false, ".");
352 /* Info on each directory in the current tree branch, to avoid
353 getting stuck in symbolic link loops. */
354 struct dir_id
356 ino_t ino;
357 dev_t dev;
359 static struct dir_id *dir_ids = NULL;
360 /* Entries allocated in `dir_ids'. */
361 static int dir_alloc = 0;
362 /* Index in `dir_ids' of directory currently being searched.
363 This is always the last valid entry. */
364 static int dir_curr = -1;
365 /* (Arbitrary) number of entries to grow `dir_ids' by. */
366 #define DIR_ALLOC_STEP 32
368 /* Recursively descend path PATHNAME, applying the predicates.
369 LEAF is true if PATHNAME is known to be in a directory that has no
370 more unexamined subdirectories, and therefore it is not a directory.
371 Knowing this allows us to avoid calling stat as long as possible for
372 leaf files.
374 NAME is PATHNAME relative to the current directory. We access NAME
375 but print PATHNAME.
377 PARENT is the path of the parent of NAME, relative to find's
378 starting directory.
380 Return nonzero iff PATHNAME is a directory. */
382 static int
383 process_path (char *pathname, char *name, boolean leaf, char *parent)
385 struct stat stat_buf;
386 static dev_t root_dev; /* Device ID of current argument pathname. */
387 int i;
388 struct stat dir_buf;
389 int parent_desc;
391 /* Assume it is a non-directory initially. */
392 stat_buf.st_mode = 0;
394 rel_pathname = name;
396 if (leaf)
397 have_stat = false;
398 else
400 if ((*xstat) (name, &stat_buf) != 0)
402 error (0, errno, "%s", pathname);
403 exit_status = 1;
404 return 0;
406 have_stat = true;
409 if (!S_ISDIR (stat_buf.st_mode))
411 if (curdepth >= mindepth)
412 apply_predicate (pathname, &stat_buf, eval_tree);
413 return 0;
416 /* From here on, we're working on a directory. */
418 stop_at_current_level = maxdepth >= 0 && curdepth >= maxdepth;
420 /* If we've already seen this directory on this branch,
421 don't descend it again. */
422 for (i = 0; i <= dir_curr; i++)
423 if (stat_buf.st_ino == dir_ids[i].ino &&
424 stat_buf.st_dev == dir_ids[i].dev)
425 stop_at_current_level = true;
427 if (dir_alloc <= ++dir_curr)
429 dir_alloc += DIR_ALLOC_STEP;
430 dir_ids = (struct dir_id *)
431 xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
433 dir_ids[dir_curr].ino = stat_buf.st_ino;
434 dir_ids[dir_curr].dev = stat_buf.st_dev;
436 if (stay_on_filesystem)
438 if (curdepth == 0)
439 root_dev = stat_buf.st_dev;
440 else if (stat_buf.st_dev != root_dev)
441 stop_at_current_level = true;
444 if (do_dir_first && curdepth >= mindepth)
445 apply_predicate (pathname, &stat_buf, eval_tree);
447 #ifdef DEBUG
448 fprintf(stderr, "pathname = %s, stop_at_current_level = %d\n",
449 pathname, stop_at_current_level);
450 #endif /* DEBUG */
452 if (stop_at_current_level == false)
453 /* Scan directory on disk. */
454 process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
456 if (do_dir_first == false && curdepth >= mindepth)
458 rel_pathname = name;
459 apply_predicate (pathname, &stat_buf, eval_tree);
462 dir_curr--;
464 return 1;
467 /* Scan directory PATHNAME and recurse through process_path for each entry.
469 PATHLEN is the length of PATHNAME.
471 NAME is PATHNAME relative to the current directory.
473 STATP is the results of *xstat on it.
475 PARENT is the path of the parent of NAME, relative to find's
476 starting directory. */
478 static void
479 process_dir (char *pathname, char *name, int pathlen, struct stat *statp, char *parent)
481 char *name_space; /* Names of files in PATHNAME. */
482 int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
483 struct stat stat_buf;
485 subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
487 errno = 0;
488 name_space = savedir (name, statp->st_size);
489 if (name_space == NULL)
491 if (errno)
493 error (0, errno, "%s", pathname);
494 exit_status = 1;
496 else
497 error (1, 0, _("virtual memory exhausted"));
499 else
501 register char *namep; /* Current point in `name_space'. */
502 char *cur_path; /* Full path of each file to process. */
503 char *cur_name; /* Base name of each file to process. */
504 unsigned cur_path_size; /* Bytes allocated for `cur_path'. */
505 register unsigned file_len; /* Length of each path to process. */
506 register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
508 if (pathname[pathlen - 1] == '/')
509 pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
510 else
511 pathname_len = pathlen + 2; /* For '/' and '\0'. */
512 cur_path_size = 0;
513 cur_path = NULL;
515 if (strcmp (name, ".") && chdir (name) < 0)
517 error (0, errno, "%s", pathname);
518 exit_status = 1;
519 return;
522 /* Check that we are where we should be. */
523 if ((*xstat) (".", &stat_buf) != 0)
524 error (1, errno, "%s", pathname);
525 if (stat_buf.st_dev != dir_ids[dir_curr].dev ||
526 stat_buf.st_ino != dir_ids[dir_curr].ino)
527 error (1, 0, _("%s changed during execution of %s"), starting_dir, program_name);
529 for (namep = name_space; *namep; namep += file_len - pathname_len + 1)
531 /* Append this directory entry's name to the path being searched. */
532 file_len = pathname_len + strlen (namep);
533 if (file_len > cur_path_size)
535 while (file_len > cur_path_size)
536 cur_path_size += 1024;
537 if (cur_path)
538 free (cur_path);
539 cur_path = xmalloc (cur_path_size);
540 strcpy (cur_path, pathname);
541 cur_path[pathname_len - 2] = '/';
543 cur_name = cur_path + pathname_len - 1;
544 strcpy (cur_name, namep);
546 curdepth++;
547 if (!no_leaf_check)
548 /* Normal case optimization.
549 On normal Unix filesystems, a directory that has no
550 subdirectories has two links: its name, and ".". Any
551 additional links are to the ".." entries of its
552 subdirectories. Once we have processed as many
553 subdirectories as there are additional links, we know
554 that the rest of the entries are non-directories --
555 in other words, leaf files. */
556 subdirs_left -= process_path (cur_path, cur_name,
557 subdirs_left == 0, pathname);
558 else
559 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
560 mounted, which don't have Unix-like directory link counts. */
561 process_path (cur_path, cur_name, false, pathname);
562 curdepth--;
565 if (strcmp (name, "."))
567 /* We could go back and do the next command-line arg
568 instead, maybe using longjmp. */
569 char const *dir;
571 if (!dereference)
572 dir = "..";
573 else
575 chdir_back ();
576 dir = parent;
579 if (chdir (dir) != 0)
580 error (1, errno, "%s", parent);
582 /* Check that we are where we should be. */
583 if ((*xstat) (".", &stat_buf) != 0)
584 error (1, errno, "%s", pathname);
585 if (stat_buf.st_dev !=
586 (dir_curr > 0 ? dir_ids[dir_curr-1].dev : starting_stat_buf.st_dev) ||
587 stat_buf.st_ino !=
588 (dir_curr > 0 ? dir_ids[dir_curr-1].ino : starting_stat_buf.st_ino))
590 if (dereference)
591 error (1, 0, _("%s changed during execution of %s"), parent, program_name);
592 else
593 error (1, 0, _("%s/.. changed during execution of %s"), starting_dir, program_name);
597 if (cur_path)
598 free (cur_path);
599 free (name_space);
603 /* Return true if there are no side effects in any of the predicates in
604 predicate list PRED, false if there are any. */
606 static boolean
607 no_side_effects (struct predicate *pred)
609 while (pred != NULL)
611 if (pred->side_effects)
612 return (false);
613 pred = pred->pred_next;
615 return (true);
618 /* Return true if there are no predicates with no_default_print in
619 predicate list PRED, false if there are any.
620 Returns true if default print should be performed */
622 static boolean
623 default_prints (struct predicate *pred)
625 while (pred != NULL)
627 if (pred->no_default_print)
628 return (false);
629 pred = pred->pred_next;
631 return (true);