Use the new find program, and the new way of locating it (/ instead of )
[findutils.git] / find / pred.c
blob085475ae99ad90df35eab95216a71e2ba5a3229b
1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
3 2004, 2005 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
18 USA.
21 #include "defs.h"
23 #include <fnmatch.h>
24 #include <signal.h>
25 #include <pwd.h>
26 #include <grp.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <assert.h>
30 #include <fcntl.h>
31 #include "xalloc.h"
32 #include "dirname.h"
33 #include "human.h"
34 #include "modetype.h"
35 #include "filemode.h"
36 #include "wait.h"
37 #include "printquoted.h"
38 #include "buildcmd.h"
39 #include "yesno.h"
40 #include "listfile.h"
42 #if ENABLE_NLS
43 # include <libintl.h>
44 # define _(Text) gettext (Text)
45 #else
46 # define _(Text) Text
47 #endif
48 #ifdef gettext_noop
49 # define N_(String) gettext_noop (String)
50 #else
51 /* See locate.c for explanation as to why not use (String) */
52 # define N_(String) String
53 #endif
55 #if !defined(SIGCHLD) && defined(SIGCLD)
56 #define SIGCHLD SIGCLD
57 #endif
61 #if HAVE_DIRENT_H
62 # include <dirent.h>
63 # define NAMLEN(dirent) strlen((dirent)->d_name)
64 #else
65 # define dirent direct
66 # define NAMLEN(dirent) (dirent)->d_namlen
67 # if HAVE_SYS_NDIR_H
68 # include <sys/ndir.h>
69 # endif
70 # if HAVE_SYS_DIR_H
71 # include <sys/dir.h>
72 # endif
73 # if HAVE_NDIR_H
74 # include <ndir.h>
75 # endif
76 #endif
78 #ifdef CLOSEDIR_VOID
79 /* Fake a return value. */
80 #define CLOSEDIR(d) (closedir (d), 0)
81 #else
82 #define CLOSEDIR(d) closedir (d)
83 #endif
88 /* Get or fake the disk device blocksize.
89 Usually defined by sys/param.h (if at all). */
90 #ifndef DEV_BSIZE
91 # ifdef BSIZE
92 # define DEV_BSIZE BSIZE
93 # else /* !BSIZE */
94 # define DEV_BSIZE 4096
95 # endif /* !BSIZE */
96 #endif /* !DEV_BSIZE */
98 /* Extract or fake data from a `struct stat'.
99 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
100 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
101 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
102 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
103 # define ST_BLKSIZE(statbuf) DEV_BSIZE
104 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
105 # define ST_NBLOCKS(statbuf) \
106 (S_ISREG ((statbuf).st_mode) \
107 || S_ISDIR ((statbuf).st_mode) \
108 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
109 # else /* !_POSIX_SOURCE && BSIZE */
110 # define ST_NBLOCKS(statbuf) \
111 (S_ISREG ((statbuf).st_mode) \
112 || S_ISDIR ((statbuf).st_mode) \
113 ? st_blocks ((statbuf).st_size) : 0)
114 # endif /* !_POSIX_SOURCE && BSIZE */
115 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
116 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
117 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
118 ? (statbuf).st_blksize : DEV_BSIZE)
119 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
120 /* HP-UX counts st_blocks in 1024-byte units.
121 This loses when mixing HP-UX and BSD filesystems with NFS. */
122 # define ST_NBLOCKSIZE 1024
123 # else /* !hpux */
124 # if defined(_AIX) && defined(_I386)
125 /* AIX PS/2 counts st_blocks in 4K units. */
126 # define ST_NBLOCKSIZE (4 * 1024)
127 # else /* not AIX PS/2 */
128 # if defined(_CRAY)
129 # define ST_NBLOCKS(statbuf) \
130 (S_ISREG ((statbuf).st_mode) \
131 || S_ISDIR ((statbuf).st_mode) \
132 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
133 # endif /* _CRAY */
134 # endif /* not AIX PS/2 */
135 # endif /* !hpux */
136 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
138 #ifndef ST_NBLOCKS
139 # define ST_NBLOCKS(statbuf) \
140 (S_ISREG ((statbuf).st_mode) \
141 || S_ISDIR ((statbuf).st_mode) \
142 ? (statbuf).st_blocks : 0)
143 #endif
145 #ifndef ST_NBLOCKSIZE
146 # define ST_NBLOCKSIZE 512
147 #endif
150 #undef MAX
151 #define MAX(a, b) ((a) > (b) ? (a) : (b))
153 static boolean insert_lname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case));
155 static char *format_date PARAMS((time_t when, int kind));
156 static char *ctime_format PARAMS((time_t when));
158 #ifdef DEBUG
159 struct pred_assoc
161 PRED_FUNC pred_func;
162 char *pred_name;
165 struct pred_assoc pred_table[] =
167 {pred_amin, "amin "},
168 {pred_and, "and "},
169 {pred_anewer, "anewer "},
170 {pred_atime, "atime "},
171 {pred_close, ") "},
172 {pred_amin, "cmin "},
173 {pred_cnewer, "cnewer "},
174 {pred_comma, ", "},
175 {pred_ctime, "ctime "},
176 {pred_delete, "delete "},
177 {pred_empty, "empty "},
178 {pred_exec, "exec "},
179 {pred_execdir, "execdir "},
180 {pred_false, "false "},
181 {pred_fprint, "fprint "},
182 {pred_fprint0, "fprint0 "},
183 {pred_fprintf, "fprintf "},
184 {pred_fstype, "fstype "},
185 {pred_gid, "gid "},
186 {pred_group, "group "},
187 {pred_ilname, "ilname "},
188 {pred_iname, "iname "},
189 {pred_inum, "inum "},
190 {pred_ipath, "ipath "},
191 {pred_links, "links "},
192 {pred_lname, "lname "},
193 {pred_ls, "ls "},
194 {pred_amin, "mmin "},
195 {pred_mtime, "mtime "},
196 {pred_name, "name "},
197 {pred_negate, "not "},
198 {pred_newer, "newer "},
199 {pred_nogroup, "nogroup "},
200 {pred_nouser, "nouser "},
201 {pred_ok, "ok "},
202 {pred_okdir, "okdir "},
203 {pred_open, "( "},
204 {pred_or, "or "},
205 {pred_path, "path "},
206 {pred_perm, "perm "},
207 {pred_print, "print "},
208 {pred_print0, "print0 "},
209 {pred_prune, "prune "},
210 {pred_regex, "regex "},
211 {pred_samefile,"samefile "},
212 {pred_size, "size "},
213 {pred_true, "true "},
214 {pred_type, "type "},
215 {pred_uid, "uid "},
216 {pred_used, "used "},
217 {pred_user, "user "},
218 {pred_xtype, "xtype "},
219 {0, "none "}
222 struct op_assoc
224 short type;
225 char *type_name;
228 struct op_assoc type_table[] =
230 {NO_TYPE, "no "},
231 {PRIMARY_TYPE, "primary "},
232 {UNI_OP, "uni_op "},
233 {BI_OP, "bi_op "},
234 {OPEN_PAREN, "open_paren "},
235 {CLOSE_PAREN, "close_paren "},
236 {-1, "unknown "}
239 struct prec_assoc
241 short prec;
242 char *prec_name;
245 struct prec_assoc prec_table[] =
247 {NO_PREC, "no "},
248 {COMMA_PREC, "comma "},
249 {OR_PREC, "or "},
250 {AND_PREC, "and "},
251 {NEGATE_PREC, "negate "},
252 {MAX_PREC, "max "},
253 {-1, "unknown "}
255 #endif /* DEBUG */
257 /* Predicate processing routines.
259 PATHNAME is the full pathname of the file being checked.
260 *STAT_BUF contains information about PATHNAME.
261 *PRED_PTR contains information for applying the predicate.
263 Return true if the file passes this predicate, false if not. */
266 /* pred_timewindow
268 * Returns true if THE_TIME is
269 * COMP_GT: after the specified time
270 * COMP_LT: before the specified time
271 * COMP_EQ: less than WINDOW seconds after the specified time.
273 static boolean
274 pred_timewindow(time_t the_time, struct predicate const *pred_ptr, int window)
276 switch (pred_ptr->args.info.kind)
278 case COMP_GT:
279 if (the_time > (time_t) pred_ptr->args.info.l_val)
280 return true;
281 break;
282 case COMP_LT:
283 if (the_time < (time_t) pred_ptr->args.info.l_val)
284 return true;
285 break;
286 case COMP_EQ:
287 if ((the_time >= (time_t) pred_ptr->args.info.l_val)
288 && (the_time < (time_t) pred_ptr->args.info.l_val + window))
289 return true;
290 break;
292 return false;
296 boolean
297 pred_amin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
299 (void) &pathname;
300 return pred_timewindow(stat_buf->st_atime, pred_ptr, 60);
303 boolean
304 pred_and (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
306 if (pred_ptr->pred_left == NULL
307 || (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
308 pred_ptr->pred_left))
310 /* Check whether we need a stat here. */
311 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
312 return false;
313 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
314 pred_ptr->pred_right));
316 else
317 return (false);
320 boolean
321 pred_anewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
323 (void) &pathname;
325 if (stat_buf->st_atime > pred_ptr->args.time)
326 return (true);
327 return (false);
330 boolean
331 pred_atime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
333 (void) &pathname;
334 return pred_timewindow(stat_buf->st_atime, pred_ptr, DAYSECS);
337 boolean
338 pred_close (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
340 (void) &pathname;
341 (void) &stat_buf;
342 (void) &pred_ptr;
344 return true;
347 boolean
348 pred_cmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
350 (void) pathname;
351 return pred_timewindow(stat_buf->st_ctime, pred_ptr, 60);
354 boolean
355 pred_cnewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
357 (void) pathname;
359 if (stat_buf->st_ctime > pred_ptr->args.time)
360 return true;
361 else
362 return false;
365 boolean
366 pred_comma (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
368 if (pred_ptr->pred_left != NULL)
369 (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
370 pred_ptr->pred_left);
371 /* Check whether we need a stat here. */
372 /* TODO: what about need_type? */
373 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
374 return false;
375 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
376 pred_ptr->pred_right));
379 boolean
380 pred_ctime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
382 (void) &pathname;
383 return pred_timewindow(stat_buf->st_ctime, pred_ptr, DAYSECS);
386 boolean
387 pred_delete (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
389 (void) pred_ptr;
390 (void) stat_buf;
391 if (strcmp (state.rel_pathname, "."))
393 if (0 != remove (state.rel_pathname))
395 error (0, errno, "cannot delete %s", pathname);
396 return false;
398 else
400 return true;
404 /* nothing to do. */
405 return true;
408 boolean
409 pred_empty (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
411 (void) pathname;
412 (void) pred_ptr;
414 if (S_ISDIR (stat_buf->st_mode))
416 DIR *d;
417 struct dirent *dp;
418 boolean empty = true;
420 errno = 0;
421 d = opendir (state.rel_pathname);
422 if (d == NULL)
424 error (0, errno, "%s", pathname);
425 state.exit_status = 1;
426 return false;
428 for (dp = readdir (d); dp; dp = readdir (d))
430 if (dp->d_name[0] != '.'
431 || (dp->d_name[1] != '\0'
432 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
434 empty = false;
435 break;
438 if (CLOSEDIR (d))
440 error (0, errno, "%s", pathname);
441 state.exit_status = 1;
442 return false;
444 return (empty);
446 else if (S_ISREG (stat_buf->st_mode))
447 return (stat_buf->st_size == 0);
448 else
449 return (false);
452 static boolean
453 new_impl_pred_exec (const char *pathname, struct stat *stat_buf,
454 struct predicate *pred_ptr,
455 const char *prefix, size_t pfxlen)
457 struct exec_val *execp = &pred_ptr->args.exec_vec;
458 size_t len = strlen(pathname);
460 (void) stat_buf;
462 if (execp->multiple)
464 /* Push the argument onto the current list.
465 * The command may or may not be run at this point,
466 * depending on the command line length limits.
468 bc_push_arg(&execp->ctl,
469 &execp->state,
470 pathname, len+1,
471 prefix, pfxlen,
474 /* POSIX: If the primary expression is punctuated by a plus
475 * sign, the primary shall always evaluate as true
477 return true;
479 else
481 int i;
483 for (i=0; i<execp->num_args; ++i)
485 bc_do_insert(&execp->ctl,
486 &execp->state,
487 execp->replace_vec[i],
488 strlen(execp->replace_vec[i]),
489 prefix, pfxlen,
490 pathname, len,
494 /* Actually invoke the command. */
495 return execp->ctl.exec_callback(&execp->ctl,
496 &execp->state);
501 boolean
502 pred_exec (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
504 return new_impl_pred_exec(pathname, stat_buf, pred_ptr, NULL, 0);
507 boolean
508 pred_execdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
510 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
511 (void) &pathname;
512 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr,
513 prefix, (prefix ? 2 : 0));
516 boolean
517 pred_false (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
519 (void) &pathname;
520 (void) &stat_buf;
521 (void) &pred_ptr;
524 return (false);
527 boolean
528 pred_fls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
530 list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
531 options.output_block_size,
532 pred_ptr->literal_control_chars, pred_ptr->args.stream);
533 return true;
536 boolean
537 pred_fprint (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
539 (void) &pathname;
540 (void) &stat_buf;
542 print_quoted(pred_ptr->args.printf_vec.stream,
543 pred_ptr->args.printf_vec.quote_opts,
544 pred_ptr->args.printf_vec.dest_is_tty,
545 "%s\n",
546 pathname);
547 return true;
550 boolean
551 pred_fprint0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
553 (void) &pathname;
554 (void) &stat_buf;
556 fputs (pathname, pred_ptr->args.stream);
557 putc (0, pred_ptr->args.stream);
558 return (true);
563 static char*
564 mode_to_filetype(mode_t m)
566 return
567 m == S_IFSOCK ? "s" :
568 m == S_IFLNK ? "l" :
569 m == S_IFREG ? "f" :
570 m == S_IFBLK ? "b" :
571 m == S_IFDIR ? "d" :
572 m == S_IFCHR ? "c" :
573 #ifdef S_IFDOOR
574 m == S_IFDOOR ? "D" :
575 #endif
576 m == S_IFIFO ? "p" : "U";
580 boolean
581 pred_fprintf (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
583 FILE *fp = pred_ptr->args.printf_vec.stream;
584 const struct quoting_options *qopts = pred_ptr->args.printf_vec.quote_opts;
585 boolean ttyflag = pred_ptr->args.printf_vec.dest_is_tty;
586 struct segment *segment;
587 char *cp;
588 char hbuf[LONGEST_HUMAN_READABLE + 1];
590 for (segment = pred_ptr->args.printf_vec.segment; segment;
591 segment = segment->next)
593 if (segment->kind & 0xff00) /* Component of date. */
595 time_t t;
597 switch (segment->kind & 0xff)
599 case 'A':
600 t = stat_buf->st_atime;
601 break;
602 case 'C':
603 t = stat_buf->st_ctime;
604 break;
605 case 'T':
606 t = stat_buf->st_mtime;
607 break;
608 default:
609 abort ();
611 /* We trust the output of format_date not to contain
612 * nasty characters, though the value of the date
613 * is itself untrusted data.
615 /* trusted */
616 fprintf (fp, segment->text,
617 format_date (t, (segment->kind >> 8) & 0xff));
618 continue;
621 switch (segment->kind)
623 case KIND_PLAIN: /* Plain text string (no % conversion). */
624 /* trusted */
625 fwrite (segment->text, 1, segment->text_len, fp);
626 break;
627 case KIND_STOP: /* Terminate argument and flush output. */
628 /* trusted */
629 fwrite (segment->text, 1, segment->text_len, fp);
630 fflush (fp);
631 return (true);
632 case 'a': /* atime in `ctime' format. */
633 /* UNTRUSTED, probably unexploitable */
634 fprintf (fp, segment->text, ctime_format (stat_buf->st_atime));
635 break;
636 case 'b': /* size in 512-byte blocks */
637 /* UNTRUSTED, probably unexploitable */
638 fprintf (fp, segment->text,
639 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
640 hbuf, human_ceiling,
641 ST_NBLOCKSIZE, 512));
642 break;
643 case 'c': /* ctime in `ctime' format */
644 /* UNTRUSTED, probably unexploitable */
645 fprintf (fp, segment->text, ctime_format (stat_buf->st_ctime));
646 break;
647 case 'd': /* depth in search tree */
648 /* UNTRUSTED, probably unexploitable */
649 fprintf (fp, segment->text, state.curdepth);
650 break;
651 case 'D': /* Device on which file exists (stat.st_dev) */
652 /* trusted */
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': /* base name of path */
658 /* sanitised */
659 print_quoted (fp, qopts, ttyflag, segment->text, base_name (pathname));
660 break;
661 case 'F': /* filesystem type */
662 /* trusted */
663 print_quoted (fp, qopts, ttyflag, segment->text, filesystem_type (stat_buf, pathname));
664 break;
665 case 'g': /* group name */
666 /* trusted */
667 /* (well, the actual group is selected by the user but
668 * its name was selected by the system administrator)
671 struct group *g;
673 g = getgrgid (stat_buf->st_gid);
674 if (g)
676 segment->text[segment->text_len] = 's';
677 fprintf (fp, segment->text, g->gr_name);
678 break;
680 /* else fallthru */
682 case 'G': /* GID number */
683 /* UNTRUSTED, probably unexploitable */
684 fprintf (fp, segment->text,
685 human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
686 human_ceiling, 1, 1));
687 break;
688 case 'h': /* leading directories part of path */
689 /* sanitised */
691 char cc;
693 cp = strrchr (pathname, '/');
694 if (cp == NULL) /* No leading directories. */
696 /* If there is no slash in the pathname, we still
697 * print the string because it contains characters
698 * other than just '%s'. The %h expands to ".".
700 print_quoted (fp, qopts, ttyflag, segment->text, ".");
702 else
704 cc = *cp;
705 *cp = '\0';
706 print_quoted (fp, qopts, ttyflag, segment->text, pathname);
707 *cp = cc;
709 break;
711 case 'H': /* ARGV element file was found under */
712 /* trusted */
714 char cc = pathname[state.starting_path_length];
716 pathname[state.starting_path_length] = '\0';
717 fprintf (fp, segment->text, pathname);
718 pathname[state.starting_path_length] = cc;
719 break;
721 case 'i': /* inode number */
722 /* UNTRUSTED, but not exploitable I think */
723 fprintf (fp, segment->text,
724 human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
725 human_ceiling,
726 1, 1));
727 break;
728 case 'k': /* size in 1K blocks */
729 /* UNTRUSTED, but not exploitable I think */
730 fprintf (fp, segment->text,
731 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
732 hbuf, human_ceiling,
733 ST_NBLOCKSIZE, 1024));
734 break;
735 case 'l': /* object of symlink */
736 /* sanitised */
737 #ifdef S_ISLNK
739 char *linkname = 0;
741 if (S_ISLNK (stat_buf->st_mode))
743 linkname = get_link_name (pathname, state.rel_pathname);
744 if (linkname == 0)
745 state.exit_status = 1;
747 if (linkname)
749 print_quoted (fp, qopts, ttyflag, segment->text, linkname);
750 free (linkname);
752 else
753 print_quoted (fp, qopts, ttyflag, segment->text, "");
755 #endif /* S_ISLNK */
756 break;
758 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
759 /* UNTRUSTED, probably unexploitable */
761 char modestring[16] ;
762 mode_string (stat_buf->st_mode, modestring);
763 modestring[10] = '\0';
764 fprintf (fp, segment->text, modestring);
766 break;
768 case 'm': /* mode as octal number (perms only) */
769 /* UNTRUSTED, probably unexploitable */
771 /* Output the mode portably using the traditional numbers,
772 even if the host unwisely uses some other numbering
773 scheme. But help the compiler in the common case where
774 the host uses the traditional numbering scheme. */
775 mode_t m = stat_buf->st_mode;
776 boolean traditional_numbering_scheme =
777 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
778 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
779 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
780 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
781 fprintf (fp, segment->text,
782 (traditional_numbering_scheme
783 ? m & MODE_ALL
784 : ((m & S_ISUID ? 04000 : 0)
785 | (m & S_ISGID ? 02000 : 0)
786 | (m & S_ISVTX ? 01000 : 0)
787 | (m & S_IRUSR ? 00400 : 0)
788 | (m & S_IWUSR ? 00200 : 0)
789 | (m & S_IXUSR ? 00100 : 0)
790 | (m & S_IRGRP ? 00040 : 0)
791 | (m & S_IWGRP ? 00020 : 0)
792 | (m & S_IXGRP ? 00010 : 0)
793 | (m & S_IROTH ? 00004 : 0)
794 | (m & S_IWOTH ? 00002 : 0)
795 | (m & S_IXOTH ? 00001 : 0))));
797 break;
799 case 'n': /* number of links */
800 /* UNTRUSTED, probably unexploitable */
801 fprintf (fp, segment->text,
802 human_readable ((uintmax_t) stat_buf->st_nlink,
803 hbuf,
804 human_ceiling,
805 1, 1));
806 break;
807 case 'p': /* pathname */
808 /* sanitised */
809 print_quoted (fp, qopts, ttyflag, segment->text, pathname);
810 break;
811 case 'P': /* pathname with ARGV element stripped */
812 /* sanitised */
813 if (state.curdepth > 0)
815 cp = pathname + state.starting_path_length;
816 if (*cp == '/')
817 /* Move past the slash between the ARGV element
818 and the rest of the pathname. But if the ARGV element
819 ends in a slash, we didn't add another, so we've
820 already skipped past it. */
821 cp++;
823 else
824 cp = "";
825 print_quoted (fp, qopts, ttyflag, segment->text, cp);
826 break;
827 case 's': /* size in bytes */
828 /* UNTRUSTED, probably unexploitable */
829 fprintf (fp, segment->text,
830 human_readable ((uintmax_t) stat_buf->st_size,
831 hbuf, human_ceiling, 1, 1));
832 break;
833 case 't': /* mtime in `ctime' format */
834 /* UNTRUSTED, probably unexploitable */
835 fprintf (fp, segment->text, ctime_format (stat_buf->st_mtime));
836 break;
837 case 'u': /* user name */
838 /* trusted */
839 /* (well, the actual user is selected by the user on systems
840 * where chown is not restricted, but the user name was
841 * selected by the system administrator)
844 struct passwd *p;
846 p = getpwuid (stat_buf->st_uid);
847 if (p)
849 segment->text[segment->text_len] = 's';
850 fprintf (fp, segment->text, p->pw_name);
851 break;
853 /* else fallthru */
856 case 'U': /* UID number */
857 /* UNTRUSTED, probably unexploitable */
858 fprintf (fp, segment->text,
859 human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
860 human_ceiling, 1, 1));
861 break;
863 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
864 case 'Y': /* in case of symlink */
865 /* trusted */
867 #ifdef S_ISLNK
868 if (S_ISLNK (stat_buf->st_mode))
870 struct stat sbuf;
871 /* If we would normally follow links, do not do so.
872 * If we would normally not follow links, do so.
874 if ((following_links() ? lstat : stat)
875 (state.rel_pathname, &sbuf) != 0)
877 if ( errno == ENOENT ) {
878 fprintf (fp, segment->text, "N");
879 break;
881 if ( errno == ELOOP ) {
882 fprintf (fp, segment->text, "L");
883 break;
885 error (0, errno, "%s", pathname);
886 /* exit_status = 1;
887 return (false); */
889 fprintf (fp, segment->text,
890 mode_to_filetype(sbuf.st_mode & S_IFMT));
892 #endif /* S_ISLNK */
893 else
895 fprintf (fp, segment->text,
896 mode_to_filetype(stat_buf->st_mode & S_IFMT));
899 break;
901 case 'y':
902 /* trusted */
904 fprintf (fp, segment->text,
905 mode_to_filetype(stat_buf->st_mode & S_IFMT));
907 break;
910 return true;
913 boolean
914 pred_fstype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
916 (void) pathname;
918 if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0)
919 return true;
920 else
921 return false;
924 boolean
925 pred_gid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
927 (void) pathname;
929 switch (pred_ptr->args.info.kind)
931 case COMP_GT:
932 if (stat_buf->st_gid > pred_ptr->args.info.l_val)
933 return (true);
934 break;
935 case COMP_LT:
936 if (stat_buf->st_gid < pred_ptr->args.info.l_val)
937 return (true);
938 break;
939 case COMP_EQ:
940 if (stat_buf->st_gid == pred_ptr->args.info.l_val)
941 return (true);
942 break;
944 return (false);
947 boolean
948 pred_group (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
950 (void) pathname;
952 if (pred_ptr->args.gid == stat_buf->st_gid)
953 return (true);
954 else
955 return (false);
958 boolean
959 pred_ilname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
961 return insert_lname (pathname, stat_buf, pred_ptr, true);
964 boolean
965 pred_iname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
967 const char *base;
969 (void) stat_buf;
971 /* FNM_PERIOD is not used here because POSIX requires that it not be.
972 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
974 base = base_name (pathname);
975 if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0)
976 return (true);
977 return (false);
980 boolean
981 pred_inum (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_ino > pred_ptr->args.info.l_val)
989 return (true);
990 break;
991 case COMP_LT:
992 if (stat_buf->st_ino < pred_ptr->args.info.l_val)
993 return (true);
994 break;
995 case COMP_EQ:
996 if (stat_buf->st_ino == pred_ptr->args.info.l_val)
997 return (true);
998 break;
1000 return (false);
1003 boolean
1004 pred_ipath (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1006 (void) stat_buf;
1008 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
1009 return (true);
1010 return (false);
1013 boolean
1014 pred_links (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1016 (void) pathname;
1018 switch (pred_ptr->args.info.kind)
1020 case COMP_GT:
1021 if (stat_buf->st_nlink > pred_ptr->args.info.l_val)
1022 return (true);
1023 break;
1024 case COMP_LT:
1025 if (stat_buf->st_nlink < pred_ptr->args.info.l_val)
1026 return (true);
1027 break;
1028 case COMP_EQ:
1029 if (stat_buf->st_nlink == pred_ptr->args.info.l_val)
1030 return (true);
1031 break;
1033 return (false);
1036 boolean
1037 pred_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1039 return insert_lname (pathname, stat_buf, pred_ptr, false);
1042 static boolean
1043 insert_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)
1045 boolean ret = false;
1046 #ifdef S_ISLNK
1047 if (S_ISLNK (stat_buf->st_mode))
1049 char *linkname = get_link_name (pathname, state.rel_pathname);
1050 if (linkname)
1052 if (fnmatch (pred_ptr->args.str, linkname,
1053 ignore_case ? FNM_CASEFOLD : 0) == 0)
1054 ret = true;
1055 free (linkname);
1058 #endif /* S_ISLNK */
1059 return (ret);
1062 boolean
1063 pred_ls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1065 list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
1066 options.output_block_size,
1067 pred_ptr->literal_control_chars,
1068 stdout);
1069 return true;
1072 boolean
1073 pred_mmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1075 (void) &pathname;
1076 return pred_timewindow(stat_buf->st_mtime, pred_ptr, 60);
1079 boolean
1080 pred_mtime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1082 (void) pathname;
1083 return pred_timewindow(stat_buf->st_mtime, pred_ptr, DAYSECS);
1086 boolean
1087 pred_name (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1089 const char *base;
1091 (void) stat_buf;
1092 base = base_name (pathname);
1094 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1095 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1097 if (fnmatch (pred_ptr->args.str, base, 0) == 0)
1098 return (true);
1099 return (false);
1102 boolean
1103 pred_negate (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1105 /* Check whether we need a stat here. */
1106 /* TODO: what about need_type? */
1107 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1108 return false;
1109 return (!(*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1110 pred_ptr->pred_right));
1113 boolean
1114 pred_newer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1116 (void) pathname;
1118 if (stat_buf->st_mtime > pred_ptr->args.time)
1119 return (true);
1120 return (false);
1123 boolean
1124 pred_nogroup (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1126 (void) pathname;
1127 (void) pred_ptr;
1129 #ifdef CACHE_IDS
1130 extern char *gid_unused;
1132 return gid_unused[(unsigned) stat_buf->st_gid];
1133 #else
1134 return getgrgid (stat_buf->st_gid) == NULL;
1135 #endif
1138 boolean
1139 pred_nouser (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1141 #ifdef CACHE_IDS
1142 extern char *uid_unused;
1143 #endif
1145 (void) pathname;
1146 (void) pred_ptr;
1148 #ifdef CACHE_IDS
1149 return uid_unused[(unsigned) stat_buf->st_uid];
1150 #else
1151 return getpwuid (stat_buf->st_uid) == NULL;
1152 #endif
1156 static boolean
1157 is_ok(const char *program, const char *arg)
1159 fflush (stdout);
1160 /* The draft open standard requires that, in the POSIX locale,
1161 the last non-blank character of this prompt be '?'.
1162 The exact format is not specified.
1163 This standard does not have requirements for locales other than POSIX
1165 /* XXX: printing UNTRUSTED data here. */
1166 fprintf (stderr, _("< %s ... %s > ? "), program, arg);
1167 fflush (stderr);
1168 return yesno();
1171 boolean
1172 pred_ok (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1174 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1175 return new_impl_pred_exec (pathname, stat_buf, pred_ptr, NULL, 0);
1176 else
1177 return false;
1180 boolean
1181 pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1183 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
1184 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1185 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr,
1186 prefix, (prefix ? 2 : 0));
1187 else
1188 return false;
1191 boolean
1192 pred_open (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1194 (void) pathname;
1195 (void) stat_buf;
1196 (void) pred_ptr;
1197 return true;
1200 boolean
1201 pred_or (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1203 if (pred_ptr->pred_left == NULL
1204 || !(*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
1205 pred_ptr->pred_left))
1207 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1208 return false;
1209 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1210 pred_ptr->pred_right));
1212 else
1213 return true;
1216 boolean
1217 pred_path (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1219 (void) stat_buf;
1220 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
1221 return (true);
1222 return (false);
1225 boolean
1226 pred_perm (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1228 (void) pathname;
1229 switch (pred_ptr->args.perm.kind)
1231 case PERM_AT_LEAST:
1232 return (stat_buf->st_mode & pred_ptr->args.perm.val) == pred_ptr->args.perm.val;
1233 break;
1235 case PERM_ANY:
1236 /* True if any of the bits set in the mask are also set in the file's mode.
1239 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1240 * evaluate as true if at least all of the bits specified in
1241 * onum that are also set in the octal mask 07777 are set.
1243 * Eric Blake's interpretation is that the mode argument is zero,
1246 if (0 == pred_ptr->args.perm.val)
1247 return true; /* Savannah bug 14748; we used to return false */
1248 else
1249 return (stat_buf->st_mode & pred_ptr->args.perm.val) != 0;
1250 break;
1252 case PERM_EXACT:
1253 return (stat_buf->st_mode & MODE_ALL) == pred_ptr->args.perm.val;
1254 break;
1256 default:
1257 abort ();
1258 break;
1263 boolean
1264 pred_executable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1266 return 0 == access(state.rel_pathname, X_OK);
1269 boolean
1270 pred_readable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1272 return 0 == access(state.rel_pathname, R_OK);
1275 boolean
1276 pred_writable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1278 return 0 == access(state.rel_pathname, W_OK);
1281 boolean
1282 pred_print (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1284 (void) stat_buf;
1285 (void) pred_ptr;
1286 /* puts (pathname); */
1287 print_quoted(pred_ptr->args.printf_vec.stream,
1288 pred_ptr->args.printf_vec.quote_opts,
1289 pred_ptr->args.printf_vec.dest_is_tty,
1290 "%s\n", pathname);
1291 return true;
1294 boolean
1295 pred_print0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1297 (void) stat_buf;
1298 (void) pred_ptr;
1299 fputs (pathname, stdout);
1300 putc (0, stdout);
1301 return (true);
1304 boolean
1305 pred_prune (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1307 (void) pathname;
1308 (void) stat_buf;
1309 (void) pred_ptr;
1310 state.stop_at_current_level = true;
1311 return (options.do_dir_first); /* This is what SunOS find seems to do. */
1314 boolean
1315 pred_quit (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1317 (void) pathname;
1318 (void) stat_buf;
1319 (void) pred_ptr;
1321 /* Run any cleanups. This includes executing any command lines
1322 * we have partly built but not executed.
1324 cleanup();
1326 /* Since -exec and friends don't leave child processes running in the
1327 * background, there is no need to wait for them here.
1329 exit(state.exit_status); /* 0 for success, etc. */
1332 boolean
1333 pred_regex (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1335 int len = strlen (pathname);
1336 (void) stat_buf;
1337 if (re_match (pred_ptr->args.regex, pathname, len, 0,
1338 (struct re_registers *) NULL) == len)
1339 return (true);
1340 return (false);
1343 boolean
1344 pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1346 uintmax_t f_val;
1348 (void) pathname;
1349 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
1350 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
1351 switch (pred_ptr->args.size.kind)
1353 case COMP_GT:
1354 if (f_val > pred_ptr->args.size.size)
1355 return (true);
1356 break;
1357 case COMP_LT:
1358 if (f_val < pred_ptr->args.size.size)
1359 return (true);
1360 break;
1361 case COMP_EQ:
1362 if (f_val == pred_ptr->args.size.size)
1363 return (true);
1364 break;
1366 return (false);
1369 boolean
1370 pred_samefile (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1372 /* Potential optimisation: because of the loop protection, we always
1373 * know the device of the current directory, hence the device number
1374 * of the file we're currently considering. If -L is not in effect,
1375 * and the device number of the file we're looking for is not the
1376 * same as the device number of the current directory, this
1377 * predicate cannot return true. Hence there would be no need to
1378 * stat the file we're lookingn at.
1380 (void) pathname;
1382 return stat_buf->st_ino == pred_ptr->args.fileid.ino
1383 && stat_buf->st_dev == pred_ptr->args.fileid.dev;
1386 boolean
1387 pred_true (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1389 (void) pathname;
1390 (void) stat_buf;
1391 (void) pred_ptr;
1392 return true;
1395 boolean
1396 pred_type (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1398 mode_t mode;
1399 mode_t type = pred_ptr->args.type;
1401 assert(state.have_type);
1402 assert(state.type != 0);
1404 (void) pathname;
1406 if (state.have_stat)
1407 mode = stat_buf->st_mode;
1408 else
1409 mode = state.type;
1411 #ifndef S_IFMT
1412 /* POSIX system; check `mode' the slow way. */
1413 if ((S_ISBLK (mode) && type == S_IFBLK)
1414 || (S_ISCHR (mode) && type == S_IFCHR)
1415 || (S_ISDIR (mode) && type == S_IFDIR)
1416 || (S_ISREG (mode) && type == S_IFREG)
1417 #ifdef S_IFLNK
1418 || (S_ISLNK (mode) && type == S_IFLNK)
1419 #endif
1420 #ifdef S_IFIFO
1421 || (S_ISFIFO (mode) && type == S_IFIFO)
1422 #endif
1423 #ifdef S_IFSOCK
1424 || (S_ISSOCK (mode) && type == S_IFSOCK)
1425 #endif
1426 #ifdef S_IFDOOR
1427 || (S_ISDOOR (mode) && type == S_IFDOOR)
1428 #endif
1430 #else /* S_IFMT */
1431 /* Unix system; check `mode' the fast way. */
1432 if ((mode & S_IFMT) == type)
1433 #endif /* S_IFMT */
1434 return (true);
1435 else
1436 return (false);
1439 boolean
1440 pred_uid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1442 (void) pathname;
1443 switch (pred_ptr->args.info.kind)
1445 case COMP_GT:
1446 if (stat_buf->st_uid > pred_ptr->args.info.l_val)
1447 return (true);
1448 break;
1449 case COMP_LT:
1450 if (stat_buf->st_uid < pred_ptr->args.info.l_val)
1451 return (true);
1452 break;
1453 case COMP_EQ:
1454 if (stat_buf->st_uid == pred_ptr->args.info.l_val)
1455 return (true);
1456 break;
1458 return (false);
1461 boolean
1462 pred_used (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1464 time_t delta;
1466 (void) pathname;
1467 delta = stat_buf->st_atime - stat_buf->st_ctime; /* Use difftime? */
1468 return pred_timewindow(delta, pred_ptr, DAYSECS);
1471 boolean
1472 pred_user (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1474 (void) pathname;
1475 if (pred_ptr->args.uid == stat_buf->st_uid)
1476 return (true);
1477 else
1478 return (false);
1481 boolean
1482 pred_xtype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1484 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
1485 int (*ystat) (const char*, struct stat *p);
1487 /* If we would normally stat the link itself, stat the target instead.
1488 * If we would normally follow the link, stat the link itself instead.
1490 if (following_links())
1491 ystat = optionp_stat;
1492 else
1493 ystat = optionl_stat;
1495 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
1497 if (following_links() && errno == ENOENT)
1499 /* If we failed to follow the symlink,
1500 * fall back on looking at the symlink itself.
1502 /* Mimic behavior of ls -lL. */
1503 return (pred_type (pathname, stat_buf, pred_ptr));
1505 else
1507 error (0, errno, "%s", pathname);
1508 state.exit_status = 1;
1510 return false;
1512 /* Now that we have our stat() information, query it in the same
1513 * way that -type does.
1515 return (pred_type (pathname, &sbuf, pred_ptr));
1518 /* 1) fork to get a child; parent remembers the child pid
1519 2) child execs the command requested
1520 3) parent waits for child; checks for proper pid of child
1522 Possible returns:
1524 ret errno status(h) status(l)
1526 pid x signal# 0177 stopped
1527 pid x exit arg 0 term by _exit
1528 pid x 0 signal # term by signal
1529 -1 EINTR parent got signal
1530 -1 other some other kind of error
1532 Return true only if the pid matches, status(l) is
1533 zero, and the exit arg (status high) is 0.
1534 Otherwise return false, possibly printing an error message. */
1537 static void
1538 prep_child_for_exec (boolean close_stdin)
1540 if (close_stdin)
1542 const char inputfile[] = "/dev/null";
1543 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1545 close(0);
1546 if (open(inputfile, O_RDONLY) < 0)
1548 /* This is not entirely fatal, since
1549 * executing the child with a closed
1550 * stdin is almost as good as executing it
1551 * with its stdin attached to /dev/null.
1553 error (0, errno, "%s", inputfile);
1561 launch (const struct buildcmd_control *ctl,
1562 struct buildcmd_state *buildstate)
1564 int wait_status;
1565 pid_t child_pid;
1566 static int first_time = 1;
1567 const struct exec_val *execp = buildstate->usercontext;
1569 /* Null terminate the arg list. */
1570 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false);
1572 /* Make sure output of command doesn't get mixed with find output. */
1573 fflush (stdout);
1574 fflush (stderr);
1576 /* Make sure to listen for the kids. */
1577 if (first_time)
1579 first_time = 0;
1580 signal (SIGCHLD, SIG_DFL);
1583 child_pid = fork ();
1584 if (child_pid == -1)
1585 error (1, errno, _("cannot fork"));
1586 if (child_pid == 0)
1588 /* We be the child. */
1589 prep_child_for_exec(execp->close_stdin);
1591 /* For -exec and -ok, change directory back to the starting directory.
1592 * for -execdir and -okdir, stay in the directory we are searching
1593 * (the latter is more secure).
1595 if (!execp->use_current_dir)
1597 /* Even if DEBUG_STAT is set, don't announce our change of
1598 * directory, since we're not going to emit a subsequent
1599 * announcement of a call to stat() anyway, as we're about
1600 * to exec something.
1602 if (starting_desc < 0
1603 ? chdir (starting_dir) != 0
1604 : fchdir (starting_desc) != 0)
1606 error (0, errno, "%s", starting_dir);
1607 _exit (1);
1611 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv);
1612 error (0, errno, "%s", buildstate->cmd_argv[0]);
1613 _exit (1);
1617 /* In parent; set up for next time. */
1618 bc_clear_args(ctl, buildstate);
1621 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1)
1623 if (errno != EINTR)
1625 error (0, errno, _("error waiting for %s"), buildstate->cmd_argv[0]);
1626 state.exit_status = 1;
1627 return 0; /* FAIL */
1631 if (WIFSIGNALED (wait_status))
1633 error (0, 0, _("%s terminated by signal %d"),
1634 buildstate->cmd_argv[0], WTERMSIG (wait_status));
1636 if (execp->multiple)
1638 /* -exec \; just returns false if the invoked command fails.
1639 * -exec {} + returns true if the invoked command fails, but
1640 * sets the program exit status.
1642 state.exit_status = 1;
1645 return 1; /* OK */
1648 if (0 == WEXITSTATUS (wait_status))
1650 return 1; /* OK */
1652 else
1654 if (execp->multiple)
1656 /* -exec \; just returns false if the invoked command fails.
1657 * -exec {} + returns true if the invoked command fails, but
1658 * sets the program exit status.
1660 state.exit_status = 1;
1662 return 0; /* FAIL */
1668 /* Return a static string formatting the time WHEN according to the
1669 strftime format character KIND. */
1671 static char *
1672 format_date (time_t when, int kind)
1674 static char buf[MAX (LONGEST_HUMAN_READABLE + 2, 64)];
1675 struct tm *tm;
1676 char fmt[6];
1678 fmt[0] = '%';
1679 fmt[1] = kind;
1680 fmt[2] = '\0';
1681 if (kind == '+')
1682 strcpy (fmt, "%F+%T");
1684 if (kind != '@'
1685 && (tm = localtime (&when))
1686 && strftime (buf, sizeof buf, fmt, tm))
1687 return buf;
1688 else
1690 uintmax_t w = when;
1691 char *p = human_readable (when < 0 ? -w : w, buf + 1,
1692 human_ceiling, 1, 1);
1693 if (when < 0)
1694 *--p = '-';
1695 return p;
1699 static char *
1700 ctime_format (time_t when)
1702 char *r = ctime (&when);
1703 if (!r)
1705 /* The time cannot be represented as a struct tm.
1706 Output it as an integer. */
1707 return format_date (when, '@');
1709 else
1711 /* Remove the trailing newline from the ctime output,
1712 being careful not to assume that the output is fixed-width. */
1713 *strchr (r, '\n') = '\0';
1714 return r;
1718 #ifdef DEBUG
1719 /* Return a pointer to the string representation of
1720 the predicate function PRED_FUNC. */
1722 char *
1723 find_pred_name (PRED_FUNC func)
1725 int i;
1727 for (i = 0; pred_table[i].pred_func != 0; i++)
1728 if (pred_table[i].pred_func == func)
1729 break;
1730 return pred_table[i].pred_name;
1733 static char *
1734 type_name (type)
1735 short type;
1737 int i;
1739 for (i = 0; type_table[i].type != (short) -1; i++)
1740 if (type_table[i].type == type)
1741 break;
1742 return (type_table[i].type_name);
1745 static char *
1746 prec_name (prec)
1747 short prec;
1749 int i;
1751 for (i = 0; prec_table[i].prec != (short) -1; i++)
1752 if (prec_table[i].prec == prec)
1753 break;
1754 return (prec_table[i].prec_name);
1757 /* Walk the expression tree NODE to stdout.
1758 INDENT is the number of levels to indent the left margin. */
1760 void
1761 print_tree (FILE *fp, struct predicate *node, int indent)
1763 int i;
1765 if (node == NULL)
1766 return;
1767 for (i = 0; i < indent; i++)
1768 fprintf (fp, " ");
1769 fprintf (fp, "pred = %s type = %s prec = %s addr = %p\n",
1770 find_pred_name (node->pred_func),
1771 type_name (node->p_type), prec_name (node->p_prec), node);
1772 if (node->need_stat || node->need_type)
1774 int comma = 0;
1776 for (i = 0; i < indent; i++)
1777 fprintf (fp, " ");
1779 fprintf (fp, "Needs ");
1780 if (node->need_stat)
1782 fprintf (fp, "stat");
1783 comma = 1;
1785 if (node->need_type)
1787 fprintf (fp, "%stype", comma ? "," : "");
1789 fprintf (fp, "\n");
1792 for (i = 0; i < indent; i++)
1793 fprintf (fp, " ");
1794 fprintf (fp, "left:\n");
1795 print_tree (fp, node->pred_left, indent + 1);
1796 for (i = 0; i < indent; i++)
1797 fprintf (fp, " ");
1798 fprintf (fp, "right:\n");
1799 print_tree (fp, node->pred_right, indent + 1);
1802 /* Copy STR into BUF and trim blanks from the end of BUF.
1803 Return BUF. */
1805 static char *
1806 blank_rtrim (str, buf)
1807 char *str;
1808 char *buf;
1810 int i;
1812 if (str == NULL)
1813 return (NULL);
1814 strcpy (buf, str);
1815 i = strlen (buf) - 1;
1816 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
1817 i--;
1818 buf[++i] = '\0';
1819 return (buf);
1822 /* Print out the predicate list starting at NODE. */
1824 void
1825 print_list (FILE *fp, struct predicate *node)
1827 struct predicate *cur;
1828 char name[256];
1830 cur = node;
1831 while (cur != NULL)
1833 fprintf (fp, "%s ", blank_rtrim (find_pred_name (cur->pred_func), name));
1834 cur = cur->pred_next;
1836 fprintf (fp, "\n");
1840 /* Print out the predicate list starting at NODE. */
1843 static void
1844 print_parenthesised(FILE *fp, struct predicate *node)
1846 int parens = 0;
1848 if (node)
1850 if ( ( (node->pred_func == pred_or)
1851 || (node->pred_func == pred_and) )
1852 && node->pred_left == NULL)
1854 /* We print "<nothing> or X" as just "X"
1855 * We print "<nothing> and X" as just "X"
1857 print_parenthesised(fp, node->pred_right);
1859 else
1861 if (node->pred_left || node->pred_right)
1862 parens = 1;
1864 if (parens)
1865 fprintf(fp, "%s", " ( ");
1866 print_optlist(fp, node);
1867 if (parens)
1868 fprintf(fp, "%s", " ) ");
1873 void
1874 print_optlist (FILE *fp, struct predicate *p)
1876 char name[256];
1878 if (p)
1880 print_parenthesised(fp, p->pred_left);
1881 fprintf (fp,
1882 "%s%s%s ",
1883 p->need_stat ? "[stat called here] " : "",
1884 p->need_type ? "[type needed here] " : "",
1885 blank_rtrim (find_pred_name (p->pred_func), name));
1886 print_parenthesised(fp, p->pred_right);
1890 #endif /* DEBUG */
1893 void
1894 pred_sanity_check(const struct predicate *predicates)
1896 const struct predicate *p;
1898 for (p=predicates; p != NULL; p=p->pred_next)
1900 /* All predicates must do something. */
1901 assert(p->pred_func != NULL);
1903 /* All predicates must have a parser table entry. */
1904 assert(p->parser_entry != NULL);
1906 /* If the parser table tells us that just one predicate function is
1907 * possible, verify that that is still the one that is in effect.
1908 * If the parser has NULL for the predicate function, that means that
1909 * the parse_xxx function fills it in, so we can't check it.
1911 if (p->parser_entry->pred_func)
1913 assert(p->parser_entry->pred_func == p->pred_func);
1916 switch (p->parser_entry->type)
1918 /* Options all take effect during parsing, so there should
1919 * be no predicate entries corresponding to them. Hence we
1920 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
1921 * items.
1923 * This is a silly way of coding this test, but it prevents
1924 * a compiler warning (i.e. otherwise it would think that
1925 * there would be case statements missing).
1927 case ARG_OPTION:
1928 case ARG_POSITIONAL_OPTION:
1929 assert(p->parser_entry->type != ARG_OPTION);
1930 assert(p->parser_entry->type != ARG_POSITIONAL_OPTION);
1931 break;
1933 case ARG_ACTION:
1934 assert(p->side_effects); /* actions have side effects. */
1935 if (p->pred_func != pred_prune && p->pred_func != pred_quit)
1937 /* actions other than -prune and -quit should
1938 * inhibit the default -print
1940 assert(p->no_default_print);
1942 break;
1944 case ARG_PUNCTUATION:
1945 case ARG_TEST:
1946 /* Punctuation and tests should have no side
1947 * effects and not inhibit default print.
1949 assert(!p->no_default_print);
1950 assert(!p->side_effects);
1951 break;