* find/pred.c (pred_timewindow): Avoid gcc warnings.
[findutils.git] / find / pred.c
blob2fe7400b9e76c1130217d90cea82e78a409cce5c
1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
3 2004, 2005, 2006, 2007 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 <config.h>
22 #include "defs.h"
24 #include <fnmatch.h>
25 #include <signal.h>
26 #include <math.h>
27 #include <pwd.h>
28 #include <grp.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <assert.h>
33 #include <stdarg.h>
34 #include <fcntl.h>
35 #include <locale.h>
36 #include <openat.h>
37 #include "xalloc.h"
38 #include "dirname.h"
39 #include "human.h"
40 #include "modetype.h"
41 #include "filemode.h"
42 #include "wait.h"
43 #include "printquoted.h"
44 #include "buildcmd.h"
45 #include "yesno.h"
46 #include "listfile.h"
47 #include "stat-time.h"
48 #include "dircallback.h"
49 #include "error.h"
50 #include "verify.h"
52 #if ENABLE_NLS
53 # include <libintl.h>
54 # define _(Text) gettext (Text)
55 #else
56 # define _(Text) Text
57 #endif
58 #ifdef gettext_noop
59 # define N_(String) gettext_noop (String)
60 #else
61 /* See locate.c for explanation as to why not use (String) */
62 # define N_(String) String
63 #endif
65 #if !defined(SIGCHLD) && defined(SIGCLD)
66 #define SIGCHLD SIGCLD
67 #endif
71 #if HAVE_DIRENT_H
72 # include <dirent.h>
73 # define NAMLEN(dirent) strlen((dirent)->d_name)
74 #else
75 # define dirent direct
76 # define NAMLEN(dirent) (dirent)->d_namlen
77 # if HAVE_SYS_NDIR_H
78 # include <sys/ndir.h>
79 # endif
80 # if HAVE_SYS_DIR_H
81 # include <sys/dir.h>
82 # endif
83 # if HAVE_NDIR_H
84 # include <ndir.h>
85 # endif
86 #endif
88 #ifdef CLOSEDIR_VOID
89 /* Fake a return value. */
90 #define CLOSEDIR(d) (closedir (d), 0)
91 #else
92 #define CLOSEDIR(d) closedir (d)
93 #endif
98 /* Get or fake the disk device blocksize.
99 Usually defined by sys/param.h (if at all). */
100 #ifndef DEV_BSIZE
101 # ifdef BSIZE
102 # define DEV_BSIZE BSIZE
103 # else /* !BSIZE */
104 # define DEV_BSIZE 4096
105 # endif /* !BSIZE */
106 #endif /* !DEV_BSIZE */
108 /* Extract or fake data from a `struct stat'.
109 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
110 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
111 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
112 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
113 # define ST_BLKSIZE(statbuf) DEV_BSIZE
114 # if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
115 # define ST_NBLOCKS(statbuf) \
116 (S_ISREG ((statbuf).st_mode) \
117 || S_ISDIR ((statbuf).st_mode) \
118 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
119 # else /* !_POSIX_SOURCE && BSIZE */
120 # define ST_NBLOCKS(statbuf) \
121 (S_ISREG ((statbuf).st_mode) \
122 || S_ISDIR ((statbuf).st_mode) \
123 ? st_blocks ((statbuf).st_size) : 0)
124 # endif /* !_POSIX_SOURCE && BSIZE */
125 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
126 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
127 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
128 ? (statbuf).st_blksize : DEV_BSIZE)
129 # if defined hpux || defined __hpux__ || defined __hpux
130 /* HP-UX counts st_blocks in 1024-byte units.
131 This loses when mixing HP-UX and BSD file systems with NFS. */
132 # define ST_NBLOCKSIZE 1024
133 # else /* !hpux */
134 # if defined _AIX && defined _I386
135 /* AIX PS/2 counts st_blocks in 4K units. */
136 # define ST_NBLOCKSIZE (4 * 1024)
137 # else /* not AIX PS/2 */
138 # if defined _CRAY
139 # define ST_NBLOCKS(statbuf) \
140 (S_ISREG ((statbuf).st_mode) \
141 || S_ISDIR ((statbuf).st_mode) \
142 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
143 # endif /* _CRAY */
144 # endif /* not AIX PS/2 */
145 # endif /* !hpux */
146 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
148 #ifndef ST_NBLOCKS
149 # define ST_NBLOCKS(statbuf) \
150 (S_ISREG ((statbuf).st_mode) \
151 || S_ISDIR ((statbuf).st_mode) \
152 ? (statbuf).st_blocks : 0)
153 #endif
155 #ifndef ST_NBLOCKSIZE
156 # define ST_NBLOCKSIZE 512
157 #endif
160 #undef MAX
161 #define MAX(a, b) ((a) > (b) ? (a) : (b))
163 static boolean match_lname PARAMS((const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case));
165 static char *format_date PARAMS((struct timespec ts, int kind));
166 static char *ctime_format PARAMS((struct timespec ts));
168 #ifdef DEBUG
169 struct pred_assoc
171 PRED_FUNC pred_func;
172 char *pred_name;
175 struct pred_assoc pred_table[] =
177 {pred_amin, "amin "},
178 {pred_and, "and "},
179 {pred_anewer, "anewer "},
180 {pred_atime, "atime "},
181 {pred_closeparen, ") "},
182 {pred_cmin, "cmin "},
183 {pred_cnewer, "cnewer "},
184 {pred_comma, ", "},
185 {pred_ctime, "ctime "},
186 {pred_delete, "delete "},
187 {pred_empty, "empty "},
188 {pred_exec, "exec "},
189 {pred_execdir, "execdir "},
190 {pred_executable, "executable "},
191 {pred_false, "false "},
192 {pred_fprint, "fprint "},
193 {pred_fprint0, "fprint0 "},
194 {pred_fprintf, "fprintf "},
195 {pred_fstype, "fstype "},
196 {pred_gid, "gid "},
197 {pred_group, "group "},
198 {pred_ilname, "ilname "},
199 {pred_iname, "iname "},
200 {pred_inum, "inum "},
201 {pred_ipath, "ipath "},
202 {pred_links, "links "},
203 {pred_lname, "lname "},
204 {pred_ls, "ls "},
205 {pred_mmin, "mmin "},
206 {pred_mtime, "mtime "},
207 {pred_name, "name "},
208 {pred_negate, "not "},
209 {pred_newer, "newer "},
210 {pred_newerXY, "newerXY "},
211 {pred_nogroup, "nogroup "},
212 {pred_nouser, "nouser "},
213 {pred_ok, "ok "},
214 {pred_okdir, "okdir "},
215 {pred_openparen, "( "},
216 {pred_or, "or "},
217 {pred_path, "path "},
218 {pred_perm, "perm "},
219 {pred_print, "print "},
220 {pred_print0, "print0 "},
221 {pred_prune, "prune "},
222 {pred_quit, "quit "},
223 {pred_readable, "readable "},
224 {pred_regex, "regex "},
225 {pred_samefile,"samefile "},
226 {pred_size, "size "},
227 {pred_true, "true "},
228 {pred_type, "type "},
229 {pred_uid, "uid "},
230 {pred_used, "used "},
231 {pred_user, "user "},
232 {pred_writable, "writable "},
233 {pred_xtype, "xtype "},
234 {0, "none "}
236 #endif
238 /* Returns ts1 - ts2 */
239 static double ts_difference(struct timespec ts1,
240 struct timespec ts2)
242 double d = difftime(ts1.tv_sec, ts2.tv_sec)
243 + (1.0e-9 * (ts1.tv_nsec - ts2.tv_nsec));
244 return d;
248 static int
249 compare_ts(struct timespec ts1,
250 struct timespec ts2)
252 if ((ts1.tv_sec == ts2.tv_sec) &&
253 (ts1.tv_nsec == ts2.tv_nsec))
255 return 0;
257 else
259 double diff = ts_difference(ts1, ts2);
260 return diff < 0.0 ? -1 : +1;
264 /* Predicate processing routines.
266 PATHNAME is the full pathname of the file being checked.
267 *STAT_BUF contains information about PATHNAME.
268 *PRED_PTR contains information for applying the predicate.
270 Return true if the file passes this predicate, false if not. */
273 /* pred_timewindow
275 * Returns true if THE_TIME is
276 * COMP_GT: after the specified time
277 * COMP_LT: before the specified time
278 * COMP_EQ: less than WINDOW seconds after the specified time.
280 static boolean
281 pred_timewindow(struct timespec ts, struct predicate const *pred_ptr, int window)
283 switch (pred_ptr->args.reftime.kind)
285 case COMP_GT:
286 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
288 case COMP_LT:
289 return compare_ts(ts, pred_ptr->args.reftime.ts) < 0;
291 case COMP_EQ:
293 double delta = ts_difference(ts, pred_ptr->args.reftime.ts);
294 return (delta >= 0.0 && delta < window);
297 assert (0);
298 abort ();
302 boolean
303 pred_amin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
305 (void) &pathname;
306 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, 60);
309 boolean
310 pred_and (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
312 if (pred_ptr->pred_left == NULL
313 || apply_predicate(pathname, stat_buf, pred_ptr->pred_left))
315 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
317 else
318 return false;
321 boolean
322 pred_anewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
324 (void) &pathname;
325 assert (COMP_GT == pred_ptr->args.reftime.kind);
326 return compare_ts(get_stat_atime(stat_buf), pred_ptr->args.reftime.ts) > 0;
329 boolean
330 pred_atime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
332 (void) &pathname;
333 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, DAYSECS);
336 boolean
337 pred_closeparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
339 (void) &pathname;
340 (void) &stat_buf;
341 (void) &pred_ptr;
343 return true;
346 boolean
347 pred_cmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
349 (void) pathname;
350 return pred_timewindow(get_stat_ctime(stat_buf), pred_ptr, 60);
353 boolean
354 pred_cnewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
356 (void) pathname;
358 assert (COMP_GT == pred_ptr->args.reftime.kind);
359 return compare_ts(get_stat_ctime(stat_buf), pred_ptr->args.reftime.ts) > 0;
362 boolean
363 pred_comma (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
365 if (pred_ptr->pred_left != NULL)
367 apply_predicate(pathname, stat_buf,pred_ptr->pred_left);
369 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
372 boolean
373 pred_ctime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
375 (void) &pathname;
376 return pred_timewindow(get_stat_ctime(stat_buf), pred_ptr, DAYSECS);
379 static boolean
380 perform_delete(int flags)
382 return 0 == unlinkat(state.cwd_dir_fd, state.rel_pathname, flags);
386 boolean
387 pred_delete (const 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 int flags=0;
394 if (state.have_stat && S_ISDIR(stat_buf->st_mode))
395 flags |= AT_REMOVEDIR;
396 if (perform_delete(flags))
398 return true;
400 else
402 if (EISDIR == errno)
404 if ((flags & AT_REMOVEDIR) == 0)
406 /* unlink() operation failed because we should have done rmdir(). */
407 flags |= AT_REMOVEDIR;
408 if (perform_delete(flags))
409 return true;
413 error (0, errno, _("cannot delete %s"),
414 safely_quote_err_filename(0, pathname));
415 return false;
417 else
419 /* nothing to do. */
420 return true;
424 boolean
425 pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
427 (void) pathname;
428 (void) pred_ptr;
430 if (S_ISDIR (stat_buf->st_mode))
432 int fd;
433 DIR *d;
434 struct dirent *dp;
435 boolean empty = true;
437 errno = 0;
438 if ((fd = openat(state.cwd_dir_fd, state.rel_pathname, O_RDONLY
439 #if defined O_LARGEFILE
440 |O_LARGEFILE
441 #endif
442 )) < 0)
444 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
445 state.exit_status = 1;
446 return false;
448 d = fdopendir (fd);
449 if (d == NULL)
451 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
452 state.exit_status = 1;
453 return false;
455 for (dp = readdir (d); dp; dp = readdir (d))
457 if (dp->d_name[0] != '.'
458 || (dp->d_name[1] != '\0'
459 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
461 empty = false;
462 break;
465 if (CLOSEDIR (d))
467 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
468 state.exit_status = 1;
469 return false;
471 return (empty);
473 else if (S_ISREG (stat_buf->st_mode))
474 return (stat_buf->st_size == 0);
475 else
476 return (false);
479 static boolean
480 new_impl_pred_exec (int dirfd, const char *pathname,
481 struct stat *stat_buf,
482 struct predicate *pred_ptr,
483 const char *prefix, size_t pfxlen)
485 struct exec_val *execp = &pred_ptr->args.exec_vec;
486 size_t len = strlen(pathname);
488 (void) stat_buf;
489 execp->dirfd = dirfd;
490 if (execp->multiple)
492 /* Push the argument onto the current list.
493 * The command may or may not be run at this point,
494 * depending on the command line length limits.
496 bc_push_arg(&execp->ctl,
497 &execp->state,
498 pathname, len+1,
499 prefix, pfxlen,
502 /* remember that there are pending execdirs. */
503 state.execdirs_outstanding = true;
505 /* POSIX: If the primary expression is punctuated by a plus
506 * sign, the primary shall always evaluate as true
508 return true;
510 else
512 int i;
514 for (i=0; i<execp->num_args; ++i)
516 bc_do_insert(&execp->ctl,
517 &execp->state,
518 execp->replace_vec[i],
519 strlen(execp->replace_vec[i]),
520 prefix, pfxlen,
521 pathname, len,
525 /* Actually invoke the command. */
526 return execp->ctl.exec_callback(&execp->ctl,
527 &execp->state);
532 boolean
533 pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
535 return new_impl_pred_exec(get_start_dirfd(),
536 pathname, stat_buf, pred_ptr, NULL, 0);
539 boolean
540 pred_execdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
542 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
543 (void) &pathname;
544 return new_impl_pred_exec (get_current_dirfd(),
545 state.rel_pathname, stat_buf, pred_ptr,
546 prefix, (prefix ? 2 : 0));
549 boolean
550 pred_false (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
552 (void) &pathname;
553 (void) &stat_buf;
554 (void) &pred_ptr;
557 return (false);
560 boolean
561 pred_fls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
563 FILE * stream = pred_ptr->args.printf_vec.stream;
564 list_file (pathname, state.cwd_dir_fd, state.rel_pathname, stat_buf,
565 options.start_time.tv_sec,
566 options.output_block_size,
567 pred_ptr->literal_control_chars, stream);
568 return true;
571 boolean
572 pred_fprint (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
574 (void) &pathname;
575 (void) &stat_buf;
577 print_quoted(pred_ptr->args.printf_vec.stream,
578 pred_ptr->args.printf_vec.quote_opts,
579 pred_ptr->args.printf_vec.dest_is_tty,
580 "%s\n",
581 pathname);
582 return true;
585 boolean
586 pred_fprint0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
588 FILE * fp = pred_ptr->args.printf_vec.stream;
590 (void) &stat_buf;
592 fputs (pathname, fp);
593 putc (0, fp);
594 return true;
599 static char*
600 mode_to_filetype(mode_t m)
602 #define HANDLE_TYPE(t,letter) if (m==t) { return letter; }
603 #ifdef S_IFREG
604 HANDLE_TYPE(S_IFREG, "f"); /* regular file */
605 #endif
606 #ifdef S_IFDIR
607 HANDLE_TYPE(S_IFDIR, "d"); /* directory */
608 #endif
609 #ifdef S_IFLNK
610 HANDLE_TYPE(S_IFLNK, "l"); /* symbolic link */
611 #endif
612 #ifdef S_IFSOCK
613 HANDLE_TYPE(S_IFSOCK, "s"); /* Unix domain socket */
614 #endif
615 #ifdef S_IFBLK
616 HANDLE_TYPE(S_IFBLK, "b"); /* block device */
617 #endif
618 #ifdef S_IFCHR
619 HANDLE_TYPE(S_IFCHR, "c"); /* character device */
620 #endif
621 #ifdef S_IFIFO
622 HANDLE_TYPE(S_IFIFO, "p"); /* FIFO */
623 #endif
624 #ifdef S_IFDOOR
625 HANDLE_TYPE(S_IFDOOR, "D"); /* Door (e.g. on Solaris) */
626 #endif
627 return "U"; /* Unknown */
630 static double
631 file_sparseness(const struct stat *p)
633 #if defined HAVE_STRUCT_STAT_ST_BLOCKS
634 if (0 == p->st_size)
636 if (0 == p->st_blocks)
637 return 1.0;
638 else
639 return p->st_blocks < 0 ? -HUGE_VAL : HUGE_VAL;
641 else
643 double blklen = file_blocksize(p) * (double)p->st_blocks;
644 return blklen / p->st_size;
646 #else
647 return 1.0;
648 #endif
653 static void
654 checked_fprintf(struct format_val *dest, const char *fmt, ...)
656 int rv;
657 va_list ap;
659 va_start(ap, fmt);
660 rv = vfprintf(dest->stream, fmt, ap);
661 if (rv < 0)
662 nonfatal_file_error(dest->filename);
666 static void
667 checked_print_quoted (struct format_val *dest,
668 const char *format, const char *s)
670 int rv = print_quoted(dest->stream, dest->quote_opts, dest->dest_is_tty,
671 format, s);
672 if (rv < 0)
673 nonfatal_file_error(dest->filename);
677 static void
678 checked_fwrite(void *p, size_t siz, size_t nmemb, struct format_val *dest)
680 int items_written = fwrite(p, siz, nmemb, dest->stream);
681 if (items_written < nmemb)
682 nonfatal_file_error(dest->filename);
685 static void
686 checked_fflush(struct format_val *dest)
688 if (0 != fflush(dest->stream))
690 nonfatal_file_error(dest->filename);
694 static void
695 do_fprintf(struct format_val *dest,
696 struct segment *segment,
697 const char *pathname,
698 const struct stat *stat_buf)
700 char hbuf[LONGEST_HUMAN_READABLE + 1];
701 const char *cp;
703 switch (segment->segkind)
705 case KIND_PLAIN: /* Plain text string (no % conversion). */
706 /* trusted */
707 checked_fwrite(segment->text, 1, segment->text_len, dest);
708 break;
710 case KIND_STOP: /* Terminate argument and flush output. */
711 /* trusted */
712 checked_fwrite(segment->text, 1, segment->text_len, dest);
713 checked_fflush(dest);
714 break;
716 case KIND_FORMAT:
717 switch (segment->format_char[0])
719 case 'a': /* atime in `ctime' format. */
720 /* UNTRUSTED, probably unexploitable */
721 checked_fprintf (dest, segment->text, ctime_format (get_stat_atime(stat_buf)));
722 break;
723 case 'b': /* size in 512-byte blocks */
724 /* UNTRUSTED, probably unexploitable */
725 checked_fprintf (dest, segment->text,
726 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
727 hbuf, human_ceiling,
728 ST_NBLOCKSIZE, 512));
729 break;
730 case 'c': /* ctime in `ctime' format */
731 /* UNTRUSTED, probably unexploitable */
732 checked_fprintf (dest, segment->text, ctime_format (get_stat_ctime(stat_buf)));
733 break;
734 case 'd': /* depth in search tree */
735 /* UNTRUSTED, probably unexploitable */
736 checked_fprintf (dest, segment->text, state.curdepth);
737 break;
738 case 'D': /* Device on which file exists (stat.st_dev) */
739 /* trusted */
740 checked_fprintf (dest, segment->text,
741 human_readable ((uintmax_t) stat_buf->st_dev, hbuf,
742 human_ceiling, 1, 1));
743 break;
744 case 'f': /* base name of path */
745 /* sanitised */
746 checked_print_quoted (dest, segment->text, base_name (pathname));
747 break;
748 case 'F': /* file system type */
749 /* trusted */
750 checked_print_quoted (dest, segment->text, filesystem_type (stat_buf, pathname));
751 break;
752 case 'g': /* group name */
753 /* trusted */
754 /* (well, the actual group is selected by the user but
755 * its name was selected by the system administrator)
758 struct group *g;
760 g = getgrgid (stat_buf->st_gid);
761 if (g)
763 segment->text[segment->text_len] = 's';
764 checked_fprintf (dest, segment->text, g->gr_name);
765 break;
767 else
769 /* Do nothing. */
770 /*FALLTHROUGH*/
773 /*FALLTHROUGH*/ /*...sometimes, so 'G' case.*/
775 case 'G': /* GID number */
776 /* UNTRUSTED, probably unexploitable */
777 checked_fprintf (dest, segment->text,
778 human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
779 human_ceiling, 1, 1));
780 break;
781 case 'h': /* leading directories part of path */
782 /* sanitised */
784 cp = strrchr (pathname, '/');
785 if (cp == NULL) /* No leading directories. */
787 /* If there is no slash in the pathname, we still
788 * print the string because it contains characters
789 * other than just '%s'. The %h expands to ".".
791 checked_print_quoted (dest, segment->text, ".");
793 else
795 char *s = strdup(pathname);
796 s[cp - pathname] = 0;
797 checked_print_quoted (dest, segment->text, s);
798 free(s);
801 break;
803 case 'H': /* ARGV element file was found under */
804 /* trusted */
806 char *s = xmalloc(state.starting_path_length+1);
807 memcpy(s, pathname, state.starting_path_length);
808 s[state.starting_path_length] = 0;
809 checked_fprintf (dest, segment->text, s);
810 free(s);
812 break;
814 case 'i': /* inode number */
815 /* UNTRUSTED, but not exploitable I think */
816 checked_fprintf (dest, segment->text,
817 human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
818 human_ceiling,
819 1, 1));
820 break;
821 case 'k': /* size in 1K blocks */
822 /* UNTRUSTED, but not exploitable I think */
823 checked_fprintf (dest, segment->text,
824 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
825 hbuf, human_ceiling,
826 ST_NBLOCKSIZE, 1024));
827 break;
828 case 'l': /* object of symlink */
829 /* sanitised */
830 #ifdef S_ISLNK
832 char *linkname = 0;
834 if (S_ISLNK (stat_buf->st_mode))
836 linkname = get_link_name_at (pathname, state.cwd_dir_fd, state.rel_pathname);
837 if (linkname == 0)
838 state.exit_status = 1;
840 if (linkname)
842 checked_print_quoted (dest, segment->text, linkname);
843 free (linkname);
845 else
847 /* We still need to honour the field width etc., so this is
848 * not a no-op.
850 checked_print_quoted (dest, segment->text, "");
853 #endif /* S_ISLNK */
854 break;
856 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
857 /* UNTRUSTED, probably unexploitable */
859 char modestring[16] ;
860 filemodestring (stat_buf, modestring);
861 modestring[10] = '\0';
862 checked_fprintf (dest, segment->text, modestring);
864 break;
866 case 'm': /* mode as octal number (perms only) */
867 /* UNTRUSTED, probably unexploitable */
869 /* Output the mode portably using the traditional numbers,
870 even if the host unwisely uses some other numbering
871 scheme. But help the compiler in the common case where
872 the host uses the traditional numbering scheme. */
873 mode_t m = stat_buf->st_mode;
874 boolean traditional_numbering_scheme =
875 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
876 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
877 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
878 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
879 checked_fprintf (dest, segment->text,
880 (traditional_numbering_scheme
881 ? m & MODE_ALL
882 : ((m & S_ISUID ? 04000 : 0)
883 | (m & S_ISGID ? 02000 : 0)
884 | (m & S_ISVTX ? 01000 : 0)
885 | (m & S_IRUSR ? 00400 : 0)
886 | (m & S_IWUSR ? 00200 : 0)
887 | (m & S_IXUSR ? 00100 : 0)
888 | (m & S_IRGRP ? 00040 : 0)
889 | (m & S_IWGRP ? 00020 : 0)
890 | (m & S_IXGRP ? 00010 : 0)
891 | (m & S_IROTH ? 00004 : 0)
892 | (m & S_IWOTH ? 00002 : 0)
893 | (m & S_IXOTH ? 00001 : 0))));
895 break;
897 case 'n': /* number of links */
898 /* UNTRUSTED, probably unexploitable */
899 checked_fprintf (dest, segment->text,
900 human_readable ((uintmax_t) stat_buf->st_nlink,
901 hbuf,
902 human_ceiling,
903 1, 1));
904 break;
906 case 'p': /* pathname */
907 /* sanitised */
908 checked_print_quoted (dest, segment->text, pathname);
909 break;
911 case 'P': /* pathname with ARGV element stripped */
912 /* sanitised */
913 if (state.curdepth > 0)
915 cp = pathname + state.starting_path_length;
916 if (*cp == '/')
917 /* Move past the slash between the ARGV element
918 and the rest of the pathname. But if the ARGV element
919 ends in a slash, we didn't add another, so we've
920 already skipped past it. */
921 cp++;
923 else
925 cp = "";
927 checked_print_quoted (dest, segment->text, cp);
928 break;
930 case 's': /* size in bytes */
931 /* UNTRUSTED, probably unexploitable */
932 checked_fprintf (dest, segment->text,
933 human_readable ((uintmax_t) stat_buf->st_size,
934 hbuf, human_ceiling, 1, 1));
935 break;
937 case 'S': /* sparseness */
938 /* UNTRUSTED, probably unexploitable */
939 checked_fprintf (dest, segment->text, file_sparseness(stat_buf));;
940 break;
942 case 't': /* mtime in `ctime' format */
943 /* UNTRUSTED, probably unexploitable */
944 checked_fprintf (dest, segment->text,
945 ctime_format (get_stat_mtime(stat_buf)));
946 break;
948 case 'u': /* user name */
949 /* trusted */
950 /* (well, the actual user is selected by the user on systems
951 * where chown is not restricted, but the user name was
952 * selected by the system administrator)
955 struct passwd *p;
957 p = getpwuid (stat_buf->st_uid);
958 if (p)
960 segment->text[segment->text_len] = 's';
961 checked_fprintf (dest, segment->text, p->pw_name);
962 break;
964 /* else fallthru */
966 /* FALLTHROUGH*/ /* .. to case U */
968 case 'U': /* UID number */
969 /* UNTRUSTED, probably unexploitable */
970 checked_fprintf (dest, segment->text,
971 human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
972 human_ceiling, 1, 1));
973 break;
975 /* %Y: type of file system entry like `ls -l`:
976 * (d,-,l,s,p,b,c,n) n=nonexistent(symlink)
978 case 'Y': /* in case of symlink */
979 /* trusted */
981 #ifdef S_ISLNK
982 if (S_ISLNK (stat_buf->st_mode))
984 struct stat sbuf;
985 /* If we would normally follow links, do not do so.
986 * If we would normally not follow links, do so.
988 if ((following_links() ? lstat : stat)
989 (state.rel_pathname, &sbuf) != 0)
991 if ( errno == ENOENT )
993 checked_fprintf (dest, segment->text, "N");
994 break;
996 else if ( errno == ELOOP )
998 checked_fprintf (dest, segment->text, "L");
999 break;
1001 else
1003 checked_fprintf (dest, segment->text, "?");
1004 error (0, errno, "%s",
1005 safely_quote_err_filename(0, pathname));
1006 /* exit_status = 1;
1007 return ; */
1008 break;
1011 checked_fprintf (dest, segment->text,
1012 mode_to_filetype(sbuf.st_mode & S_IFMT));
1014 #endif /* S_ISLNK */
1015 else
1017 checked_fprintf (dest, segment->text,
1018 mode_to_filetype(stat_buf->st_mode & S_IFMT));
1021 break;
1023 case 'y':
1024 /* trusted */
1026 checked_fprintf (dest, segment->text,
1027 mode_to_filetype(stat_buf->st_mode & S_IFMT));
1029 break;
1031 /* end of KIND_FORMAT case */
1032 break;
1036 boolean
1037 pred_fprintf (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1039 struct format_val *dest = &pred_ptr->args.printf_vec;
1040 struct segment *segment;
1042 for (segment = dest->segment; segment; segment = segment->next)
1044 if ( (KIND_FORMAT == segment->segkind) && segment->format_char[1]) /* Component of date. */
1046 struct timespec ts;
1047 int valid = 0;
1049 switch (segment->format_char[0])
1051 case 'A':
1052 ts = get_stat_atime(stat_buf);
1053 valid = 1;
1054 break;
1055 case 'B':
1056 ts = get_stat_birthtime(stat_buf);
1057 if ('@' == segment->format_char[1])
1058 valid = 1;
1059 else
1060 valid = (ts.tv_nsec >= 0);
1061 break;
1062 case 'C':
1063 ts = get_stat_ctime(stat_buf);
1064 valid = 1;
1065 break;
1066 case 'T':
1067 ts = get_stat_mtime(stat_buf);
1068 valid = 1;
1069 break;
1070 default:
1071 assert (0);
1072 abort ();
1074 /* We trust the output of format_date not to contain
1075 * nasty characters, though the value of the date
1076 * is itself untrusted data.
1078 if (valid)
1080 /* trusted */
1081 checked_fprintf (dest, segment->text,
1082 format_date (ts, segment->format_char[1]));
1084 else
1086 /* The specified timestamp is not available, output
1087 * nothing for the timestamp, but use the rest (so that
1088 * for example find foo -printf '[%Bs] %p\n' can print
1089 * "[] foo").
1091 /* trusted */
1092 checked_fprintf (dest, segment->text, "");
1095 else
1097 /* Print a segment which is not a date. */
1098 do_fprintf(dest, segment, pathname, stat_buf);
1101 return true;
1104 boolean
1105 pred_fstype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1107 (void) pathname;
1109 if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0)
1110 return true;
1111 else
1112 return false;
1115 boolean
1116 pred_gid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1118 (void) pathname;
1120 switch (pred_ptr->args.numinfo.kind)
1122 case COMP_GT:
1123 if (stat_buf->st_gid > pred_ptr->args.numinfo.l_val)
1124 return (true);
1125 break;
1126 case COMP_LT:
1127 if (stat_buf->st_gid < pred_ptr->args.numinfo.l_val)
1128 return (true);
1129 break;
1130 case COMP_EQ:
1131 if (stat_buf->st_gid == pred_ptr->args.numinfo.l_val)
1132 return (true);
1133 break;
1135 return (false);
1138 boolean
1139 pred_group (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1141 (void) pathname;
1143 if (pred_ptr->args.gid == stat_buf->st_gid)
1144 return (true);
1145 else
1146 return (false);
1149 boolean
1150 pred_ilname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1152 return match_lname (pathname, stat_buf, pred_ptr, true);
1155 boolean
1156 pred_iname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1158 const char *base;
1160 (void) stat_buf;
1162 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1163 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1165 base = base_name (pathname);
1166 if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0)
1167 return (true);
1168 return (false);
1171 boolean
1172 pred_inum (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1174 (void) pathname;
1176 switch (pred_ptr->args.numinfo.kind)
1178 case COMP_GT:
1179 if (stat_buf->st_ino > pred_ptr->args.numinfo.l_val)
1180 return (true);
1181 break;
1182 case COMP_LT:
1183 if (stat_buf->st_ino < pred_ptr->args.numinfo.l_val)
1184 return (true);
1185 break;
1186 case COMP_EQ:
1187 if (stat_buf->st_ino == pred_ptr->args.numinfo.l_val)
1188 return (true);
1189 break;
1191 return (false);
1194 boolean
1195 pred_ipath (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1197 (void) stat_buf;
1199 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
1200 return (true);
1201 return (false);
1204 boolean
1205 pred_links (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1207 (void) pathname;
1209 switch (pred_ptr->args.numinfo.kind)
1211 case COMP_GT:
1212 if (stat_buf->st_nlink > pred_ptr->args.numinfo.l_val)
1213 return (true);
1214 break;
1215 case COMP_LT:
1216 if (stat_buf->st_nlink < pred_ptr->args.numinfo.l_val)
1217 return (true);
1218 break;
1219 case COMP_EQ:
1220 if (stat_buf->st_nlink == pred_ptr->args.numinfo.l_val)
1221 return (true);
1222 break;
1224 return (false);
1227 boolean
1228 pred_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1230 return match_lname (pathname, stat_buf, pred_ptr, false);
1233 static boolean
1234 match_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)
1236 boolean ret = false;
1237 #ifdef S_ISLNK
1238 if (S_ISLNK (stat_buf->st_mode))
1240 char *linkname = get_link_name_at (pathname, state.cwd_dir_fd, state.rel_pathname);
1241 if (linkname)
1243 if (fnmatch (pred_ptr->args.str, linkname,
1244 ignore_case ? FNM_CASEFOLD : 0) == 0)
1245 ret = true;
1246 free (linkname);
1249 #endif /* S_ISLNK */
1250 return ret;
1253 boolean
1254 pred_ls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1256 return pred_fls(pathname, stat_buf, pred_ptr);
1259 boolean
1260 pred_mmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1262 (void) &pathname;
1263 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, 60);
1266 boolean
1267 pred_mtime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1269 (void) pathname;
1270 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, DAYSECS);
1273 boolean
1274 pred_name (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1276 const char *base;
1278 (void) stat_buf;
1279 base = base_name (pathname);
1281 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1282 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1284 if (fnmatch (pred_ptr->args.str, base, 0) == 0)
1285 return (true);
1286 return (false);
1289 boolean
1290 pred_negate (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1292 return !apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
1295 boolean
1296 pred_newer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1298 (void) pathname;
1300 assert (COMP_GT == pred_ptr->args.reftime.kind);
1301 return compare_ts(get_stat_mtime(stat_buf), pred_ptr->args.reftime.ts) > 0;
1304 boolean
1305 pred_newerXY (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1307 struct timespec ts;
1308 boolean collected = false;
1310 assert (COMP_GT == pred_ptr->args.reftime.kind);
1312 switch (pred_ptr->args.reftime.xval)
1314 case XVAL_TIME:
1315 assert (pred_ptr->args.reftime.xval != XVAL_TIME);
1316 return false;
1318 case XVAL_ATIME:
1319 ts = get_stat_atime(stat_buf);
1320 collected = true;
1321 break;
1323 case XVAL_BIRTHTIME:
1324 ts = get_stat_birthtime(stat_buf);
1325 collected = true;
1326 if (ts.tv_nsec < 0);
1328 /* XXX: Cannot determine birth time. Warn once. */
1329 error(0, 0, _("Warning: cannot determine birth time of file %s"),
1330 safely_quote_err_filename(0, pathname));
1331 return false;
1333 break;
1335 case XVAL_CTIME:
1336 ts = get_stat_ctime(stat_buf);
1337 collected = true;
1338 break;
1340 case XVAL_MTIME:
1341 ts = get_stat_mtime(stat_buf);
1342 collected = true;
1343 break;
1346 assert (collected);
1347 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
1350 boolean
1351 pred_nogroup (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1353 (void) pathname;
1354 (void) pred_ptr;
1356 #ifdef CACHE_IDS
1357 extern char *gid_unused;
1359 return gid_unused[(unsigned) stat_buf->st_gid];
1360 #else
1361 return getgrgid (stat_buf->st_gid) == NULL;
1362 #endif
1365 boolean
1366 pred_nouser (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1368 #ifdef CACHE_IDS
1369 extern char *uid_unused;
1370 #endif
1372 (void) pathname;
1373 (void) pred_ptr;
1375 #ifdef CACHE_IDS
1376 return uid_unused[(unsigned) stat_buf->st_uid];
1377 #else
1378 return getpwuid (stat_buf->st_uid) == NULL;
1379 #endif
1383 static boolean
1384 is_ok(const char *program, const char *arg)
1386 fflush (stdout);
1387 /* The draft open standard requires that, in the POSIX locale,
1388 the last non-blank character of this prompt be '?'.
1389 The exact format is not specified.
1390 This standard does not have requirements for locales other than POSIX
1392 /* XXX: printing UNTRUSTED data here. */
1393 fprintf (stderr, _("< %s ... %s > ? "), program, arg);
1394 fflush (stderr);
1395 return yesno();
1398 boolean
1399 pred_ok (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1401 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1402 return new_impl_pred_exec (get_start_dirfd(),
1403 pathname, stat_buf, pred_ptr, NULL, 0);
1404 else
1405 return false;
1408 boolean
1409 pred_okdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1411 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
1412 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1413 return new_impl_pred_exec (get_current_dirfd(),
1414 state.rel_pathname, stat_buf, pred_ptr,
1415 prefix, (prefix ? 2 : 0));
1416 else
1417 return false;
1420 boolean
1421 pred_openparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1423 (void) pathname;
1424 (void) stat_buf;
1425 (void) pred_ptr;
1426 return true;
1429 boolean
1430 pred_or (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1432 if (pred_ptr->pred_left == NULL
1433 || !apply_predicate(pathname, stat_buf, pred_ptr->pred_left))
1435 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
1437 else
1438 return true;
1441 boolean
1442 pred_path (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1444 (void) stat_buf;
1445 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
1446 return (true);
1447 return (false);
1450 boolean
1451 pred_perm (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1453 mode_t mode = stat_buf->st_mode;
1454 mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0];
1455 (void) pathname;
1456 switch (pred_ptr->args.perm.kind)
1458 case PERM_AT_LEAST:
1459 return (mode & perm_val) == perm_val;
1460 break;
1462 case PERM_ANY:
1463 /* True if any of the bits set in the mask are also set in the file's mode.
1466 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1467 * evaluate as true if at least all of the bits specified in
1468 * onum that are also set in the octal mask 07777 are set.
1470 * Eric Blake's interpretation is that the mode argument is zero,
1473 if (0 == perm_val)
1474 return true; /* Savannah bug 14748; we used to return false */
1475 else
1476 return (mode & perm_val) != 0;
1477 break;
1479 case PERM_EXACT:
1480 return (mode & MODE_ALL) == perm_val;
1481 break;
1483 default:
1484 abort ();
1485 break;
1490 struct access_check_args
1492 const char *filename;
1493 int access_type;
1494 int cb_errno;
1498 static int
1499 access_callback(void *context)
1501 int rv;
1502 struct access_check_args *args = context;
1503 if ((rv = access(args->filename, args->access_type)) < 0)
1504 args->cb_errno = errno;
1505 return rv;
1508 static int
1509 can_access(int access_type)
1511 struct access_check_args args;
1512 args.filename = state.rel_pathname;
1513 args.access_type = access_type;
1514 args.cb_errno = 0;
1515 return 0 == run_in_dir(state.cwd_dir_fd, access_callback, &args);
1519 boolean
1520 pred_executable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1522 (void) pathname;
1523 (void) stat_buf;
1524 (void) pred_ptr;
1526 return can_access(X_OK);
1529 boolean
1530 pred_readable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1532 (void) pathname;
1533 (void) stat_buf;
1534 (void) pred_ptr;
1536 return can_access(R_OK);
1539 boolean
1540 pred_writable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1542 (void) pathname;
1543 (void) stat_buf;
1544 (void) pred_ptr;
1546 return can_access(W_OK);
1549 boolean
1550 pred_print (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1552 (void) stat_buf;
1553 (void) pred_ptr;
1555 print_quoted(pred_ptr->args.printf_vec.stream,
1556 pred_ptr->args.printf_vec.quote_opts,
1557 pred_ptr->args.printf_vec.dest_is_tty,
1558 "%s\n", pathname);
1559 return true;
1562 boolean
1563 pred_print0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1565 return pred_fprint0(pathname, stat_buf, pred_ptr);
1568 boolean
1569 pred_prune (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1571 (void) pathname;
1572 (void) pred_ptr;
1574 if (options.do_dir_first == true &&
1575 stat_buf != NULL &&
1576 S_ISDIR(stat_buf->st_mode))
1577 state.stop_at_current_level = true;
1579 return (options.do_dir_first); /* This is what SunOS find seems to do. */
1582 boolean
1583 pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1585 (void) pathname;
1586 (void) stat_buf;
1587 (void) pred_ptr;
1589 /* Run any cleanups. This includes executing any command lines
1590 * we have partly built but not executed.
1592 cleanup();
1594 /* Since -exec and friends don't leave child processes running in the
1595 * background, there is no need to wait for them here.
1597 exit(state.exit_status); /* 0 for success, etc. */
1600 boolean
1601 pred_regex (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1603 int len = strlen (pathname);
1604 (void) stat_buf;
1605 if (re_match (pred_ptr->args.regex, pathname, len, 0,
1606 (struct re_registers *) NULL) == len)
1607 return (true);
1608 return (false);
1611 boolean
1612 pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1614 uintmax_t f_val;
1616 (void) pathname;
1617 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
1618 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
1619 switch (pred_ptr->args.size.kind)
1621 case COMP_GT:
1622 if (f_val > pred_ptr->args.size.size)
1623 return (true);
1624 break;
1625 case COMP_LT:
1626 if (f_val < pred_ptr->args.size.size)
1627 return (true);
1628 break;
1629 case COMP_EQ:
1630 if (f_val == pred_ptr->args.size.size)
1631 return (true);
1632 break;
1634 return (false);
1637 boolean
1638 pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1640 /* Potential optimisation: because of the loop protection, we always
1641 * know the device of the current directory, hence the device number
1642 * of the file we're currently considering. If -L is not in effect,
1643 * and the device number of the file we're looking for is not the
1644 * same as the device number of the current directory, this
1645 * predicate cannot return true. Hence there would be no need to
1646 * stat the file we're looking at.
1648 (void) pathname;
1650 /* We will often still have an fd open on the file under consideration,
1651 * but that's just to ensure inode number stability by maintaining
1652 * a reference to it; we don't need the file for anything else.
1654 return stat_buf->st_ino == pred_ptr->args.samefileid.ino
1655 && stat_buf->st_dev == pred_ptr->args.samefileid.dev;
1658 boolean
1659 pred_true (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1661 (void) pathname;
1662 (void) stat_buf;
1663 (void) pred_ptr;
1664 return true;
1667 boolean
1668 pred_type (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1670 mode_t mode;
1671 mode_t type = pred_ptr->args.type;
1673 assert (state.have_type);
1675 if (0 == state.type)
1677 /* This can sometimes happen with broken NFS servers.
1678 * See Savannah bug #16378.
1680 return false;
1683 (void) pathname;
1685 if (state.have_stat)
1686 mode = stat_buf->st_mode;
1687 else
1688 mode = state.type;
1690 #ifndef S_IFMT
1691 /* POSIX system; check `mode' the slow way. */
1692 if ((S_ISBLK (mode) && type == S_IFBLK)
1693 || (S_ISCHR (mode) && type == S_IFCHR)
1694 || (S_ISDIR (mode) && type == S_IFDIR)
1695 || (S_ISREG (mode) && type == S_IFREG)
1696 #ifdef S_IFLNK
1697 || (S_ISLNK (mode) && type == S_IFLNK)
1698 #endif
1699 #ifdef S_IFIFO
1700 || (S_ISFIFO (mode) && type == S_IFIFO)
1701 #endif
1702 #ifdef S_IFSOCK
1703 || (S_ISSOCK (mode) && type == S_IFSOCK)
1704 #endif
1705 #ifdef S_IFDOOR
1706 || (S_ISDOOR (mode) && type == S_IFDOOR)
1707 #endif
1709 #else /* S_IFMT */
1710 /* Unix system; check `mode' the fast way. */
1711 if ((mode & S_IFMT) == type)
1712 #endif /* S_IFMT */
1713 return (true);
1714 else
1715 return (false);
1718 boolean
1719 pred_uid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1721 (void) pathname;
1722 switch (pred_ptr->args.numinfo.kind)
1724 case COMP_GT:
1725 if (stat_buf->st_uid > pred_ptr->args.numinfo.l_val)
1726 return (true);
1727 break;
1728 case COMP_LT:
1729 if (stat_buf->st_uid < pred_ptr->args.numinfo.l_val)
1730 return (true);
1731 break;
1732 case COMP_EQ:
1733 if (stat_buf->st_uid == pred_ptr->args.numinfo.l_val)
1734 return (true);
1735 break;
1737 return (false);
1740 boolean
1741 pred_used (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1743 struct timespec delta, at, ct;
1745 (void) pathname;
1747 /* TODO: this needs to be retested carefully (manually, if necessary) */
1748 at = get_stat_atime(stat_buf);
1749 ct = get_stat_ctime(stat_buf);
1750 delta.tv_sec = at.tv_sec - ct.tv_sec;
1751 delta.tv_nsec = at.tv_nsec - ct.tv_nsec;
1752 if (delta.tv_nsec < 0)
1754 delta.tv_nsec += 1000000000;
1755 delta.tv_sec -= 1;
1757 return pred_timewindow(delta, pred_ptr, DAYSECS);
1760 boolean
1761 pred_user (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1763 (void) pathname;
1764 if (pred_ptr->args.uid == stat_buf->st_uid)
1765 return (true);
1766 else
1767 return (false);
1770 boolean
1771 pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1773 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
1774 int (*ystat) (const char*, struct stat *p);
1776 /* If we would normally stat the link itself, stat the target instead.
1777 * If we would normally follow the link, stat the link itself instead.
1779 if (following_links())
1780 ystat = optionp_stat;
1781 else
1782 ystat = optionl_stat;
1784 set_stat_placeholders(&sbuf);
1785 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
1787 if (following_links() && errno == ENOENT)
1789 /* If we failed to follow the symlink,
1790 * fall back on looking at the symlink itself.
1792 /* Mimic behavior of ls -lL. */
1793 return (pred_type (pathname, stat_buf, pred_ptr));
1795 else
1797 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
1798 state.exit_status = 1;
1800 return false;
1802 /* Now that we have our stat() information, query it in the same
1803 * way that -type does.
1805 return (pred_type (pathname, &sbuf, pred_ptr));
1808 /* 1) fork to get a child; parent remembers the child pid
1809 2) child execs the command requested
1810 3) parent waits for child; checks for proper pid of child
1812 Possible returns:
1814 ret errno status(h) status(l)
1816 pid x signal# 0177 stopped
1817 pid x exit arg 0 term by _exit
1818 pid x 0 signal # term by signal
1819 -1 EINTR parent got signal
1820 -1 other some other kind of error
1822 Return true only if the pid matches, status(l) is
1823 zero, and the exit arg (status high) is 0.
1824 Otherwise return false, possibly printing an error message. */
1827 static boolean
1828 prep_child_for_exec (boolean close_stdin, int dirfd)
1830 boolean ok = true;
1831 if (close_stdin)
1833 const char inputfile[] = "/dev/null";
1835 if (close(0) < 0)
1837 error(0, errno, _("Cannot close standard input"));
1838 ok = false;
1840 else
1842 if (open(inputfile, O_RDONLY
1843 #if defined O_LARGEFILE
1844 |O_LARGEFILE
1845 #endif
1846 ) < 0)
1848 /* This is not entirely fatal, since
1849 * executing the child with a closed
1850 * stdin is almost as good as executing it
1851 * with its stdin attached to /dev/null.
1853 error (0, errno, "%s", safely_quote_err_filename(0, inputfile));
1854 /* do not set ok=false, it is OK to continue anyway. */
1859 /* Even if DebugSearch is set, don't announce our change of
1860 * directory, since we're not going to emit a subsequent
1861 * announcement of a call to stat() anyway, as we're about to exec
1862 * something.
1864 if (dirfd != AT_FDCWD)
1866 assert (dirfd >= 0);
1867 if (0 != fchdir(dirfd))
1869 /* If we cannot execute our command in the correct directory,
1870 * we should not execute it at all.
1872 error(0, errno, _("Failed to change directory"));
1873 ok = false;
1876 return ok;
1882 launch (const struct buildcmd_control *ctl,
1883 struct buildcmd_state *buildstate)
1885 int wait_status;
1886 pid_t child_pid;
1887 static int first_time = 1;
1888 const struct exec_val *execp = buildstate->usercontext;
1890 if (!execp->use_current_dir)
1892 assert (starting_desc >= 0);
1893 assert (execp->dirfd == starting_desc);
1897 /* Null terminate the arg list. */
1898 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false);
1900 /* Make sure output of command doesn't get mixed with find output. */
1901 fflush (stdout);
1902 fflush (stderr);
1904 /* Make sure to listen for the kids. */
1905 if (first_time)
1907 first_time = 0;
1908 signal (SIGCHLD, SIG_DFL);
1911 child_pid = fork ();
1912 if (child_pid == -1)
1913 error (1, errno, _("cannot fork"));
1914 if (child_pid == 0)
1916 /* We are the child. */
1917 assert (starting_desc >= 0);
1918 if (!prep_child_for_exec(execp->close_stdin, execp->dirfd))
1920 _exit(1);
1923 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv);
1924 error (0, errno, "%s",
1925 safely_quote_err_filename(0, buildstate->cmd_argv[0]));
1926 _exit (1);
1930 /* In parent; set up for next time. */
1931 bc_clear_args(ctl, buildstate);
1934 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1)
1936 if (errno != EINTR)
1938 error (0, errno, _("error waiting for %s"),
1939 safely_quote_err_filename(0, buildstate->cmd_argv[0]));
1940 state.exit_status = 1;
1941 return 0; /* FAIL */
1945 if (WIFSIGNALED (wait_status))
1947 error (0, 0, _("%s terminated by signal %d"),
1948 quotearg_n_style(0, options.err_quoting_style,
1949 buildstate->cmd_argv[0]),
1950 WTERMSIG (wait_status));
1952 if (execp->multiple)
1954 /* -exec \; just returns false if the invoked command fails.
1955 * -exec {} + returns true if the invoked command fails, but
1956 * sets the program exit status.
1958 state.exit_status = 1;
1961 return 1; /* OK */
1964 if (0 == WEXITSTATUS (wait_status))
1966 return 1; /* OK */
1968 else
1970 if (execp->multiple)
1972 /* -exec \; just returns false if the invoked command fails.
1973 * -exec {} + returns true if the invoked command fails, but
1974 * sets the program exit status.
1976 state.exit_status = 1;
1978 return 0; /* FAIL */
1984 /* Return a static string formatting the time WHEN according to the
1985 * strftime format character KIND.
1987 * This function contains a number of assertions. These look like
1988 * runtime checks of the results of computations, which would be a
1989 * problem since external events should not be tested for with
1990 * "assert" (instead you should use "if"). However, they are not
1991 * really runtime checks. The assertions actually exist to verify
1992 * that the various buffers are correctly sized.
1994 static char *
1995 format_date (struct timespec ts, int kind)
1997 /* In theory, we use an extra 10 characters for 9 digits of
1998 * nanoseconds and 1 for the decimal point. However, the real
1999 * world is more complex than that.
2001 * For example, some systems return junk in the tv_nsec part of
2002 * st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
2003 * (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
2004 * runtime and examining files on an msdos filesytem. So for that
2005 * reason we set NS_BUF_LEN to 32, which is simply "long enough" as
2006 * opposed to "exactly the right size". Note that the behaviour of
2007 * NetBSD appears to be a result of the use of uninitialised data,
2008 * as it's not 100% reproducible (more like 25%).
2010 enum {
2011 NS_BUF_LEN = 32,
2012 DATE_LEN_PERCENT_APLUS=21 /* length of result of %A+ (it's longer than %c)*/
2014 static char buf[128u+10u + MAX(DATE_LEN_PERCENT_APLUS,
2015 MAX (LONGEST_HUMAN_READABLE + 2, NS_BUF_LEN+64+200))];
2016 char ns_buf[NS_BUF_LEN]; /* -.9999999990 (- sign can happen!)*/
2017 int charsprinted, need_ns_suffix;
2018 struct tm *tm;
2019 char fmt[6];
2021 /* human_readable() assumes we pass a buffer which is at least as
2022 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
2023 * ensure that no nasty unsigned overflow happend in our calculation
2024 * of the size of buf. Do the assertion here rather than in the
2025 * code for %@ so that we find the problem quickly if it exists. If
2026 * you want to submit a patch to move this into the if statement, go
2027 * ahead, I'll apply it. But include performance timings
2028 * demonstrating that the performance difference is actually
2029 * measurable.
2031 verify (sizeof(buf) >= LONGEST_HUMAN_READABLE);
2033 charsprinted = 0;
2034 need_ns_suffix = 0;
2036 /* Format the main part of the time. */
2037 if (kind == '+')
2039 strcpy (fmt, "%F+%T");
2040 need_ns_suffix = 1;
2042 else
2044 fmt[0] = '%';
2045 fmt[1] = kind;
2046 fmt[2] = '\0';
2048 /* %a, %c, and %t are handled in ctime_format() */
2049 switch (kind)
2051 case 'S':
2052 case 'T':
2053 case 'X':
2054 case '@':
2055 need_ns_suffix = 1;
2056 break;
2057 default:
2058 need_ns_suffix = 0;
2059 break;
2063 if (need_ns_suffix)
2065 /* Format the nanoseconds part. Leave a trailing zero to
2066 * discourage people from writing scripts which extract the
2067 * fractional part of the timestamp by using column offsets.
2068 * The reason for discouraging this is that in the future, the
2069 * granularity may not be nanoseconds.
2071 ns_buf[0] = 0;
2072 charsprinted = snprintf(ns_buf, NS_BUF_LEN, ".%09ld0", (long int)ts.tv_nsec);
2073 assert (charsprinted < NS_BUF_LEN);
2076 if (kind != '@'
2077 && (tm = localtime (&ts.tv_sec))
2078 && strftime (buf, sizeof buf, fmt, tm))
2080 /* For %AS, %CS, %TS, add the fractional part of the seconds
2081 * information.
2083 if (need_ns_suffix)
2085 assert ((sizeof buf - strlen(buf)) > strlen(ns_buf));
2086 strcat(buf, ns_buf);
2088 return buf;
2090 else
2092 uintmax_t w = ts.tv_sec;
2093 size_t used, len, remaining;
2095 /* XXX: note that we are negating an unsigned type which is the
2096 * widest possible unsigned type.
2098 char *p = human_readable (ts.tv_sec < 0 ? -w : w, buf + 1,
2099 human_ceiling, 1, 1);
2100 assert (p > buf);
2101 assert (p < (buf + (sizeof buf)));
2102 if (ts.tv_sec < 0)
2103 *--p = '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
2105 /* Add the nanoseconds part. Because we cannot enforce a
2106 * particlar implementation of human_readable, we cannot assume
2107 * any particular value for (p-buf). So we need to be careful
2108 * that there is enough space remaining in the buffer.
2110 if (need_ns_suffix)
2112 len = strlen(p);
2113 used = (p-buf) + len; /* Offset into buf of current end */
2114 assert (sizeof buf > used); /* Ensure we can perform subtraction safely. */
2115 remaining = sizeof buf - used - 1u; /* allow space for NUL */
2117 if (strlen(ns_buf) >= remaining)
2119 error(0, 0,
2120 "charsprinted=%ld but remaining=%lu: ns_buf=%s",
2121 (long)charsprinted, (unsigned long)remaining, ns_buf);
2123 assert (strlen(ns_buf) < remaining);
2124 strcat(p, ns_buf);
2126 return p;
2130 static const char *weekdays[] =
2132 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
2134 static char * months[] =
2136 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2137 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2141 static char *
2142 ctime_format (struct timespec ts)
2144 const struct tm * ptm;
2145 #define TIME_BUF_LEN 1024u
2146 static char resultbuf[TIME_BUF_LEN];
2147 int nout;
2149 ptm = localtime(&ts.tv_sec);
2150 if (ptm)
2152 assert (ptm->tm_wday >= 0);
2153 assert (ptm->tm_wday < 7);
2154 assert (ptm->tm_mon >= 0);
2155 assert (ptm->tm_mon < 12);
2156 assert (ptm->tm_hour >= 0);
2157 assert (ptm->tm_hour < 24);
2158 assert (ptm->tm_min < 60);
2159 assert (ptm->tm_sec <= 61); /* allows 2 leap seconds. */
2161 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
2162 nout = snprintf(resultbuf, TIME_BUF_LEN,
2163 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
2164 weekdays[ptm->tm_wday],
2165 months[ptm->tm_mon],
2166 ptm->tm_mday,
2167 ptm->tm_hour,
2168 ptm->tm_min,
2169 ptm->tm_sec,
2170 (long int)ts.tv_nsec,
2171 1900 + ptm->tm_year);
2173 assert (nout < TIME_BUF_LEN);
2174 return resultbuf;
2176 else
2178 /* The time cannot be represented as a struct tm.
2179 Output it as an integer. */
2180 return format_date (ts, '@');
2184 /* Copy STR into BUF and trim blanks from the end of BUF.
2185 Return BUF. */
2187 static char *
2188 blank_rtrim (str, buf)
2189 char *str;
2190 char *buf;
2192 int i;
2194 if (str == NULL)
2195 return (NULL);
2196 strcpy (buf, str);
2197 i = strlen (buf) - 1;
2198 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
2199 i--;
2200 buf[++i] = '\0';
2201 return (buf);
2204 /* Print out the predicate list starting at NODE. */
2205 void
2206 print_list (FILE *fp, struct predicate *node)
2208 struct predicate *cur;
2209 char name[256];
2211 cur = node;
2212 while (cur != NULL)
2214 fprintf (fp, "[%s] ", blank_rtrim (cur->p_name, name));
2215 cur = cur->pred_next;
2217 fprintf (fp, "\n");
2220 /* Print out the predicate list starting at NODE. */
2221 static void
2222 print_parenthesised(FILE *fp, struct predicate *node)
2224 int parens = 0;
2226 if (node)
2228 if ((pred_is(node, pred_or) || pred_is(node, pred_and))
2229 && node->pred_left == NULL)
2231 /* We print "<nothing> or X" as just "X"
2232 * We print "<nothing> and X" as just "X"
2234 print_parenthesised(fp, node->pred_right);
2236 else
2238 if (node->pred_left || node->pred_right)
2239 parens = 1;
2241 if (parens)
2242 fprintf(fp, "%s", " ( ");
2243 print_optlist(fp, node);
2244 if (parens)
2245 fprintf(fp, "%s", " ) ");
2250 void
2251 print_optlist (FILE *fp, const struct predicate *p)
2253 if (p)
2255 print_parenthesised(fp, p->pred_left);
2256 fprintf (fp,
2257 "%s%s",
2258 p->need_stat ? "[call stat] " : "",
2259 p->need_type ? "[need type] " : "");
2260 print_predicate(fp, p);
2261 fprintf(fp, " [%g] ", p->est_success_rate);
2262 if (options.debug_options & DebugSuccessRates)
2264 fprintf(fp, "[%ld/%ld", p->perf.successes, p->perf.visits);
2265 if (p->perf.visits)
2267 double real_rate = (double)p->perf.successes / (double)p->perf.visits;
2268 fprintf(fp, "=%g] ", real_rate);
2270 else
2272 fprintf(fp, "=_] ");
2275 print_parenthesised(fp, p->pred_right);
2279 void show_success_rates(const struct predicate *p)
2281 if (options.debug_options & DebugSuccessRates)
2283 fprintf(stderr, "Predicate success rates after completion:\n");
2284 print_optlist(stderr, p);
2285 fprintf(stderr, "\n");
2292 #ifdef _NDEBUG
2293 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2294 * there is no point in having a function body for pred_sanity_check()
2295 * if that preprocessor macro is defined.
2297 void
2298 pred_sanity_check(const struct predicate *predicates)
2300 /* Do nothing, since assert is a no-op with _NDEBUG set */
2301 return;
2303 #else
2304 void
2305 pred_sanity_check(const struct predicate *predicates)
2307 const struct predicate *p;
2309 for (p=predicates; p != NULL; p=p->pred_next)
2311 /* All predicates must do something. */
2312 assert (p->pred_func != NULL);
2314 /* All predicates must have a parser table entry. */
2315 assert (p->parser_entry != NULL);
2317 /* If the parser table tells us that just one predicate function is
2318 * possible, verify that that is still the one that is in effect.
2319 * If the parser has NULL for the predicate function, that means that
2320 * the parse_xxx function fills it in, so we can't check it.
2322 if (p->parser_entry->pred_func)
2324 assert (p->parser_entry->pred_func == p->pred_func);
2327 switch (p->parser_entry->type)
2329 /* Options all take effect during parsing, so there should
2330 * be no predicate entries corresponding to them. Hence we
2331 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2332 * items.
2334 * This is a silly way of coding this test, but it prevents
2335 * a compiler warning (i.e. otherwise it would think that
2336 * there would be case statements missing).
2338 case ARG_OPTION:
2339 case ARG_POSITIONAL_OPTION:
2340 assert (p->parser_entry->type != ARG_OPTION);
2341 assert (p->parser_entry->type != ARG_POSITIONAL_OPTION);
2342 break;
2344 case ARG_ACTION:
2345 assert(p->side_effects); /* actions have side effects. */
2346 if (!pred_is(p, pred_prune) && !pred_is(p, pred_quit))
2348 /* actions other than -prune and -quit should
2349 * inhibit the default -print
2351 assert (p->no_default_print);
2353 break;
2355 /* We happen to know that the only user of ARG_SPECIAL_PARSE
2356 * is a test, so handle it like ARG_TEST.
2358 case ARG_SPECIAL_PARSE:
2359 case ARG_TEST:
2360 case ARG_PUNCTUATION:
2361 case ARG_NOOP:
2362 /* Punctuation and tests should have no side
2363 * effects and not inhibit default print.
2365 assert (!p->no_default_print);
2366 assert (!p->side_effects);
2367 break;
2371 #endif