Invoke gl_INCLUDED_REGEX directly to ensure successful compilation on
[findutils.git] / find / pred.c
blob5079251c95fe0a8afce6bce00b7c5876f6376fdd
1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA.
20 #include "defs.h"
22 #include <fnmatch.h>
23 #include <signal.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <assert.h>
29 #include <fcntl.h>
30 #include "../gnulib/lib/xalloc.h"
31 #include "../gnulib/lib/dirname.h"
32 #include "../gnulib/lib/human.h"
33 #include "modetype.h"
34 #include "filemode.h"
35 #include "wait.h"
36 #include "buildcmd.h"
38 #if ENABLE_NLS
39 # include <libintl.h>
40 # define _(Text) gettext (Text)
41 #else
42 # define _(Text) Text
43 #endif
44 #ifdef gettext_noop
45 # define N_(String) gettext_noop (String)
46 #else
47 /* See locate.c for explanation as to why not use (String) */
48 # define N_(String) String
49 #endif
51 #if !defined(SIGCHLD) && defined(SIGCLD)
52 #define SIGCHLD SIGCLD
53 #endif
55 #if HAVE_DIRENT_H
56 # include <dirent.h>
57 # define NAMLEN(dirent) strlen((dirent)->d_name)
58 #else
59 # define dirent direct
60 # define NAMLEN(dirent) (dirent)->d_namlen
61 # if HAVE_SYS_NDIR_H
62 # include <sys/ndir.h>
63 # endif
64 # if HAVE_SYS_DIR_H
65 # include <sys/dir.h>
66 # endif
67 # if HAVE_NDIR_H
68 # include <ndir.h>
69 # endif
70 #endif
72 #ifdef CLOSEDIR_VOID
73 /* Fake a return value. */
74 #define CLOSEDIR(d) (closedir (d), 0)
75 #else
76 #define CLOSEDIR(d) closedir (d)
77 #endif
79 extern int yesno ();
82 /* Get or fake the disk device blocksize.
83 Usually defined by sys/param.h (if at all). */
84 #ifndef DEV_BSIZE
85 # ifdef BSIZE
86 # define DEV_BSIZE BSIZE
87 # else /* !BSIZE */
88 # define DEV_BSIZE 4096
89 # endif /* !BSIZE */
90 #endif /* !DEV_BSIZE */
92 /* Extract or fake data from a `struct stat'.
93 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
94 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
95 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
96 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
97 # define ST_BLKSIZE(statbuf) DEV_BSIZE
98 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
99 # define ST_NBLOCKS(statbuf) \
100 (S_ISREG ((statbuf).st_mode) \
101 || S_ISDIR ((statbuf).st_mode) \
102 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
103 # else /* !_POSIX_SOURCE && BSIZE */
104 # define ST_NBLOCKS(statbuf) \
105 (S_ISREG ((statbuf).st_mode) \
106 || S_ISDIR ((statbuf).st_mode) \
107 ? st_blocks ((statbuf).st_size) : 0)
108 # endif /* !_POSIX_SOURCE && BSIZE */
109 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
110 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
111 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
112 ? (statbuf).st_blksize : DEV_BSIZE)
113 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
114 /* HP-UX counts st_blocks in 1024-byte units.
115 This loses when mixing HP-UX and BSD filesystems with NFS. */
116 # define ST_NBLOCKSIZE 1024
117 # else /* !hpux */
118 # if defined(_AIX) && defined(_I386)
119 /* AIX PS/2 counts st_blocks in 4K units. */
120 # define ST_NBLOCKSIZE (4 * 1024)
121 # else /* not AIX PS/2 */
122 # if defined(_CRAY)
123 # define ST_NBLOCKS(statbuf) \
124 (S_ISREG ((statbuf).st_mode) \
125 || S_ISDIR ((statbuf).st_mode) \
126 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
127 # endif /* _CRAY */
128 # endif /* not AIX PS/2 */
129 # endif /* !hpux */
130 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
132 #ifndef ST_NBLOCKS
133 # define ST_NBLOCKS(statbuf) \
134 (S_ISREG ((statbuf).st_mode) \
135 || S_ISDIR ((statbuf).st_mode) \
136 ? (statbuf).st_blocks : 0)
137 #endif
139 #ifndef ST_NBLOCKSIZE
140 # define ST_NBLOCKSIZE 512
141 #endif
143 #undef MAX
144 #define MAX(a, b) ((a) > (b) ? (a) : (b))
146 static boolean insert_lname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case));
148 static char *format_date PARAMS((time_t when, int kind));
149 static char *ctime_format PARAMS((time_t when));
151 #ifdef DEBUG
152 struct pred_assoc
154 PFB pred_func;
155 char *pred_name;
158 struct pred_assoc pred_table[] =
160 {pred_amin, "amin "},
161 {pred_and, "and "},
162 {pred_anewer, "anewer "},
163 {pred_atime, "atime "},
164 {pred_close, ") "},
165 {pred_amin, "cmin "},
166 {pred_cnewer, "cnewer "},
167 {pred_comma, ", "},
168 {pred_ctime, "ctime "},
169 {pred_delete, "delete "},
170 {pred_empty, "empty "},
171 {pred_exec, "exec "},
172 {pred_execdir, "execdir "},
173 {pred_false, "false "},
174 {pred_fprint, "fprint "},
175 {pred_fprint0, "fprint0 "},
176 {pred_fprintf, "fprintf "},
177 {pred_fstype, "fstype "},
178 {pred_gid, "gid "},
179 {pred_group, "group "},
180 {pred_ilname, "ilname "},
181 {pred_iname, "iname "},
182 {pred_inum, "inum "},
183 {pred_ipath, "ipath "},
184 {pred_links, "links "},
185 {pred_lname, "lname "},
186 {pred_ls, "ls "},
187 {pred_amin, "mmin "},
188 {pred_mtime, "mtime "},
189 {pred_name, "name "},
190 {pred_negate, "not "},
191 {pred_newer, "newer "},
192 {pred_nogroup, "nogroup "},
193 {pred_nouser, "nouser "},
194 {pred_ok, "ok "},
195 {pred_okdir, "okdir "},
196 {pred_open, "( "},
197 {pred_or, "or "},
198 {pred_path, "path "},
199 {pred_perm, "perm "},
200 {pred_print, "print "},
201 {pred_print0, "print0 "},
202 {pred_prune, "prune "},
203 {pred_regex, "regex "},
204 {pred_samefile,"samefile "},
205 {pred_size, "size "},
206 {pred_true, "true "},
207 {pred_type, "type "},
208 {pred_uid, "uid "},
209 {pred_used, "used "},
210 {pred_user, "user "},
211 {pred_xtype, "xtype "},
212 {0, "none "}
215 struct op_assoc
217 short type;
218 char *type_name;
221 struct op_assoc type_table[] =
223 {NO_TYPE, "no "},
224 {PRIMARY_TYPE, "primary "},
225 {UNI_OP, "uni_op "},
226 {BI_OP, "bi_op "},
227 {OPEN_PAREN, "open_paren "},
228 {CLOSE_PAREN, "close_paren "},
229 {-1, "unknown "}
232 struct prec_assoc
234 short prec;
235 char *prec_name;
238 struct prec_assoc prec_table[] =
240 {NO_PREC, "no "},
241 {COMMA_PREC, "comma "},
242 {OR_PREC, "or "},
243 {AND_PREC, "and "},
244 {NEGATE_PREC, "negate "},
245 {MAX_PREC, "max "},
246 {-1, "unknown "}
248 #endif /* DEBUG */
250 /* Predicate processing routines.
252 PATHNAME is the full pathname of the file being checked.
253 *STAT_BUF contains information about PATHNAME.
254 *PRED_PTR contains information for applying the predicate.
256 Return true if the file passes this predicate, false if not. */
259 /* pred_timewindow
261 * Returns true if THE_TIME is
262 * COMP_GT: after the specified time
263 * COMP_LT: before the specified time
264 * COMP_EQ: less than WINDOW seconds after the specified time.
266 static boolean
267 pred_timewindow(time_t the_time, struct predicate const *pred_ptr, int window)
269 switch (pred_ptr->args.info.kind)
271 case COMP_GT:
272 if (the_time > (time_t) pred_ptr->args.info.l_val)
273 return true;
274 break;
275 case COMP_LT:
276 if (the_time < (time_t) pred_ptr->args.info.l_val)
277 return true;
278 break;
279 case COMP_EQ:
280 if ((the_time >= (time_t) pred_ptr->args.info.l_val)
281 && (the_time < (time_t) pred_ptr->args.info.l_val + window))
282 return true;
283 break;
285 return false;
289 boolean
290 pred_amin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
292 (void) &pathname;
293 return pred_timewindow(stat_buf->st_atime, pred_ptr, 60);
296 boolean
297 pred_and (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
299 int match = 0;
301 if (pred_ptr->pred_left == NULL
302 || (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
303 pred_ptr->pred_left))
305 /* Check whether we need a stat here. */
306 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
307 return false;
308 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
309 pred_ptr->pred_right));
311 else
312 return (false);
315 boolean
316 pred_anewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
318 (void) &pathname;
320 if (stat_buf->st_atime > pred_ptr->args.time)
321 return (true);
322 return (false);
325 boolean
326 pred_atime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
328 (void) &pathname;
329 return pred_timewindow(stat_buf->st_atime, pred_ptr, DAYSECS);
332 boolean
333 pred_close (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
335 (void) &pathname;
336 (void) &stat_buf;
337 (void) &pred_ptr;
339 return true;
342 boolean
343 pred_cmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
345 (void) pathname;
346 return pred_timewindow(stat_buf->st_ctime, pred_ptr, 60);
349 boolean
350 pred_cnewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
352 (void) pathname;
354 if (stat_buf->st_ctime > pred_ptr->args.time)
355 return true;
356 else
357 return false;
360 boolean
361 pred_comma (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
363 if (pred_ptr->pred_left != NULL)
364 (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
365 pred_ptr->pred_left);
366 /* Check whether we need a stat here. */
367 /* TODO: what about need_type? */
368 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
369 return false;
370 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
371 pred_ptr->pred_right));
374 boolean
375 pred_ctime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
377 (void) &pathname;
378 return pred_timewindow(stat_buf->st_ctime, pred_ptr, DAYSECS);
381 boolean
382 pred_delete (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
384 (void) pred_ptr;
385 (void) stat_buf;
386 if (strcmp (state.rel_pathname, "."))
388 if (0 != remove (state.rel_pathname))
390 error (0, errno, "cannot delete %s", pathname);
391 return false;
393 else
395 return true;
399 /* nothing to do. */
400 return true;
403 boolean
404 pred_empty (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
406 (void) pathname;
407 (void) pred_ptr;
409 if (S_ISDIR (stat_buf->st_mode))
411 DIR *d;
412 struct dirent *dp;
413 boolean empty = true;
415 errno = 0;
416 d = opendir (state.rel_pathname);
417 if (d == NULL)
419 error (0, errno, "%s", pathname);
420 state.exit_status = 1;
421 return false;
423 for (dp = readdir (d); dp; dp = readdir (d))
425 if (dp->d_name[0] != '.'
426 || (dp->d_name[1] != '\0'
427 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
429 empty = false;
430 break;
433 if (CLOSEDIR (d))
435 error (0, errno, "%s", pathname);
436 state.exit_status = 1;
437 return false;
439 return (empty);
441 else if (S_ISREG (stat_buf->st_mode))
442 return (stat_buf->st_size == 0);
443 else
444 return (false);
447 #if defined(NEW_EXEC)
448 static boolean
449 new_impl_pred_exec (const char *pathname, struct stat *stat_buf,
450 struct predicate *pred_ptr,
451 const char *prefix, size_t pfxlen)
453 struct exec_val *execp = &pred_ptr->args.exec_vec;
454 size_t len = strlen(pathname);
456 if (execp->multiple)
458 /* Push the argument onto the current list.
459 * The command may or may not be run at this point,
460 * depending on the command line length limits.
462 bc_push_arg(&execp->ctl,
463 &execp->state,
464 pathname, len+1,
465 prefix, pfxlen,
468 /* POSIX: If the primary expression is punctuated by a plus
469 * sign, the primary shall always evaluate as true
471 return true;
473 else
475 int i;
477 for (i=0; i<execp->num_args; ++i)
479 bc_do_insert(&execp->ctl,
480 &execp->state,
481 execp->replace_vec[i],
482 strlen(execp->replace_vec[i]),
483 prefix, pfxlen,
484 pathname, len,
488 /* Actually invoke the command. */
489 return execp->ctl.exec_callback(&execp->ctl,
490 &execp->state);
493 #else
494 static boolean
495 old_impl_pred_exec (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
497 int i;
498 int path_pos;
499 struct exec_val *execp; /* Pointer for efficiency. */
501 (void) pathname;
502 (void) stat_buf;
504 execp = &pred_ptr->args.exec_vec;
506 /* Replace "{}" with the real path in each affected arg. */
507 for (path_pos = 0; execp->paths[path_pos].offset >= 0; path_pos++)
509 register char *from, *to;
511 i = execp->paths[path_pos].offset;
512 execp->vec[i] =
513 xmalloc (strlen (execp->paths[path_pos].origarg) + 1
514 + (strlen (pathname) - 2) * execp->paths[path_pos].count);
515 for (from = execp->paths[path_pos].origarg, to = execp->vec[i]; *from; )
516 if (from[0] == '{' && from[1] == '}')
518 to = stpcpy (to, pathname);
519 from += 2;
521 else
522 *to++ = *from++;
523 *to = *from; /* Copy null. */
526 i = launch (pred_ptr);
528 /* Free the temporary args. */
529 for (path_pos = 0; execp->paths[path_pos].offset >= 0; path_pos++)
530 free (execp->vec[execp->paths[path_pos].offset]);
532 return (i);
534 #endif
536 boolean
537 pred_exec (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
539 #if defined(NEW_EXEC)
540 return new_impl_pred_exec(pathname, stat_buf, pred_ptr, NULL, 0);
541 #else
542 return old_impl_pred_exec(pathname, stat_buf, pred_ptr);
543 #endif
546 boolean
547 pred_execdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
549 const char *s = basename(pathname);
550 return new_impl_pred_exec(s, stat_buf, pred_ptr, "./", 2);
553 boolean
554 pred_false (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
556 (void) &pathname;
557 (void) &stat_buf;
558 (void) &pred_ptr;
561 return (false);
564 boolean
565 pred_fls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
567 list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
568 options.output_block_size, pred_ptr->args.stream);
569 return (true);
572 boolean
573 pred_fprint (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
575 (void) &pathname;
576 (void) &stat_buf;
578 fputs (pathname, pred_ptr->args.stream);
579 putc ('\n', pred_ptr->args.stream);
580 return (true);
583 boolean
584 pred_fprint0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
586 (void) &pathname;
587 (void) &stat_buf;
589 fputs (pathname, pred_ptr->args.stream);
590 putc (0, pred_ptr->args.stream);
591 return (true);
594 boolean
595 pred_fprintf (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
597 FILE *fp = pred_ptr->args.printf_vec.stream;
598 struct segment *segment;
599 char *cp;
600 char hbuf[LONGEST_HUMAN_READABLE + 1];
602 for (segment = pred_ptr->args.printf_vec.segment; segment;
603 segment = segment->next)
605 if (segment->kind & 0xff00) /* Component of date. */
607 time_t t;
609 switch (segment->kind & 0xff)
611 case 'A':
612 t = stat_buf->st_atime;
613 break;
614 case 'C':
615 t = stat_buf->st_ctime;
616 break;
617 case 'T':
618 t = stat_buf->st_mtime;
619 break;
620 default:
621 abort ();
623 fprintf (fp, segment->text,
624 format_date (t, (segment->kind >> 8) & 0xff));
625 continue;
628 switch (segment->kind)
630 case KIND_PLAIN: /* Plain text string (no % conversion). */
631 fwrite (segment->text, 1, segment->text_len, fp);
632 break;
633 case KIND_STOP: /* Terminate argument and flush output. */
634 fwrite (segment->text, 1, segment->text_len, fp);
635 fflush (fp);
636 return (true);
637 case 'a': /* atime in `ctime' format. */
638 fprintf (fp, segment->text, ctime_format (stat_buf->st_atime));
639 break;
640 case 'b': /* size in 512-byte blocks */
641 fprintf (fp, segment->text,
642 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
643 hbuf, human_ceiling,
644 ST_NBLOCKSIZE, 512));
645 break;
646 case 'c': /* ctime in `ctime' format */
647 fprintf (fp, segment->text, ctime_format (stat_buf->st_ctime));
648 break;
649 case 'd': /* depth in search tree */
650 fprintf (fp, segment->text, state.curdepth);
651 break;
652 case 'D': /* Device on which file exists (stat.st_dev) */
653 fprintf (fp, segment->text,
654 human_readable ((uintmax_t) stat_buf->st_dev, hbuf,
655 human_ceiling, 1, 1));
656 break;
657 case 'f': /* basename of path */
658 fprintf (fp, segment->text, base_name (pathname));
659 break;
660 case 'F': /* filesystem type */
661 fprintf (fp, segment->text, filesystem_type (stat_buf));
662 break;
663 case 'g': /* group name */
665 struct group *g;
667 g = getgrgid (stat_buf->st_gid);
668 if (g)
670 segment->text[segment->text_len] = 's';
671 fprintf (fp, segment->text, g->gr_name);
672 break;
674 /* else fallthru */
676 case 'G': /* GID number */
677 fprintf (fp, segment->text,
678 human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
679 human_ceiling, 1, 1));
680 break;
681 case 'h': /* leading directories part of path */
683 char cc;
685 cp = strrchr (pathname, '/');
686 if (cp == NULL) /* No leading directories. */
687 break;
688 cc = *cp;
689 *cp = '\0';
690 fprintf (fp, segment->text, pathname);
691 *cp = cc;
692 break;
694 case 'H': /* ARGV element file was found under */
696 char cc = pathname[state.path_length];
698 pathname[state.path_length] = '\0';
699 fprintf (fp, segment->text, pathname);
700 pathname[state.path_length] = cc;
701 break;
703 case 'i': /* inode number */
704 fprintf (fp, segment->text,
705 human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
706 human_ceiling,
707 1, 1));
708 break;
709 case 'k': /* size in 1K blocks */
710 fprintf (fp, segment->text,
711 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
712 hbuf, human_ceiling,
713 ST_NBLOCKSIZE, 1024));
714 break;
715 case 'l': /* object of symlink */
716 #ifdef S_ISLNK
718 char *linkname = 0;
720 if (S_ISLNK (stat_buf->st_mode))
722 linkname = get_link_name (pathname, state.rel_pathname);
723 if (linkname == 0)
724 state.exit_status = 1;
726 if (linkname)
728 fprintf (fp, segment->text, linkname);
729 free (linkname);
731 else
732 fprintf (fp, segment->text, "");
734 #endif /* S_ISLNK */
735 break;
737 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
739 char modestring[16] ;
740 mode_string (stat_buf->st_mode, modestring);
741 modestring[10] = '\0';
742 fprintf (fp, segment->text, modestring);
744 break;
746 case 'm': /* mode as octal number (perms only) */
748 /* Output the mode portably using the traditional numbers,
749 even if the host unwisely uses some other numbering
750 scheme. But help the compiler in the common case where
751 the host uses the traditional numbering scheme. */
752 mode_t m = stat_buf->st_mode;
753 boolean traditional_numbering_scheme =
754 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
755 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
756 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
757 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
758 fprintf (fp, segment->text,
759 (traditional_numbering_scheme
760 ? m & MODE_ALL
761 : ((m & S_ISUID ? 04000 : 0)
762 | (m & S_ISGID ? 02000 : 0)
763 | (m & S_ISVTX ? 01000 : 0)
764 | (m & S_IRUSR ? 00400 : 0)
765 | (m & S_IWUSR ? 00200 : 0)
766 | (m & S_IXUSR ? 00100 : 0)
767 | (m & S_IRGRP ? 00040 : 0)
768 | (m & S_IWGRP ? 00020 : 0)
769 | (m & S_IXGRP ? 00010 : 0)
770 | (m & S_IROTH ? 00004 : 0)
771 | (m & S_IWOTH ? 00002 : 0)
772 | (m & S_IXOTH ? 00001 : 0))));
774 break;
776 case 'n': /* number of links */
777 fprintf (fp, segment->text,
778 human_readable ((uintmax_t) stat_buf->st_nlink,
779 hbuf,
780 human_ceiling,
781 1, 1));
782 break;
783 case 'p': /* pathname */
784 fprintf (fp, segment->text, pathname);
785 break;
786 case 'P': /* pathname with ARGV element stripped */
787 if (state.curdepth > 0)
789 cp = pathname + state.path_length;
790 if (*cp == '/')
791 /* Move past the slash between the ARGV element
792 and the rest of the pathname. But if the ARGV element
793 ends in a slash, we didn't add another, so we've
794 already skipped past it. */
795 cp++;
797 else
798 cp = "";
799 fprintf (fp, segment->text, cp);
800 break;
801 case 's': /* size in bytes */
802 fprintf (fp, segment->text,
803 human_readable ((uintmax_t) stat_buf->st_size,
804 hbuf, human_ceiling, 1, 1));
805 break;
806 case 't': /* mtime in `ctime' format */
807 fprintf (fp, segment->text, ctime_format (stat_buf->st_mtime));
808 break;
809 case 'u': /* user name */
811 struct passwd *p;
813 p = getpwuid (stat_buf->st_uid);
814 if (p)
816 segment->text[segment->text_len] = 's';
817 fprintf (fp, segment->text, p->pw_name);
818 break;
820 /* else fallthru */
823 case 'U': /* UID number */
824 fprintf (fp, segment->text,
825 human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
826 human_ceiling, 1, 1));
827 break;
829 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
830 case 'Y': /* in case of symlink */
832 #ifdef S_ISLNK
833 if (S_ISLNK (stat_buf->st_mode))
835 struct stat sbuf;
836 int (*ystat) ();
837 ystat = options.xstat == lstat ? stat : lstat;
838 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
840 if ( errno == ENOENT ) {
841 fprintf (fp, segment->text, "N");
842 break;
844 if ( errno == ELOOP ) {
845 fprintf (fp, segment->text, "L");
846 break;
848 error (0, errno, "%s", pathname);
849 /* exit_status = 1;
850 return (false); */
852 stat_buf->st_mode = sbuf.st_mode;
854 #endif /* S_ISLNK */
856 /* FALLTHROUGH */
857 case 'y':
859 mode_t m = stat_buf->st_mode & S_IFMT;
861 fprintf (fp, segment->text,
862 ( m == S_IFSOCK ? "s" :
863 m == S_IFLNK ? "l" :
864 m == S_IFREG ? "f" :
865 m == S_IFBLK ? "b" :
866 m == S_IFDIR ? "d" :
867 m == S_IFCHR ? "c" :
868 #ifdef S_IFDOOR
869 m == S_IFDOOR ? "D" :
870 #endif
871 m == S_IFIFO ? "p" : "U" ) );
874 break;
877 return (true);
880 boolean
881 pred_fstype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
883 (void) pathname;
885 if (strcmp (filesystem_type (stat_buf), pred_ptr->args.str) == 0)
886 return true;
887 else
888 return false;
891 boolean
892 pred_gid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
894 (void) pathname;
896 switch (pred_ptr->args.info.kind)
898 case COMP_GT:
899 if (stat_buf->st_gid > pred_ptr->args.info.l_val)
900 return (true);
901 break;
902 case COMP_LT:
903 if (stat_buf->st_gid < pred_ptr->args.info.l_val)
904 return (true);
905 break;
906 case COMP_EQ:
907 if (stat_buf->st_gid == pred_ptr->args.info.l_val)
908 return (true);
909 break;
911 return (false);
914 boolean
915 pred_group (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
917 (void) pathname;
919 if (pred_ptr->args.gid == stat_buf->st_gid)
920 return (true);
921 else
922 return (false);
925 boolean
926 pred_ilname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
928 return insert_lname (pathname, stat_buf, pred_ptr, true);
931 boolean
932 pred_iname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
934 const char *base;
936 (void) stat_buf;
938 /* FNM_PERIOD is not used here because POSIX requires that it not be.
939 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
941 base = base_name (pathname);
942 if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0)
943 return (true);
944 return (false);
947 boolean
948 pred_inum (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
950 (void) pathname;
952 switch (pred_ptr->args.info.kind)
954 case COMP_GT:
955 if (stat_buf->st_ino > pred_ptr->args.info.l_val)
956 return (true);
957 break;
958 case COMP_LT:
959 if (stat_buf->st_ino < pred_ptr->args.info.l_val)
960 return (true);
961 break;
962 case COMP_EQ:
963 if (stat_buf->st_ino == pred_ptr->args.info.l_val)
964 return (true);
965 break;
967 return (false);
970 boolean
971 pred_ipath (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
973 (void) stat_buf;
975 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
976 return (true);
977 return (false);
980 boolean
981 pred_links (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
983 (void) pathname;
985 switch (pred_ptr->args.info.kind)
987 case COMP_GT:
988 if (stat_buf->st_nlink > pred_ptr->args.info.l_val)
989 return (true);
990 break;
991 case COMP_LT:
992 if (stat_buf->st_nlink < pred_ptr->args.info.l_val)
993 return (true);
994 break;
995 case COMP_EQ:
996 if (stat_buf->st_nlink == pred_ptr->args.info.l_val)
997 return (true);
998 break;
1000 return (false);
1003 boolean
1004 pred_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1006 return insert_lname (pathname, stat_buf, pred_ptr, false);
1009 static boolean
1010 insert_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)
1012 boolean ret = false;
1013 #ifdef S_ISLNK
1014 if (S_ISLNK (stat_buf->st_mode))
1016 char *linkname = get_link_name (pathname, state.rel_pathname);
1017 if (linkname)
1019 if (fnmatch (pred_ptr->args.str, linkname,
1020 ignore_case ? FNM_CASEFOLD : 0) == 0)
1021 ret = true;
1022 free (linkname);
1025 #endif /* S_ISLNK */
1026 return (ret);
1029 boolean
1030 pred_ls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1032 (void) pred_ptr;
1034 list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
1035 options.output_block_size, stdout);
1036 return (true);
1039 boolean
1040 pred_mmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1042 (void) &pathname;
1043 return pred_timewindow(stat_buf->st_mtime, pred_ptr, 60);
1046 boolean
1047 pred_mtime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1049 (void) pathname;
1050 return pred_timewindow(stat_buf->st_mtime, pred_ptr, DAYSECS);
1053 boolean
1054 pred_name (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1056 const char *base;
1058 (void) stat_buf;
1059 base = base_name (pathname);
1061 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1062 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1064 if (fnmatch (pred_ptr->args.str, base, 0) == 0)
1065 return (true);
1066 return (false);
1069 boolean
1070 pred_negate (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1072 /* Check whether we need a stat here. */
1073 /* TODO: what about need_type? */
1074 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1075 return false;
1076 return (!(*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1077 pred_ptr->pred_right));
1080 boolean
1081 pred_newer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1083 (void) pathname;
1085 if (stat_buf->st_mtime > pred_ptr->args.time)
1086 return (true);
1087 return (false);
1090 boolean
1091 pred_nogroup (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1093 (void) pathname;
1094 (void) pred_ptr;
1096 #ifdef CACHE_IDS
1097 extern char *gid_unused;
1099 return gid_unused[(unsigned) stat_buf->st_gid];
1100 #else
1101 return getgrgid (stat_buf->st_gid) == NULL;
1102 #endif
1105 boolean
1106 pred_nouser (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1108 #ifdef CACHE_IDS
1109 extern char *uid_unused;
1110 #endif
1112 (void) pathname;
1113 (void) pred_ptr;
1115 #ifdef CACHE_IDS
1116 return uid_unused[(unsigned) stat_buf->st_uid];
1117 #else
1118 return getpwuid (stat_buf->st_uid) == NULL;
1119 #endif
1122 #if defined(NEW_EXEC)
1124 static boolean
1125 is_ok(const char *program, const char *arg)
1127 fflush (stdout);
1128 /* The draft open standard requires that, in the POSIX locale,
1129 the last non-blank character of this prompt be '?'.
1130 The exact format is not specified.
1131 This standard does not have requirements for locales other than POSIX
1133 fprintf (stderr, _("< %s ... %s > ? "), program, arg);
1134 fflush (stderr);
1135 return yesno();
1138 boolean
1139 pred_ok (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1141 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1142 return new_impl_pred_exec (pathname, stat_buf, pred_ptr, NULL, 0);
1143 else
1144 return false;
1147 boolean
1148 pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1150 const char *s = basename(pathname);
1152 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1153 return new_impl_pred_exec (s, stat_buf, pred_ptr, "./", 2);
1154 else
1155 return false;
1160 #else
1161 boolean
1162 pred_ok (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1164 fflush (stdout);
1165 /* The draft open standard requires that, in the POSIX locale,
1166 the last non-blank character of this prompt be '?'.
1167 The exact format is not specified.
1168 This standard does not have requirements for locales other than POSIX
1170 fprintf (stderr, _("< %s ... %s > ? "),
1171 pred_ptr->args.exec_vec.vec[0], pathname);
1172 fflush (stderr);
1173 if (yesno ())
1174 return pred_exec (pathname, stat_buf, pred_ptr);
1175 else
1176 return (false);
1179 boolean
1180 pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1182 error(1, 0, "-okdir is not yet implemented.");
1183 return false;
1187 #endif
1190 boolean
1191 pred_open (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1193 (void) pathname;
1194 (void) stat_buf;
1195 (void) pred_ptr;
1196 return true;
1199 boolean
1200 pred_or (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1202 if (pred_ptr->pred_left == NULL
1203 || !(*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
1204 pred_ptr->pred_left))
1206 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1207 return false;
1208 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1209 pred_ptr->pred_right));
1211 else
1212 return true;
1215 boolean
1216 pred_path (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1218 (void) stat_buf;
1219 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
1220 return (true);
1221 return (false);
1224 boolean
1225 pred_perm (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1227 (void) pathname;
1228 switch (pred_ptr->args.perm.kind)
1230 case PERM_AT_LEAST:
1231 return (stat_buf->st_mode & pred_ptr->args.perm.val) == pred_ptr->args.perm.val;
1232 break;
1234 case PERM_ANY:
1235 return (stat_buf->st_mode & pred_ptr->args.perm.val) != 0;
1236 break;
1238 case PERM_EXACT:
1239 return (stat_buf->st_mode & MODE_ALL) == pred_ptr->args.perm.val;
1240 break;
1242 default:
1243 abort ();
1244 break;
1248 boolean
1249 pred_print (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1251 (void) stat_buf;
1252 (void) pred_ptr;
1253 puts (pathname);
1254 return true;
1257 boolean
1258 pred_print0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1260 (void) stat_buf;
1261 (void) pred_ptr;
1262 fputs (pathname, stdout);
1263 putc (0, stdout);
1264 return (true);
1267 boolean
1268 pred_prune (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1270 (void) pathname;
1271 (void) stat_buf;
1272 (void) pred_ptr;
1273 state.stop_at_current_level = true;
1274 return (options.do_dir_first); /* This is what SunOS find seems to do. */
1277 boolean
1278 pred_quit (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1280 (void) pathname;
1281 (void) stat_buf;
1282 (void) pred_ptr;
1284 /* Run any cleanups. This includes executing any command lines
1285 * we have partly built but not executed.
1287 cleanup();
1289 /* Since -exec and friends don't leave child processes running in the
1290 * background, there is no need to wait for them here.
1292 exit(state.exit_status); /* 0 for success, etc. */
1295 boolean
1296 pred_regex (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1298 int len = strlen (pathname);
1299 (void) stat_buf;
1300 if (re_match (pred_ptr->args.regex, pathname, len, 0,
1301 (struct re_registers *) NULL) == len)
1302 return (true);
1303 return (false);
1306 boolean
1307 pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1309 uintmax_t f_val;
1311 (void) pathname;
1312 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
1313 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
1314 switch (pred_ptr->args.size.kind)
1316 case COMP_GT:
1317 if (f_val > pred_ptr->args.size.size)
1318 return (true);
1319 break;
1320 case COMP_LT:
1321 if (f_val < pred_ptr->args.size.size)
1322 return (true);
1323 break;
1324 case COMP_EQ:
1325 if (f_val == pred_ptr->args.size.size)
1326 return (true);
1327 break;
1329 return (false);
1332 boolean
1333 pred_samefile (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1335 /* Potential optimisation: because of the loop protection, we
1336 * always know the device of the current directory, hence the
1337 * device number of the current filesystem. If -L is not in
1338 * effect, and the device number of the file we're looking for
1339 * is not the same as the device number of the current directory,
1340 * this predicate cannot return true. Hence there would be no
1341 * need to stat the file.
1343 return stat_buf->st_ino == pred_ptr->args.fileid.ino
1344 && stat_buf->st_dev == pred_ptr->args.fileid.dev;
1347 boolean
1348 pred_true (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1350 (void) pathname;
1351 (void) stat_buf;
1352 (void) pred_ptr;
1353 return true;
1356 boolean
1357 pred_type (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1359 mode_t mode;
1360 mode_t type = pred_ptr->args.type;
1362 assert(state.have_type);
1363 assert(state.type != 0);
1365 (void) pathname;
1367 if (state.have_stat)
1368 mode = stat_buf->st_mode;
1369 else
1370 mode = state.type;
1372 #ifndef S_IFMT
1373 /* POSIX system; check `mode' the slow way. */
1374 if ((S_ISBLK (mode) && type == S_IFBLK)
1375 || (S_ISCHR (mode) && type == S_IFCHR)
1376 || (S_ISDIR (mode) && type == S_IFDIR)
1377 || (S_ISREG (mode) && type == S_IFREG)
1378 #ifdef S_IFLNK
1379 || (S_ISLNK (mode) && type == S_IFLNK)
1380 #endif
1381 #ifdef S_IFIFO
1382 || (S_ISFIFO (mode) && type == S_IFIFO)
1383 #endif
1384 #ifdef S_IFSOCK
1385 || (S_ISSOCK (mode) && type == S_IFSOCK)
1386 #endif
1387 #ifdef S_IFDOOR
1388 || (S_ISDOOR (mode) && type == S_IFDOOR)
1389 #endif
1391 #else /* S_IFMT */
1392 /* Unix system; check `mode' the fast way. */
1393 if ((mode & S_IFMT) == type)
1394 #endif /* S_IFMT */
1395 return (true);
1396 else
1397 return (false);
1400 boolean
1401 pred_uid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1403 (void) pathname;
1404 switch (pred_ptr->args.info.kind)
1406 case COMP_GT:
1407 if (stat_buf->st_uid > pred_ptr->args.info.l_val)
1408 return (true);
1409 break;
1410 case COMP_LT:
1411 if (stat_buf->st_uid < pred_ptr->args.info.l_val)
1412 return (true);
1413 break;
1414 case COMP_EQ:
1415 if (stat_buf->st_uid == pred_ptr->args.info.l_val)
1416 return (true);
1417 break;
1419 return (false);
1422 boolean
1423 pred_used (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1425 time_t delta;
1427 (void) pathname;
1428 delta = stat_buf->st_atime - stat_buf->st_ctime; /* Use difftime? */
1429 return pred_timewindow(delta, pred_ptr, DAYSECS);
1432 boolean
1433 pred_user (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1435 (void) pathname;
1436 if (pred_ptr->args.uid == stat_buf->st_uid)
1437 return (true);
1438 else
1439 return (false);
1442 boolean
1443 pred_xtype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1445 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
1446 int (*ystat) (const char*, struct stat *p);
1448 switch (options.symlink_handling)
1450 case SYMLINK_ALWAYS_DEREF:
1451 ystat = optionl_stat;
1452 case SYMLINK_DEREF_ARGSONLY:
1453 case SYMLINK_NEVER_DEREF:
1454 ystat = optionp_stat;
1457 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
1459 if (ystat == optionl_stat && errno == ENOENT)
1461 /* If we failed to follow the symlink,
1462 * fall back on looking at the symlink itself.
1464 /* Mimic behavior of ls -lL. */
1465 return (pred_type (pathname, stat_buf, pred_ptr));
1467 else
1469 error (0, errno, "%s", pathname);
1470 state.exit_status = 1;
1472 return false;
1474 /* Now that we have our stat() information, query it in the same
1475 * way that -type does.
1477 return (pred_type (pathname, &sbuf, pred_ptr));
1480 /* 1) fork to get a child; parent remembers the child pid
1481 2) child execs the command requested
1482 3) parent waits for child; checks for proper pid of child
1484 Possible returns:
1486 ret errno status(h) status(l)
1488 pid x signal# 0177 stopped
1489 pid x exit arg 0 term by _exit
1490 pid x 0 signal # term by signal
1491 -1 EINTR parent got signal
1492 -1 other some other kind of error
1494 Return true only if the pid matches, status(l) is
1495 zero, and the exit arg (status high) is 0.
1496 Otherwise return false, possibly printing an error message. */
1498 #if defined(NEW_EXEC)
1499 static void
1500 prep_child_for_exec (void)
1502 const char inputfile[] = "/dev/null";
1503 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1505 close(0);
1506 if (open(inputfile, O_RDONLY) < 0)
1508 /* This is not entirely fatal, since
1509 * executing the child with a closed
1510 * stdin is almost as good as executing it
1511 * with its stdin attached to /dev/null.
1513 error (0, errno, "%s", inputfile);
1520 launch (const struct buildcmd_control *ctl,
1521 struct buildcmd_state *buildstate)
1523 int wait_status;
1524 pid_t child_pid;
1525 static int first_time = 1;
1526 const struct exec_val *execp = buildstate->usercontext;
1528 /* Null terminate the arg list. */
1529 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false);
1531 /* Make sure output of command doesn't get mixed with find output. */
1532 fflush (stdout);
1533 fflush (stderr);
1535 /* Make sure to listen for the kids. */
1536 if (first_time)
1538 first_time = 0;
1539 signal (SIGCHLD, SIG_DFL);
1542 child_pid = fork ();
1543 if (child_pid == -1)
1544 error (1, errno, _("cannot fork"));
1545 if (child_pid == 0)
1547 /* We be the child. */
1548 prep_child_for_exec();
1550 /* For -exec and -ok, change directory back to the starting directory.
1551 * for -execdir and -okdir, stay in the directory we are searching
1552 * (the latter is more secure).
1554 if (!execp->use_current_dir)
1556 /* Even if DEBUG_STAT is set, don't announce our change of
1557 * directory, since we're not going to emit a subsequent
1558 * announcement of a call to stat() anyway, as we're about
1559 * to exec something.
1561 if (starting_desc < 0
1562 ? chdir (starting_dir) != 0
1563 : fchdir (starting_desc) != 0)
1565 error (0, errno, "%s", starting_dir);
1566 _exit (1);
1570 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv);
1571 error (0, errno, "%s", buildstate->cmd_argv[0]);
1572 _exit (1);
1576 /* In parent; set up for next time. */
1577 bc_clear_args(ctl, buildstate);
1580 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1)
1582 if (errno != EINTR)
1584 error (0, errno, _("error waiting for %s"), buildstate->cmd_argv[0]);
1585 state.exit_status = 1;
1586 return 0; /* FAIL */
1590 if (WIFSIGNALED (wait_status))
1592 error (0, 0, _("%s terminated by signal %d"),
1593 buildstate->cmd_argv[0], WTERMSIG (wait_status));
1595 if (execp->multiple)
1597 /* -exec \; just returns false if the invoked command fails.
1598 * -exec {} + returns true if the invoked command fails, but
1599 * sets the program exit status.
1601 state.exit_status = 1;
1604 return 1; /* OK */
1607 if (0 == WEXITSTATUS (wait_status))
1609 return 1; /* OK */
1611 else
1613 if (execp->multiple)
1615 /* -exec \; just returns false if the invoked command fails.
1616 * -exec {} + returns true if the invoked command fails, but
1617 * sets the program exit status.
1619 state.exit_status = 1;
1621 return 0; /* FAIL */
1625 #else
1626 static boolean
1627 launch (struct predicate *pred_ptr)
1629 int status;
1630 pid_t child_pid;
1631 struct exec_val *execp; /* Pointer for efficiency. */
1632 static int first_time = 1;
1634 execp = &pred_ptr->args.exec_vec;
1636 /* Make sure output of command doesn't get mixed with find output. */
1637 fflush (stdout);
1638 fflush (stderr);
1640 /* Make sure to listen for the kids. */
1641 if (first_time)
1643 first_time = 0;
1644 signal (SIGCHLD, SIG_DFL);
1647 child_pid = fork ();
1648 if (child_pid == -1)
1649 error (1, errno, _("cannot fork"));
1650 if (child_pid == 0)
1652 /* We be the child. */
1653 if (starting_desc < 0
1654 ? chdir (starting_dir) != 0
1655 : fchdir (starting_desc) != 0)
1657 error (0, errno, "%s", starting_dir);
1658 _exit (1);
1660 execvp (execp->vec[0], execp->vec);
1661 error (0, errno, "%s", execp->vec[0]);
1662 _exit (1);
1666 while (waitpid (child_pid, &status, 0) == (pid_t) -1)
1667 if (errno != EINTR)
1669 error (0, errno, _("error waiting for %s"), execp->vec[0]);
1670 state.exit_status = 1;
1671 return false;
1673 if (WIFSIGNALED (status))
1675 error (0, 0, _("%s terminated by signal %d"),
1676 execp->vec[0], WTERMSIG (status));
1677 state.exit_status = 1;
1678 return (false);
1680 return (!WEXITSTATUS (status));
1682 #endif
1685 /* Return a static string formatting the time WHEN according to the
1686 strftime format character KIND. */
1688 static char *
1689 format_date (time_t when, int kind)
1691 static char buf[MAX (LONGEST_HUMAN_READABLE + 2, 64)];
1692 struct tm *tm;
1693 char fmt[6];
1695 fmt[0] = '%';
1696 fmt[1] = kind;
1697 fmt[2] = '\0';
1698 if (kind == '+')
1699 strcpy (fmt, "%F+%T");
1701 if (kind != '@'
1702 && (tm = localtime (&when))
1703 && strftime (buf, sizeof buf, fmt, tm))
1704 return buf;
1705 else
1707 uintmax_t w = when;
1708 char *p = human_readable (when < 0 ? -w : w, buf + 1,
1709 human_ceiling, 1, 1);
1710 if (when < 0)
1711 *--p = '-';
1712 return p;
1716 static char *
1717 ctime_format (when)
1718 time_t when;
1720 char *r = ctime (&when);
1721 if (!r)
1723 /* The time cannot be represented as a struct tm.
1724 Output it as an integer. */
1725 return format_date (when, '@');
1727 else
1729 /* Remove the trailing newline from the ctime output,
1730 being careful not to assume that the output is fixed-width. */
1731 *strchr (r, '\n') = '\0';
1732 return r;
1736 #ifdef DEBUG
1737 /* Return a pointer to the string representation of
1738 the predicate function PRED_FUNC. */
1740 char *
1741 find_pred_name (pred_func)
1742 PFB pred_func;
1744 int i;
1746 for (i = 0; pred_table[i].pred_func != 0; i++)
1747 if (pred_table[i].pred_func == pred_func)
1748 break;
1749 return (pred_table[i].pred_name);
1752 static char *
1753 type_name (type)
1754 short type;
1756 int i;
1758 for (i = 0; type_table[i].type != (short) -1; i++)
1759 if (type_table[i].type == type)
1760 break;
1761 return (type_table[i].type_name);
1764 static char *
1765 prec_name (prec)
1766 short prec;
1768 int i;
1770 for (i = 0; prec_table[i].prec != (short) -1; i++)
1771 if (prec_table[i].prec == prec)
1772 break;
1773 return (prec_table[i].prec_name);
1776 /* Walk the expression tree NODE to stdout.
1777 INDENT is the number of levels to indent the left margin. */
1779 void
1780 print_tree (FILE *fp, struct predicate *node, int indent)
1782 int i;
1784 if (node == NULL)
1785 return;
1786 for (i = 0; i < indent; i++)
1787 fprintf (fp, " ");
1788 fprintf (fp, "pred = %s type = %s prec = %s addr = %p\n",
1789 find_pred_name (node->pred_func),
1790 type_name (node->p_type), prec_name (node->p_prec), node);
1791 if (node->need_stat || node->need_type)
1793 int comma = 0;
1795 for (i = 0; i < indent; i++)
1796 fprintf (fp, " ");
1798 fprintf (fp, "Needs ");
1799 if (node->need_stat)
1801 fprintf (fp, "stat");
1802 comma = 1;
1804 if (node->need_type)
1806 fprintf (fp, "%stype", comma ? "," : "");
1808 fprintf (fp, "\n");
1811 for (i = 0; i < indent; i++)
1812 fprintf (fp, " ");
1813 fprintf (fp, _("left:\n"));
1814 print_tree (fp, node->pred_left, indent + 1);
1815 for (i = 0; i < indent; i++)
1816 fprintf (fp, " ");
1817 fprintf (fp, _("right:\n"));
1818 print_tree (fp, node->pred_right, indent + 1);
1821 /* Copy STR into BUF and trim blanks from the end of BUF.
1822 Return BUF. */
1824 static char *
1825 blank_rtrim (str, buf)
1826 char *str;
1827 char *buf;
1829 int i;
1831 if (str == NULL)
1832 return (NULL);
1833 strcpy (buf, str);
1834 i = strlen (buf) - 1;
1835 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
1836 i--;
1837 buf[++i] = '\0';
1838 return (buf);
1841 /* Print out the predicate list starting at NODE. */
1843 void
1844 print_list (FILE *fp, struct predicate *node)
1846 struct predicate *cur;
1847 char name[256];
1849 cur = node;
1850 while (cur != NULL)
1852 fprintf (fp, "%s ", blank_rtrim (find_pred_name (cur->pred_func), name));
1853 cur = cur->pred_next;
1855 fprintf (fp, "\n");
1859 /* Print out the predicate list starting at NODE. */
1862 static void
1863 print_parenthesised(FILE *fp, struct predicate *node)
1865 int parens = 0;
1867 if (node)
1869 if ( ( (node->pred_func == pred_or)
1870 || (node->pred_func == pred_and) )
1871 && node->pred_left == NULL)
1873 /* We print "<nothing> or X" as just "X"
1874 * We print "<nothing> and X" as just "X"
1876 print_parenthesised(fp, node->pred_right);
1878 else
1880 if (node->pred_left || node->pred_right)
1881 parens = 1;
1883 if (parens)
1884 fprintf(fp, "%s", " ( ");
1885 print_optlist(fp, node);
1886 if (parens)
1887 fprintf(fp, "%s", " ) ");
1892 void
1893 print_optlist (FILE *fp, struct predicate *p)
1895 char name[256];
1897 if (p)
1899 print_parenthesised(fp, p->pred_left);
1900 fprintf (fp,
1901 "%s%s%s ",
1902 p->need_stat ? _("[stat called here] ") : "",
1903 p->need_type ? _("[type needed here] ") : "",
1904 blank_rtrim (find_pred_name (p->pred_func), name));
1905 print_parenthesised(fp, p->pred_right);
1909 #endif /* DEBUG */