1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003 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)
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., 9 Temple Place - Suite 330, Boston, MA 02111-1307,
19 /* GNU find was written by Eric Decker <cire@cisco.com>,
20 with enhancements by David MacKenzie <djm@gnu.ai.mit.edu>,
21 Jay Plett <jay@silence.princeton.nj.us>,
22 and Tim Wood <axolotl!tim@toad.com>.
23 The idea for -print0 and xargs -0 came from
24 Dan Bernstein <brnstnd@kramden.acf.nyu.edu>. */
33 #include "../gnulib/lib/human.h"
35 #include "../gnulib/lib/savedir.h"
43 # define _(Text) gettext (Text)
46 #define textdomain(Domain)
47 #define bindtextdomain(Package, Directory)
50 # define N_(String) gettext_noop (String)
52 /* See locate.c for explanation as to why not use (String) */
53 # define N_(String) String
56 #define apply_predicate(pathname, stat_buf_ptr, node) \
57 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
59 static void process_top_path
PARAMS((char *pathname
));
60 static int process_path
PARAMS((char *pathname
, char *name
, boolean leaf
, char *parent
));
61 static void process_dir
PARAMS((char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
));
62 static boolean no_side_effects
PARAMS((struct predicate
*pred
));
63 static boolean default_prints
PARAMS((struct predicate
*pred
));
65 /* Name this program was run with. */
68 /* All predicates for each path to process. */
69 struct predicate
*predicates
;
71 /* The last predicate allocated. */
72 struct predicate
*last_pred
;
74 /* The root of the evaluation tree. */
75 static struct predicate
*eval_tree
;
77 /* If true, process directory before contents. True unless -depth given. */
80 /* If >=0, don't descend more than this many levels of subdirectories. */
83 /* If >=0, don't process files above this level. */
86 /* Current depth; 0 means current path is a command line arg. */
89 /* Output block size. */
90 int output_block_size
;
92 /* Time at start of execution. */
95 /* Seconds between 00:00 1/1/70 and either one day before now
96 (the default), or the start of today (if -daystart is given). */
99 /* If true, cur_day_start has been adjusted to the start of the day. */
102 /* If true, do not assume that files in directories with nlink == 2
103 are non-directories. */
104 boolean no_leaf_check
;
106 /* If true, don't cross filesystem boundaries. */
107 boolean stay_on_filesystem
;
109 /* If true, don't descend past current directory.
110 Can be set by -prune, -maxdepth, and -xdev/-mount. */
111 boolean stop_at_current_level
;
113 /* The full path of the initial working directory, or "." if
114 STARTING_DESC is nonnegative. */
115 char const *starting_dir
= ".";
117 /* A file descriptor open to the initial working directory.
118 Doing it this way allows us to work when the i.w.d. has
119 unreadable parents. */
122 /* The stat buffer of the initial working directory. */
123 struct stat starting_stat_buf
;
125 /* If true, we have called stat on the current path. */
128 /* The file being operated on, relative to the current directory.
129 Used for stat, readlink, remove, and opendir. */
132 /* Length of current path. */
135 /* true if following symlinks. Should be consistent with xstat. */
138 /* Pointer to the function used to stat files. */
141 /* Status value to return to system. */
144 /* If true, we ignore the problem where we find that a directory entry
145 * no longer exists by the time we get around to processing it.
147 boolean ignore_readdir_race
;
152 debug_stat (file
, bufp
)
156 fprintf (stderr
, "debug_stat (%s)\n", file
);
157 return lstat (file
, bufp
);
159 #endif /* DEBUG_STAT */
162 main (int argc
, char **argv
)
165 PFB parse_function
; /* Pointer to the function which parses. */
166 struct predicate
*cur_pred
;
167 char *predicate_name
; /* Name of predicate being parsed. */
169 program_name
= argv
[0];
171 #ifdef HAVE_SETLOCALE
172 setlocale (LC_ALL
, "");
174 bindtextdomain (PACKAGE
, LOCALEDIR
);
175 textdomain (PACKAGE
);
180 maxdepth
= mindepth
= -1;
181 start_time
= time (NULL
);
182 cur_day_start
= start_time
- DAYSECS
;
184 no_leaf_check
= false;
185 stay_on_filesystem
= false;
186 ignore_readdir_race
= false;
191 #else /* !DEBUG_STAT */
193 #endif /* !DEBUG_STAT */
196 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size
);
198 if (getenv("POSIXLY_CORRECT"))
199 output_block_size
= 512;
201 output_block_size
= 1024;
203 if (getenv("FIND_BLOCK_SIZE"))
205 error (1, errno
, _("The environment variable FIND_BLOCK_SIZE is not supported, the only thing that affects the block size is the POSIXLY_CORRECT environment variable"));
211 printf ("cur_day_start = %s", ctime (&cur_day_start
));
214 /* Find where in ARGV the predicates begin. */
215 for (i
= 1; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
218 /* Enclose the expression in `( ... )' so a default -print will
219 apply to the whole expression. */
220 parse_open (argv
, &argc
);
221 /* Build the input order list. */
224 if (strchr ("-!(),", argv
[i
][0]) == NULL
)
225 usage (_("paths must precede expression"));
226 predicate_name
= argv
[i
];
227 parse_function
= find_parser (predicate_name
);
228 if (parse_function
== NULL
)
229 /* Command line option not recognized */
230 error (1, 0, _("invalid predicate `%s'"), predicate_name
);
232 if (!(*parse_function
) (argv
, &i
))
235 /* Command line option requires an argument */
236 error (1, 0, _("missing argument to `%s'"), predicate_name
);
238 error (1, 0, _("invalid argument `%s' to `%s'"),
239 argv
[i
], predicate_name
);
242 if (predicates
->pred_next
== NULL
)
244 /* No predicates that do something other than set a global variable
245 were given; remove the unneeded initial `(' and add `-print'. */
246 cur_pred
= predicates
;
247 predicates
= last_pred
= predicates
->pred_next
;
248 free ((char *) cur_pred
);
249 parse_print (argv
, &argc
);
251 else if (!default_prints (predicates
->pred_next
))
253 /* One or more predicates that produce output were given;
254 remove the unneeded initial `('. */
255 cur_pred
= predicates
;
256 predicates
= predicates
->pred_next
;
257 free ((char *) cur_pred
);
261 /* `( user-supplied-expression ) -print'. */
262 parse_close (argv
, &argc
);
263 parse_print (argv
, &argc
);
267 printf (_("Predicate List:\n"));
268 print_list (predicates
);
271 /* Done parsing the predicates. Build the evaluation tree. */
272 cur_pred
= predicates
;
273 eval_tree
= get_expr (&cur_pred
, NO_PREC
);
275 /* Check if we have any left-over predicates (this fixes
276 * Debian bug #185202).
278 if (cur_pred
!= NULL
)
280 error (1, 0, _("unexpected extra predicate"));
284 printf (_("Eval Tree:\n"));
285 print_tree (eval_tree
, 0);
288 /* Rearrange the eval tree in optimal-predicate order. */
289 opt_expr (&eval_tree
);
291 /* Determine the point, if any, at which to stat the file. */
292 mark_stat (eval_tree
);
295 printf (_("Optimized Eval Tree:\n"));
296 print_tree (eval_tree
, 0);
299 starting_desc
= open (".", O_RDONLY
);
300 if (0 <= starting_desc
&& fchdir (starting_desc
) != 0)
302 close (starting_desc
);
305 if (starting_desc
< 0)
307 starting_dir
= xgetcwd ();
309 error (1, errno
, _("cannot get current directory"));
311 if ((*xstat
) (".", &starting_stat_buf
) != 0)
312 error (1, errno
, _("cannot get current directory"));
314 /* If no paths are given, default to ".". */
315 for (i
= 1; i
< argc
&& strchr ("-!(),", argv
[i
][0]) == NULL
; i
++)
316 process_top_path (argv
[i
]);
318 process_top_path (".");
323 /* Safely go back to the starting directory. */
327 struct stat stat_buf
;
329 if (starting_desc
< 0)
331 if (chdir (starting_dir
) != 0)
332 error (1, errno
, "%s", starting_dir
);
333 if ((*xstat
) (".", &stat_buf
) != 0)
334 error (1, errno
, "%s", starting_dir
);
335 if (stat_buf
.st_dev
!= starting_stat_buf
.st_dev
||
336 stat_buf
.st_ino
!= starting_stat_buf
.st_ino
)
337 error (1, 0, _("%s changed during execution of %s"), starting_dir
, program_name
);
341 if (fchdir (starting_desc
) != 0)
342 error (1, errno
, "%s", starting_dir
);
346 /* Descend PATHNAME, which is a command-line argument. */
349 process_top_path (char *pathname
)
351 struct stat stat_buf
, cur_stat_buf
;
354 path_length
= strlen (pathname
);
356 /* We stat each pathname given on the command-line twice --
357 once here and once in process_path. It's not too bad, though,
358 since the kernel can read the stat information out of its inode
359 cache the second time. */
360 if ((*xstat
) (pathname
, &stat_buf
) == 0 && S_ISDIR (stat_buf
.st_mode
))
362 if (chdir (pathname
) < 0)
364 if (!ignore_readdir_race
|| (errno
!= ENOENT
) )
366 error (0, errno
, "%s", pathname
);
372 /* Check that we are where we should be. */
373 if ((*xstat
) (".", &cur_stat_buf
) != 0)
374 error (1, errno
, "%s", pathname
);
375 if (cur_stat_buf
.st_dev
!= stat_buf
.st_dev
||
376 cur_stat_buf
.st_ino
!= stat_buf
.st_ino
)
377 error (1, 0, _("%s changed during execution of %s"), pathname
, program_name
);
379 process_path (pathname
, ".", false, ".");
383 process_path (pathname
, pathname
, false, ".");
386 /* Info on each directory in the current tree branch, to avoid
387 getting stuck in symbolic link loops. */
393 static struct dir_id
*dir_ids
= NULL
;
394 /* Entries allocated in `dir_ids'. */
395 static int dir_alloc
= 0;
396 /* Index in `dir_ids' of directory currently being searched.
397 This is always the last valid entry. */
398 static int dir_curr
= -1;
399 /* (Arbitrary) number of entries to grow `dir_ids' by. */
400 #define DIR_ALLOC_STEP 32
402 /* Recursively descend path PATHNAME, applying the predicates.
403 LEAF is true if PATHNAME is known to be in a directory that has no
404 more unexamined subdirectories, and therefore it is not a directory.
405 Knowing this allows us to avoid calling stat as long as possible for
408 NAME is PATHNAME relative to the current directory. We access NAME
411 PARENT is the path of the parent of NAME, relative to find's
414 Return nonzero iff PATHNAME is a directory. */
417 process_path (char *pathname
, char *name
, boolean leaf
, char *parent
)
419 struct stat stat_buf
;
420 static dev_t root_dev
; /* Device ID of current argument pathname. */
425 /* Assume it is a non-directory initially. */
426 stat_buf
.st_mode
= 0;
434 if ((*xstat
) (name
, &stat_buf
) != 0)
436 if (!ignore_readdir_race
|| (errno
!= ENOENT
) )
438 error (0, errno
, "%s", pathname
);
446 if (!S_ISDIR (stat_buf
.st_mode
))
448 if (curdepth
>= mindepth
)
449 apply_predicate (pathname
, &stat_buf
, eval_tree
);
453 /* From here on, we're working on a directory. */
455 stop_at_current_level
= maxdepth
>= 0 && curdepth
>= maxdepth
;
457 /* If we've already seen this directory on this branch,
458 don't descend it again. */
459 for (i
= 0; i
<= dir_curr
; i
++)
460 if (stat_buf
.st_ino
== dir_ids
[i
].ino
&&
461 stat_buf
.st_dev
== dir_ids
[i
].dev
)
462 stop_at_current_level
= true;
464 if (dir_alloc
<= ++dir_curr
)
466 dir_alloc
+= DIR_ALLOC_STEP
;
467 dir_ids
= (struct dir_id
*)
468 xrealloc ((char *) dir_ids
, dir_alloc
* sizeof (struct dir_id
));
470 dir_ids
[dir_curr
].ino
= stat_buf
.st_ino
;
471 dir_ids
[dir_curr
].dev
= stat_buf
.st_dev
;
473 if (stay_on_filesystem
)
476 root_dev
= stat_buf
.st_dev
;
477 else if (stat_buf
.st_dev
!= root_dev
)
478 stop_at_current_level
= true;
481 if (do_dir_first
&& curdepth
>= mindepth
)
482 apply_predicate (pathname
, &stat_buf
, eval_tree
);
485 fprintf(stderr
, "pathname = %s, stop_at_current_level = %d\n",
486 pathname
, stop_at_current_level
);
489 if (stop_at_current_level
== false)
490 /* Scan directory on disk. */
491 process_dir (pathname
, name
, strlen (pathname
), &stat_buf
, parent
);
493 if (do_dir_first
== false && curdepth
>= mindepth
)
496 apply_predicate (pathname
, &stat_buf
, eval_tree
);
504 /* Scan directory PATHNAME and recurse through process_path for each entry.
506 PATHLEN is the length of PATHNAME.
508 NAME is PATHNAME relative to the current directory.
510 STATP is the results of *xstat on it.
512 PARENT is the path of the parent of NAME, relative to find's
513 starting directory. */
516 process_dir (char *pathname
, char *name
, int pathlen
, struct stat
*statp
, char *parent
)
518 char *name_space
; /* Names of files in PATHNAME. */
519 int subdirs_left
; /* Number of unexamined subdirs in PATHNAME. */
520 struct stat stat_buf
;
522 subdirs_left
= statp
->st_nlink
- 2; /* Account for name and ".". */
525 name_space
= savedir (name
);
526 if (name_space
== NULL
)
530 error (0, errno
, "%s", pathname
);
534 error (1, 0, _("virtual memory exhausted"));
538 register char *namep
; /* Current point in `name_space'. */
539 char *cur_path
; /* Full path of each file to process. */
540 char *cur_name
; /* Base name of each file to process. */
541 unsigned cur_path_size
; /* Bytes allocated for `cur_path'. */
542 register unsigned file_len
; /* Length of each path to process. */
543 register unsigned pathname_len
; /* PATHLEN plus trailing '/'. */
545 if (pathname
[pathlen
- 1] == '/')
546 pathname_len
= pathlen
+ 1; /* For '\0'; already have '/'. */
548 pathname_len
= pathlen
+ 2; /* For '/' and '\0'. */
552 if (strcmp (name
, ".") && chdir (name
) < 0)
554 error (0, errno
, "%s", pathname
);
559 /* Check that we are where we should be. */
560 if ((*xstat
) (".", &stat_buf
) != 0)
561 error (1, errno
, "%s", pathname
);
562 if (stat_buf
.st_dev
!= dir_ids
[dir_curr
].dev
||
563 stat_buf
.st_ino
!= dir_ids
[dir_curr
].ino
)
564 error (1, 0, _("%s changed during execution of %s"), starting_dir
, program_name
);
566 for (namep
= name_space
; *namep
; namep
+= file_len
- pathname_len
+ 1)
568 /* Append this directory entry's name to the path being searched. */
569 file_len
= pathname_len
+ strlen (namep
);
570 if (file_len
> cur_path_size
)
572 while (file_len
> cur_path_size
)
573 cur_path_size
+= 1024;
576 cur_path
= xmalloc (cur_path_size
);
577 strcpy (cur_path
, pathname
);
578 cur_path
[pathname_len
- 2] = '/';
580 cur_name
= cur_path
+ pathname_len
- 1;
581 strcpy (cur_name
, namep
);
585 /* Normal case optimization.
586 On normal Unix filesystems, a directory that has no
587 subdirectories has two links: its name, and ".". Any
588 additional links are to the ".." entries of its
589 subdirectories. Once we have processed as many
590 subdirectories as there are additional links, we know
591 that the rest of the entries are non-directories --
592 in other words, leaf files. */
593 subdirs_left
-= process_path (cur_path
, cur_name
,
594 subdirs_left
== 0, pathname
);
596 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
597 mounted, which don't have Unix-like directory link counts. */
598 process_path (cur_path
, cur_name
, false, pathname
);
602 if (strcmp (name
, "."))
604 /* We could go back and do the next command-line arg
605 instead, maybe using longjmp. */
616 if (chdir (dir
) != 0)
617 error (1, errno
, "%s", parent
);
619 /* Check that we are where we should be. */
620 if ((*xstat
) (".", &stat_buf
) != 0)
621 error (1, errno
, "%s", pathname
);
622 if (stat_buf
.st_dev
!=
623 (dir_curr
> 0 ? dir_ids
[dir_curr
-1].dev
: starting_stat_buf
.st_dev
) ||
625 (dir_curr
> 0 ? dir_ids
[dir_curr
-1].ino
: starting_stat_buf
.st_ino
))
628 error (1, 0, _("%s changed during execution of %s"), parent
, program_name
);
630 error (1, 0, _("%s/.. changed during execution of %s"), starting_dir
, program_name
);
640 /* Return true if there are no side effects in any of the predicates in
641 predicate list PRED, false if there are any. */
644 no_side_effects (struct predicate
*pred
)
648 if (pred
->side_effects
)
650 pred
= pred
->pred_next
;
655 /* Return true if there are no predicates with no_default_print in
656 predicate list PRED, false if there are any.
657 Returns true if default print should be performed */
660 default_prints (struct predicate
*pred
)
664 if (pred
->no_default_print
)
666 pred
= pred
->pred_next
;