Implemented -newerXY (but this is not documented yet)
[findutils.git] / find / pred.c
blob6e8203dcc7482bc8bec50b6238a22ba4df63e47d
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 <math.h>
26 #include <pwd.h>
27 #include <grp.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <assert.h>
31 #include <fcntl.h>
32 #include <locale.h>
33 #include "xalloc.h"
34 #include "dirname.h"
35 #include "human.h"
36 #include "modetype.h"
37 #include "filemode.h"
38 #include "wait.h"
39 #include "printquoted.h"
40 #include "buildcmd.h"
41 #include "yesno.h"
42 #include "listfile.h"
43 #include "stat-time.h"
45 #if ENABLE_NLS
46 # include <libintl.h>
47 # define _(Text) gettext (Text)
48 #else
49 # define _(Text) Text
50 #endif
51 #ifdef gettext_noop
52 # define N_(String) gettext_noop (String)
53 #else
54 /* See locate.c for explanation as to why not use (String) */
55 # define N_(String) String
56 #endif
58 #if !defined(SIGCHLD) && defined(SIGCLD)
59 #define SIGCHLD SIGCLD
60 #endif
64 #if HAVE_DIRENT_H
65 # include <dirent.h>
66 # define NAMLEN(dirent) strlen((dirent)->d_name)
67 #else
68 # define dirent direct
69 # define NAMLEN(dirent) (dirent)->d_namlen
70 # if HAVE_SYS_NDIR_H
71 # include <sys/ndir.h>
72 # endif
73 # if HAVE_SYS_DIR_H
74 # include <sys/dir.h>
75 # endif
76 # if HAVE_NDIR_H
77 # include <ndir.h>
78 # endif
79 #endif
81 #ifdef CLOSEDIR_VOID
82 /* Fake a return value. */
83 #define CLOSEDIR(d) (closedir (d), 0)
84 #else
85 #define CLOSEDIR(d) closedir (d)
86 #endif
91 /* Get or fake the disk device blocksize.
92 Usually defined by sys/param.h (if at all). */
93 #ifndef DEV_BSIZE
94 # ifdef BSIZE
95 # define DEV_BSIZE BSIZE
96 # else /* !BSIZE */
97 # define DEV_BSIZE 4096
98 # endif /* !BSIZE */
99 #endif /* !DEV_BSIZE */
101 /* Extract or fake data from a `struct stat'.
102 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
103 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
104 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
105 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
106 # define ST_BLKSIZE(statbuf) DEV_BSIZE
107 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
108 # define ST_NBLOCKS(statbuf) \
109 (S_ISREG ((statbuf).st_mode) \
110 || S_ISDIR ((statbuf).st_mode) \
111 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
112 # else /* !_POSIX_SOURCE && BSIZE */
113 # define ST_NBLOCKS(statbuf) \
114 (S_ISREG ((statbuf).st_mode) \
115 || S_ISDIR ((statbuf).st_mode) \
116 ? st_blocks ((statbuf).st_size) : 0)
117 # endif /* !_POSIX_SOURCE && BSIZE */
118 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
119 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
120 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
121 ? (statbuf).st_blksize : DEV_BSIZE)
122 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
123 /* HP-UX counts st_blocks in 1024-byte units.
124 This loses when mixing HP-UX and BSD filesystems with NFS. */
125 # define ST_NBLOCKSIZE 1024
126 # else /* !hpux */
127 # if defined(_AIX) && defined(_I386)
128 /* AIX PS/2 counts st_blocks in 4K units. */
129 # define ST_NBLOCKSIZE (4 * 1024)
130 # else /* not AIX PS/2 */
131 # if defined(_CRAY)
132 # define ST_NBLOCKS(statbuf) \
133 (S_ISREG ((statbuf).st_mode) \
134 || S_ISDIR ((statbuf).st_mode) \
135 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
136 # endif /* _CRAY */
137 # endif /* not AIX PS/2 */
138 # endif /* !hpux */
139 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
141 #ifndef ST_NBLOCKS
142 # define ST_NBLOCKS(statbuf) \
143 (S_ISREG ((statbuf).st_mode) \
144 || S_ISDIR ((statbuf).st_mode) \
145 ? (statbuf).st_blocks : 0)
146 #endif
148 #ifndef ST_NBLOCKSIZE
149 # define ST_NBLOCKSIZE 512
150 #endif
153 #undef MAX
154 #define MAX(a, b) ((a) > (b) ? (a) : (b))
156 static boolean match_lname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case));
158 static char *format_date PARAMS((struct timespec ts, int kind));
159 static char *ctime_format PARAMS((struct timespec ts));
161 #ifdef DEBUG
162 struct pred_assoc
164 PRED_FUNC pred_func;
165 char *pred_name;
168 struct pred_assoc pred_table[] =
170 {pred_amin, "amin "},
171 {pred_and, "and "},
172 {pred_anewer, "anewer "},
173 {pred_atime, "atime "},
174 {pred_close, ") "},
175 {pred_cmin, "cmin "},
176 {pred_cnewer, "cnewer "},
177 {pred_comma, ", "},
178 {pred_ctime, "ctime "},
179 {pred_delete, "delete "},
180 {pred_empty, "empty "},
181 {pred_exec, "exec "},
182 {pred_execdir, "execdir "},
183 {pred_executable, "executable "},
184 {pred_false, "false "},
185 {pred_fprint, "fprint "},
186 {pred_fprint0, "fprint0 "},
187 {pred_fprintf, "fprintf "},
188 {pred_fstype, "fstype "},
189 {pred_gid, "gid "},
190 {pred_group, "group "},
191 {pred_ilname, "ilname "},
192 {pred_iname, "iname "},
193 {pred_inum, "inum "},
194 {pred_ipath, "ipath "},
195 {pred_links, "links "},
196 {pred_lname, "lname "},
197 {pred_ls, "ls "},
198 {pred_mmin, "mmin "},
199 {pred_mtime, "mtime "},
200 {pred_name, "name "},
201 {pred_negate, "not "},
202 {pred_newer, "newer "},
203 {pred_newerXY, "newerXY "},
204 {pred_nogroup, "nogroup "},
205 {pred_nouser, "nouser "},
206 {pred_ok, "ok "},
207 {pred_okdir, "okdir "},
208 {pred_open, "( "},
209 {pred_or, "or "},
210 {pred_path, "path "},
211 {pred_perm, "perm "},
212 {pred_print, "print "},
213 {pred_print0, "print0 "},
214 {pred_prune, "prune "},
215 {pred_quit, "quit "},
216 {pred_readable, "readable "},
217 {pred_regex, "regex "},
218 {pred_samefile,"samefile "},
219 {pred_size, "size "},
220 {pred_true, "true "},
221 {pred_type, "type "},
222 {pred_uid, "uid "},
223 {pred_used, "used "},
224 {pred_user, "user "},
225 {pred_writable, "writable "},
226 {pred_xtype, "xtype "},
227 {0, "none "}
229 #endif
231 /* Returns ts1 - ts2 */
232 static double ts_difference(struct timespec ts1,
233 struct timespec ts2)
235 double d = difftime(ts1.tv_sec, ts2.tv_sec)
236 + (1.0e-9 * (ts1.tv_nsec - ts2.tv_nsec));
237 return d;
241 static int
242 compare_ts(struct timespec ts1,
243 struct timespec ts2)
245 if ((ts1.tv_sec == ts2.tv_sec) &&
246 (ts1.tv_nsec == ts2.tv_nsec))
248 return 0;
250 else
252 double diff = ts_difference(ts1, ts2);
253 return diff < 0.0 ? -1 : +1;
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(struct timespec ts, struct predicate const *pred_ptr, int window)
276 double delta;
278 switch (pred_ptr->args.reftime.kind)
280 case COMP_GT:
281 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
283 case COMP_LT:
284 return compare_ts(ts, pred_ptr->args.reftime.ts) < 0;
286 case COMP_EQ:
287 delta = ts_difference(ts, pred_ptr->args.reftime.ts);
288 return (delta >= 0.0 && delta < window);
293 boolean
294 pred_amin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
296 (void) &pathname;
297 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, 60);
300 boolean
301 pred_and (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
303 if (pred_ptr->pred_left == NULL
304 || (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
305 pred_ptr->pred_left))
307 /* Check whether we need a stat here. */
308 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
309 return false;
310 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
311 pred_ptr->pred_right));
313 else
314 return (false);
317 boolean
318 pred_anewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
320 (void) &pathname;
321 assert(COMP_GT == pred_ptr->args.reftime.kind);
322 return compare_ts(get_stat_atime(stat_buf), pred_ptr->args.reftime.ts) > 0;
325 boolean
326 pred_atime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
328 (void) &pathname;
329 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, DAYSECS);
332 boolean
333 pred_close (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
335 (void) &pathname;
336 (void) &stat_buf;
337 (void) &pred_ptr;
339 return true;
342 boolean
343 pred_cmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
345 (void) pathname;
346 return pred_timewindow(get_stat_ctime(stat_buf), pred_ptr, 60);
349 boolean
350 pred_cnewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
352 (void) pathname;
354 assert(COMP_GT == pred_ptr->args.reftime.kind);
355 return compare_ts(get_stat_ctime(stat_buf), pred_ptr->args.reftime.ts) > 0;
358 boolean
359 pred_comma (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
361 if (pred_ptr->pred_left != NULL)
362 (*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
363 pred_ptr->pred_left);
364 /* Check whether we need a stat here. */
365 /* TODO: what about need_type? */
366 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
367 return false;
368 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
369 pred_ptr->pred_right));
372 boolean
373 pred_ctime (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 boolean
380 pred_delete (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
382 (void) pred_ptr;
383 (void) stat_buf;
384 if (strcmp (state.rel_pathname, "."))
386 if (0 != remove (state.rel_pathname))
388 error (0, errno, "cannot delete %s", pathname);
389 return false;
391 else
393 return true;
397 /* nothing to do. */
398 return true;
401 boolean
402 pred_empty (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
404 (void) pathname;
405 (void) pred_ptr;
407 if (S_ISDIR (stat_buf->st_mode))
409 DIR *d;
410 struct dirent *dp;
411 boolean empty = true;
413 errno = 0;
414 d = opendir (state.rel_pathname);
415 if (d == NULL)
417 error (0, errno, "%s", pathname);
418 state.exit_status = 1;
419 return false;
421 for (dp = readdir (d); dp; dp = readdir (d))
423 if (dp->d_name[0] != '.'
424 || (dp->d_name[1] != '\0'
425 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
427 empty = false;
428 break;
431 if (CLOSEDIR (d))
433 error (0, errno, "%s", pathname);
434 state.exit_status = 1;
435 return false;
437 return (empty);
439 else if (S_ISREG (stat_buf->st_mode))
440 return (stat_buf->st_size == 0);
441 else
442 return (false);
445 static boolean
446 new_impl_pred_exec (const char *pathname, struct stat *stat_buf,
447 struct predicate *pred_ptr,
448 const char *prefix, size_t pfxlen)
450 struct exec_val *execp = &pred_ptr->args.exec_vec;
451 size_t len = strlen(pathname);
453 (void) stat_buf;
455 if (execp->multiple)
457 /* Push the argument onto the current list.
458 * The command may or may not be run at this point,
459 * depending on the command line length limits.
461 bc_push_arg(&execp->ctl,
462 &execp->state,
463 pathname, len+1,
464 prefix, pfxlen,
467 /* POSIX: If the primary expression is punctuated by a plus
468 * sign, the primary shall always evaluate as true
470 return true;
472 else
474 int i;
476 for (i=0; i<execp->num_args; ++i)
478 bc_do_insert(&execp->ctl,
479 &execp->state,
480 execp->replace_vec[i],
481 strlen(execp->replace_vec[i]),
482 prefix, pfxlen,
483 pathname, len,
487 /* Actually invoke the command. */
488 return execp->ctl.exec_callback(&execp->ctl,
489 &execp->state);
494 boolean
495 pred_exec (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
497 return new_impl_pred_exec(pathname, stat_buf, pred_ptr, NULL, 0);
500 boolean
501 pred_execdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
503 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
504 (void) &pathname;
505 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr,
506 prefix, (prefix ? 2 : 0));
509 boolean
510 pred_false (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
512 (void) &pathname;
513 (void) &stat_buf;
514 (void) &pred_ptr;
517 return (false);
520 boolean
521 pred_fls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
523 list_file (pathname, state.rel_pathname, stat_buf, options.start_time.tv_sec,
524 options.output_block_size,
525 pred_ptr->literal_control_chars, pred_ptr->args.stream);
526 return true;
529 boolean
530 pred_fprint (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
532 (void) &pathname;
533 (void) &stat_buf;
535 print_quoted(pred_ptr->args.printf_vec.stream,
536 pred_ptr->args.printf_vec.quote_opts,
537 pred_ptr->args.printf_vec.dest_is_tty,
538 "%s\n",
539 pathname);
540 return true;
543 boolean
544 pred_fprint0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
546 (void) &pathname;
547 (void) &stat_buf;
549 fputs (pathname, pred_ptr->args.stream);
550 putc (0, pred_ptr->args.stream);
551 return (true);
556 static char*
557 mode_to_filetype(mode_t m)
559 return
560 m == S_IFSOCK ? "s" :
561 m == S_IFLNK ? "l" :
562 m == S_IFREG ? "f" :
563 m == S_IFBLK ? "b" :
564 m == S_IFDIR ? "d" :
565 m == S_IFCHR ? "c" :
566 #ifdef S_IFDOOR
567 m == S_IFDOOR ? "D" :
568 #endif
569 m == S_IFIFO ? "p" : "U";
572 static double
573 file_sparseness(const struct stat *p)
575 if (0 == p->st_size)
577 if (0 == p->st_blocks)
578 return 1.0;
579 else
580 return p->st_blocks < 0 ? -HUGE_VAL : HUGE_VAL;
582 else
584 double blklen = file_blocksize(p) * (double)p->st_blocks;
585 return blklen / p->st_size;
591 static boolean
592 do_fprintf(FILE *fp,
593 struct segment *segment,
594 char *pathname,
595 const struct stat *stat_buf,
596 boolean ttyflag,
597 const struct quoting_options *qopts)
599 char hbuf[LONGEST_HUMAN_READABLE + 1];
600 char *cp;
602 switch (segment->segkind)
604 case KIND_PLAIN: /* Plain text string (no % conversion). */
605 /* trusted */
606 fwrite (segment->text, 1, segment->text_len, fp);
607 break;
609 case KIND_STOP: /* Terminate argument and flush output. */
610 /* trusted */
611 fwrite (segment->text, 1, segment->text_len, fp);
612 fflush (fp);
613 return (true);
615 case KIND_FORMAT:
616 switch (segment->format_char[0])
618 case 'a': /* atime in `ctime' format. */
619 /* UNTRUSTED, probably unexploitable */
620 fprintf (fp, segment->text, ctime_format (get_stat_atime(stat_buf)));
621 break;
622 case 'b': /* size in 512-byte blocks */
623 /* UNTRUSTED, probably unexploitable */
624 fprintf (fp, segment->text,
625 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
626 hbuf, human_ceiling,
627 ST_NBLOCKSIZE, 512));
628 break;
629 case 'c': /* ctime in `ctime' format */
630 /* UNTRUSTED, probably unexploitable */
631 fprintf (fp, segment->text, ctime_format (get_stat_ctime(stat_buf)));
632 break;
633 case 'd': /* depth in search tree */
634 /* UNTRUSTED, probably unexploitable */
635 fprintf (fp, segment->text, state.curdepth);
636 break;
637 case 'D': /* Device on which file exists (stat.st_dev) */
638 /* trusted */
639 fprintf (fp, segment->text,
640 human_readable ((uintmax_t) stat_buf->st_dev, hbuf,
641 human_ceiling, 1, 1));
642 break;
643 case 'f': /* base name of path */
644 /* sanitised */
645 print_quoted (fp, qopts, ttyflag, segment->text, base_name (pathname));
646 break;
647 case 'F': /* filesystem type */
648 /* trusted */
649 print_quoted (fp, qopts, ttyflag, segment->text, filesystem_type (stat_buf, pathname));
650 break;
651 case 'g': /* group name */
652 /* trusted */
653 /* (well, the actual group is selected by the user but
654 * its name was selected by the system administrator)
657 struct group *g;
659 g = getgrgid (stat_buf->st_gid);
660 if (g)
662 segment->text[segment->text_len] = 's';
663 fprintf (fp, segment->text, g->gr_name);
664 break;
666 else
668 /* Do nothing. */
669 /*FALLTHROUGH*/
672 case 'G': /* GID number */
673 /* UNTRUSTED, probably unexploitable */
674 fprintf (fp, segment->text,
675 human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
676 human_ceiling, 1, 1));
677 break;
678 case 'h': /* leading directories part of path */
679 /* sanitised */
681 char cc;
683 cp = strrchr (pathname, '/');
684 if (cp == NULL) /* No leading directories. */
686 /* If there is no slash in the pathname, we still
687 * print the string because it contains characters
688 * other than just '%s'. The %h expands to ".".
690 print_quoted (fp, qopts, ttyflag, segment->text, ".");
692 else
694 cc = *cp;
695 *cp = '\0';
696 print_quoted (fp, qopts, ttyflag, segment->text, pathname);
697 *cp = cc;
699 break;
701 case 'H': /* ARGV element file was found under */
702 /* trusted */
704 char cc = pathname[state.starting_path_length];
706 pathname[state.starting_path_length] = '\0';
707 fprintf (fp, segment->text, pathname);
708 pathname[state.starting_path_length] = cc;
709 break;
711 case 'i': /* inode number */
712 /* UNTRUSTED, but not exploitable I think */
713 fprintf (fp, segment->text,
714 human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
715 human_ceiling,
716 1, 1));
717 break;
718 case 'k': /* size in 1K blocks */
719 /* UNTRUSTED, but not exploitable I think */
720 fprintf (fp, segment->text,
721 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
722 hbuf, human_ceiling,
723 ST_NBLOCKSIZE, 1024));
724 break;
725 case 'l': /* object of symlink */
726 /* sanitised */
727 #ifdef S_ISLNK
729 char *linkname = 0;
731 if (S_ISLNK (stat_buf->st_mode))
733 linkname = get_link_name (pathname, state.rel_pathname);
734 if (linkname == 0)
735 state.exit_status = 1;
737 if (linkname)
739 print_quoted (fp, qopts, ttyflag, segment->text, linkname);
740 free (linkname);
742 else
743 print_quoted (fp, qopts, ttyflag, segment->text, "");
745 #endif /* S_ISLNK */
746 break;
748 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
749 /* UNTRUSTED, probably unexploitable */
751 char modestring[16] ;
752 filemodestring (stat_buf, modestring);
753 modestring[10] = '\0';
754 fprintf (fp, segment->text, modestring);
756 break;
758 case 'm': /* mode as octal number (perms only) */
759 /* UNTRUSTED, probably unexploitable */
761 /* Output the mode portably using the traditional numbers,
762 even if the host unwisely uses some other numbering
763 scheme. But help the compiler in the common case where
764 the host uses the traditional numbering scheme. */
765 mode_t m = stat_buf->st_mode;
766 boolean traditional_numbering_scheme =
767 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
768 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
769 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
770 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
771 fprintf (fp, segment->text,
772 (traditional_numbering_scheme
773 ? m & MODE_ALL
774 : ((m & S_ISUID ? 04000 : 0)
775 | (m & S_ISGID ? 02000 : 0)
776 | (m & S_ISVTX ? 01000 : 0)
777 | (m & S_IRUSR ? 00400 : 0)
778 | (m & S_IWUSR ? 00200 : 0)
779 | (m & S_IXUSR ? 00100 : 0)
780 | (m & S_IRGRP ? 00040 : 0)
781 | (m & S_IWGRP ? 00020 : 0)
782 | (m & S_IXGRP ? 00010 : 0)
783 | (m & S_IROTH ? 00004 : 0)
784 | (m & S_IWOTH ? 00002 : 0)
785 | (m & S_IXOTH ? 00001 : 0))));
787 break;
789 case 'n': /* number of links */
790 /* UNTRUSTED, probably unexploitable */
791 fprintf (fp, segment->text,
792 human_readable ((uintmax_t) stat_buf->st_nlink,
793 hbuf,
794 human_ceiling,
795 1, 1));
796 break;
797 case 'p': /* pathname */
798 /* sanitised */
799 print_quoted (fp, qopts, ttyflag, segment->text, pathname);
800 break;
801 case 'P': /* pathname with ARGV element stripped */
802 /* sanitised */
803 if (state.curdepth > 0)
805 cp = pathname + state.starting_path_length;
806 if (*cp == '/')
807 /* Move past the slash between the ARGV element
808 and the rest of the pathname. But if the ARGV element
809 ends in a slash, we didn't add another, so we've
810 already skipped past it. */
811 cp++;
813 else
814 cp = "";
815 print_quoted (fp, qopts, ttyflag, segment->text, cp);
816 break;
817 case 's': /* size in bytes */
818 /* UNTRUSTED, probably unexploitable */
819 fprintf (fp, segment->text,
820 human_readable ((uintmax_t) stat_buf->st_size,
821 hbuf, human_ceiling, 1, 1));
822 break;
824 case 'S': /* sparseness */
825 /* UNTRUSTED, probably unexploitable */
826 fprintf (fp, segment->text, file_sparseness(stat_buf));;
827 break;
829 case 't': /* mtime in `ctime' format */
830 /* UNTRUSTED, probably unexploitable */
831 fprintf (fp, segment->text, ctime_format (get_stat_mtime(stat_buf)));
832 break;
834 case 'u': /* user name */
835 /* trusted */
836 /* (well, the actual user is selected by the user on systems
837 * where chown is not restricted, but the user name was
838 * selected by the system administrator)
841 struct passwd *p;
843 p = getpwuid (stat_buf->st_uid);
844 if (p)
846 segment->text[segment->text_len] = 's';
847 fprintf (fp, segment->text, p->pw_name);
848 break;
850 /* else fallthru */
853 case 'U': /* UID number */
854 /* UNTRUSTED, probably unexploitable */
855 fprintf (fp, segment->text,
856 human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
857 human_ceiling, 1, 1));
858 break;
860 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
861 case 'Y': /* in case of symlink */
862 /* trusted */
864 #ifdef S_ISLNK
865 if (S_ISLNK (stat_buf->st_mode))
867 struct stat sbuf;
868 /* If we would normally follow links, do not do so.
869 * If we would normally not follow links, do so.
871 if ((following_links() ? lstat : stat)
872 (state.rel_pathname, &sbuf) != 0)
874 if ( errno == ENOENT ) {
875 fprintf (fp, segment->text, "N");
876 break;
878 if ( errno == ELOOP ) {
879 fprintf (fp, segment->text, "L");
880 break;
882 error (0, errno, "%s", pathname);
883 /* exit_status = 1;
884 return (false); */
886 fprintf (fp, segment->text,
887 mode_to_filetype(sbuf.st_mode & S_IFMT));
889 #endif /* S_ISLNK */
890 else
892 fprintf (fp, segment->text,
893 mode_to_filetype(stat_buf->st_mode & S_IFMT));
896 break;
898 case 'y':
899 /* trusted */
901 fprintf (fp, segment->text,
902 mode_to_filetype(stat_buf->st_mode & S_IFMT));
904 break;
906 break;
908 #warning this function needs a return statement. See Savannah bug#19146.
911 boolean
912 pred_fprintf (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
914 FILE *fp = pred_ptr->args.printf_vec.stream;
915 struct segment *segment;
916 boolean ttyflag = pred_ptr->args.printf_vec.dest_is_tty;
917 const struct quoting_options *qopts = pred_ptr->args.printf_vec.quote_opts;
919 for (segment = pred_ptr->args.printf_vec.segment; segment;
920 segment = segment->next)
922 if ( (KIND_FORMAT == segment->segkind) && segment->format_char[1]) /* Component of date. */
924 struct timespec ts;
926 switch (segment->format_char[0])
928 case 'A':
929 ts = get_stat_atime(stat_buf);
930 break;
931 case 'C':
932 ts = get_stat_ctime(stat_buf);
933 break;
934 case 'T':
935 ts = get_stat_mtime(stat_buf);
936 break;
937 default:
938 assert(0);
939 abort ();
941 /* We trust the output of format_date not to contain
942 * nasty characters, though the value of the date
943 * is itself untrusted data.
945 /* trusted */
946 fprintf (fp, segment->text,
947 format_date (ts, segment->format_char[1]));
949 else
951 do_fprintf(fp, segment, pathname, stat_buf, ttyflag, qopts);
954 return true;
957 boolean
958 pred_fstype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
960 (void) pathname;
962 if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0)
963 return true;
964 else
965 return false;
968 boolean
969 pred_gid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
971 (void) pathname;
973 switch (pred_ptr->args.numinfo.kind)
975 case COMP_GT:
976 if (stat_buf->st_gid > pred_ptr->args.numinfo.l_val)
977 return (true);
978 break;
979 case COMP_LT:
980 if (stat_buf->st_gid < pred_ptr->args.numinfo.l_val)
981 return (true);
982 break;
983 case COMP_EQ:
984 if (stat_buf->st_gid == pred_ptr->args.numinfo.l_val)
985 return (true);
986 break;
988 return (false);
991 boolean
992 pred_group (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
994 (void) pathname;
996 if (pred_ptr->args.gid == stat_buf->st_gid)
997 return (true);
998 else
999 return (false);
1002 boolean
1003 pred_ilname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1005 return match_lname (pathname, stat_buf, pred_ptr, true);
1008 boolean
1009 pred_iname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1011 const char *base;
1013 (void) stat_buf;
1015 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1016 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1018 base = base_name (pathname);
1019 if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0)
1020 return (true);
1021 return (false);
1024 boolean
1025 pred_inum (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1027 (void) pathname;
1029 switch (pred_ptr->args.numinfo.kind)
1031 case COMP_GT:
1032 if (stat_buf->st_ino > pred_ptr->args.numinfo.l_val)
1033 return (true);
1034 break;
1035 case COMP_LT:
1036 if (stat_buf->st_ino < pred_ptr->args.numinfo.l_val)
1037 return (true);
1038 break;
1039 case COMP_EQ:
1040 if (stat_buf->st_ino == pred_ptr->args.numinfo.l_val)
1041 return (true);
1042 break;
1044 return (false);
1047 boolean
1048 pred_ipath (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1050 (void) stat_buf;
1052 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
1053 return (true);
1054 return (false);
1057 boolean
1058 pred_links (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1060 (void) pathname;
1062 switch (pred_ptr->args.numinfo.kind)
1064 case COMP_GT:
1065 if (stat_buf->st_nlink > pred_ptr->args.numinfo.l_val)
1066 return (true);
1067 break;
1068 case COMP_LT:
1069 if (stat_buf->st_nlink < pred_ptr->args.numinfo.l_val)
1070 return (true);
1071 break;
1072 case COMP_EQ:
1073 if (stat_buf->st_nlink == pred_ptr->args.numinfo.l_val)
1074 return (true);
1075 break;
1077 return (false);
1080 boolean
1081 pred_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1083 return match_lname (pathname, stat_buf, pred_ptr, false);
1086 static boolean
1087 match_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)
1089 boolean ret = false;
1090 #ifdef S_ISLNK
1091 if (S_ISLNK (stat_buf->st_mode))
1093 char *linkname = get_link_name (pathname, state.rel_pathname);
1094 if (linkname)
1096 if (fnmatch (pred_ptr->args.str, linkname,
1097 ignore_case ? FNM_CASEFOLD : 0) == 0)
1098 ret = true;
1099 free (linkname);
1102 #endif /* S_ISLNK */
1103 return ret;
1106 boolean
1107 pred_ls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1109 list_file (pathname, state.rel_pathname, stat_buf, options.start_time.tv_sec,
1110 options.output_block_size,
1111 pred_ptr->literal_control_chars,
1112 stdout);
1113 return true;
1116 boolean
1117 pred_mmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1119 (void) &pathname;
1120 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, 60);
1123 boolean
1124 pred_mtime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1126 (void) pathname;
1127 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, DAYSECS);
1130 boolean
1131 pred_name (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1133 const char *base;
1135 (void) stat_buf;
1136 base = base_name (pathname);
1138 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1139 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1141 if (fnmatch (pred_ptr->args.str, base, 0) == 0)
1142 return (true);
1143 return (false);
1146 boolean
1147 pred_negate (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1149 /* Check whether we need a stat here. */
1150 /* TODO: what about need_type? */
1151 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1152 return false;
1153 return (!(*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1154 pred_ptr->pred_right));
1157 boolean
1158 pred_newer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1160 (void) pathname;
1162 assert(COMP_GT == pred_ptr->args.reftime.kind);
1163 return compare_ts(get_stat_mtime(stat_buf), pred_ptr->args.reftime.ts) > 0;
1166 boolean
1167 pred_newerXY (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1169 struct timespec ts;
1171 assert(COMP_GT == pred_ptr->args.reftime.kind);
1173 switch (pred_ptr->args.reftime.xval)
1175 case XVAL_ATIME:
1176 ts = get_stat_atime(stat_buf);
1177 break;
1178 case XVAL_BIRTHTIME:
1179 assert(pred_ptr->args.reftime.xval != XVAL_BIRTHTIME); /* Unsupported. */
1180 assert(0);
1181 abort();
1182 break;
1183 case XVAL_CTIME:
1184 ts = get_stat_ctime(stat_buf);
1185 break;
1186 case XVAL_MTIME:
1187 ts = get_stat_mtime(stat_buf);
1188 break;
1189 case XVAL_TIME:
1190 assert(pred_ptr->args.reftime.xval != XVAL_TIME);
1191 abort();
1192 break;
1194 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
1197 boolean
1198 pred_nogroup (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1200 (void) pathname;
1201 (void) pred_ptr;
1203 #ifdef CACHE_IDS
1204 extern char *gid_unused;
1206 return gid_unused[(unsigned) stat_buf->st_gid];
1207 #else
1208 return getgrgid (stat_buf->st_gid) == NULL;
1209 #endif
1212 boolean
1213 pred_nouser (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1215 #ifdef CACHE_IDS
1216 extern char *uid_unused;
1217 #endif
1219 (void) pathname;
1220 (void) pred_ptr;
1222 #ifdef CACHE_IDS
1223 return uid_unused[(unsigned) stat_buf->st_uid];
1224 #else
1225 return getpwuid (stat_buf->st_uid) == NULL;
1226 #endif
1230 static boolean
1231 is_ok(const char *program, const char *arg)
1233 fflush (stdout);
1234 /* The draft open standard requires that, in the POSIX locale,
1235 the last non-blank character of this prompt be '?'.
1236 The exact format is not specified.
1237 This standard does not have requirements for locales other than POSIX
1239 /* XXX: printing UNTRUSTED data here. */
1240 fprintf (stderr, _("< %s ... %s > ? "), program, arg);
1241 fflush (stderr);
1242 return yesno();
1245 boolean
1246 pred_ok (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1248 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1249 return new_impl_pred_exec (pathname, stat_buf, pred_ptr, NULL, 0);
1250 else
1251 return false;
1254 boolean
1255 pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1257 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
1258 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1259 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr,
1260 prefix, (prefix ? 2 : 0));
1261 else
1262 return false;
1265 boolean
1266 pred_open (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1268 (void) pathname;
1269 (void) stat_buf;
1270 (void) pred_ptr;
1271 return true;
1274 boolean
1275 pred_or (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1277 if (pred_ptr->pred_left == NULL
1278 || !(*pred_ptr->pred_left->pred_func) (pathname, stat_buf,
1279 pred_ptr->pred_left))
1281 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0)
1282 return false;
1283 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf,
1284 pred_ptr->pred_right));
1286 else
1287 return true;
1290 boolean
1291 pred_path (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1293 (void) stat_buf;
1294 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
1295 return (true);
1296 return (false);
1299 boolean
1300 pred_perm (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1302 mode_t mode = stat_buf->st_mode;
1303 mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0];
1304 (void) pathname;
1305 switch (pred_ptr->args.perm.kind)
1307 case PERM_AT_LEAST:
1308 return (mode & perm_val) == perm_val;
1309 break;
1311 case PERM_ANY:
1312 /* True if any of the bits set in the mask are also set in the file's mode.
1315 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1316 * evaluate as true if at least all of the bits specified in
1317 * onum that are also set in the octal mask 07777 are set.
1319 * Eric Blake's interpretation is that the mode argument is zero,
1322 if (0 == perm_val)
1323 return true; /* Savannah bug 14748; we used to return false */
1324 else
1325 return (mode & perm_val) != 0;
1326 break;
1328 case PERM_EXACT:
1329 return (mode & MODE_ALL) == perm_val;
1330 break;
1332 default:
1333 abort ();
1334 break;
1339 boolean
1340 pred_executable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1342 (void) pathname;
1343 (void) stat_buf;
1344 (void) pred_ptr;
1346 return 0 == access(state.rel_pathname, X_OK);
1349 boolean
1350 pred_readable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1352 (void) pathname;
1353 (void) stat_buf;
1354 (void) pred_ptr;
1356 return 0 == access(state.rel_pathname, R_OK);
1359 boolean
1360 pred_writable (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1362 (void) pathname;
1363 (void) stat_buf;
1364 (void) pred_ptr;
1366 return 0 == access(state.rel_pathname, W_OK);
1369 boolean
1370 pred_print (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1372 (void) stat_buf;
1373 (void) pred_ptr;
1374 /* puts (pathname); */
1375 print_quoted(pred_ptr->args.printf_vec.stream,
1376 pred_ptr->args.printf_vec.quote_opts,
1377 pred_ptr->args.printf_vec.dest_is_tty,
1378 "%s\n", pathname);
1379 return true;
1382 boolean
1383 pred_print0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1385 (void) stat_buf;
1386 (void) pred_ptr;
1387 fputs (pathname, stdout);
1388 putc (0, stdout);
1389 return (true);
1392 boolean
1393 pred_prune (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1395 (void) pathname;
1396 (void) pred_ptr;
1398 if (options.do_dir_first == true &&
1399 stat_buf != NULL &&
1400 S_ISDIR(stat_buf->st_mode))
1401 state.stop_at_current_level = true;
1403 return (options.do_dir_first); /* This is what SunOS find seems to do. */
1406 boolean
1407 pred_quit (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1409 (void) pathname;
1410 (void) stat_buf;
1411 (void) pred_ptr;
1413 /* Run any cleanups. This includes executing any command lines
1414 * we have partly built but not executed.
1416 cleanup();
1418 /* Since -exec and friends don't leave child processes running in the
1419 * background, there is no need to wait for them here.
1421 exit(state.exit_status); /* 0 for success, etc. */
1424 boolean
1425 pred_regex (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1427 int len = strlen (pathname);
1428 (void) stat_buf;
1429 if (re_match (pred_ptr->args.regex, pathname, len, 0,
1430 (struct re_registers *) NULL) == len)
1431 return (true);
1432 return (false);
1435 boolean
1436 pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1438 uintmax_t f_val;
1440 (void) pathname;
1441 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
1442 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
1443 switch (pred_ptr->args.size.kind)
1445 case COMP_GT:
1446 if (f_val > pred_ptr->args.size.size)
1447 return (true);
1448 break;
1449 case COMP_LT:
1450 if (f_val < pred_ptr->args.size.size)
1451 return (true);
1452 break;
1453 case COMP_EQ:
1454 if (f_val == pred_ptr->args.size.size)
1455 return (true);
1456 break;
1458 return (false);
1461 boolean
1462 pred_samefile (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1464 /* Potential optimisation: because of the loop protection, we always
1465 * know the device of the current directory, hence the device number
1466 * of the file we're currently considering. If -L is not in effect,
1467 * and the device number of the file we're looking for is not the
1468 * same as the device number of the current directory, this
1469 * predicate cannot return true. Hence there would be no need to
1470 * stat the file we're looking at.
1472 (void) pathname;
1474 return stat_buf->st_ino == pred_ptr->args.fileid.ino
1475 && stat_buf->st_dev == pred_ptr->args.fileid.dev;
1478 boolean
1479 pred_true (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1481 (void) pathname;
1482 (void) stat_buf;
1483 (void) pred_ptr;
1484 return true;
1487 boolean
1488 pred_type (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1490 mode_t mode;
1491 mode_t type = pred_ptr->args.type;
1493 assert(state.have_type);
1494 assert(state.type != 0);
1496 (void) pathname;
1498 if (state.have_stat)
1499 mode = stat_buf->st_mode;
1500 else
1501 mode = state.type;
1503 #ifndef S_IFMT
1504 /* POSIX system; check `mode' the slow way. */
1505 if ((S_ISBLK (mode) && type == S_IFBLK)
1506 || (S_ISCHR (mode) && type == S_IFCHR)
1507 || (S_ISDIR (mode) && type == S_IFDIR)
1508 || (S_ISREG (mode) && type == S_IFREG)
1509 #ifdef S_IFLNK
1510 || (S_ISLNK (mode) && type == S_IFLNK)
1511 #endif
1512 #ifdef S_IFIFO
1513 || (S_ISFIFO (mode) && type == S_IFIFO)
1514 #endif
1515 #ifdef S_IFSOCK
1516 || (S_ISSOCK (mode) && type == S_IFSOCK)
1517 #endif
1518 #ifdef S_IFDOOR
1519 || (S_ISDOOR (mode) && type == S_IFDOOR)
1520 #endif
1522 #else /* S_IFMT */
1523 /* Unix system; check `mode' the fast way. */
1524 if ((mode & S_IFMT) == type)
1525 #endif /* S_IFMT */
1526 return (true);
1527 else
1528 return (false);
1531 boolean
1532 pred_uid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1534 (void) pathname;
1535 switch (pred_ptr->args.numinfo.kind)
1537 case COMP_GT:
1538 if (stat_buf->st_uid > pred_ptr->args.numinfo.l_val)
1539 return (true);
1540 break;
1541 case COMP_LT:
1542 if (stat_buf->st_uid < pred_ptr->args.numinfo.l_val)
1543 return (true);
1544 break;
1545 case COMP_EQ:
1546 if (stat_buf->st_uid == pred_ptr->args.numinfo.l_val)
1547 return (true);
1548 break;
1550 return (false);
1553 boolean
1554 pred_used (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1556 struct timespec delta, at, ct;
1558 (void) pathname;
1560 /* TODO: this needs to be retested carefully (manually, if necessary) */
1561 at = get_stat_atime(stat_buf);
1562 ct = get_stat_ctime(stat_buf);
1563 delta.tv_sec = at.tv_sec - ct.tv_sec;
1564 delta.tv_nsec = at.tv_nsec - ct.tv_nsec;
1565 if (delta.tv_nsec < 0)
1567 delta.tv_nsec += 1000000000;
1568 delta.tv_sec -= 1;
1570 return pred_timewindow(delta, pred_ptr, DAYSECS);
1573 boolean
1574 pred_user (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1576 (void) pathname;
1577 if (pred_ptr->args.uid == stat_buf->st_uid)
1578 return (true);
1579 else
1580 return (false);
1583 boolean
1584 pred_xtype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1586 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
1587 int (*ystat) (const char*, struct stat *p);
1589 /* If we would normally stat the link itself, stat the target instead.
1590 * If we would normally follow the link, stat the link itself instead.
1592 if (following_links())
1593 ystat = optionp_stat;
1594 else
1595 ystat = optionl_stat;
1597 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
1599 if (following_links() && errno == ENOENT)
1601 /* If we failed to follow the symlink,
1602 * fall back on looking at the symlink itself.
1604 /* Mimic behavior of ls -lL. */
1605 return (pred_type (pathname, stat_buf, pred_ptr));
1607 else
1609 error (0, errno, "%s", pathname);
1610 state.exit_status = 1;
1612 return false;
1614 /* Now that we have our stat() information, query it in the same
1615 * way that -type does.
1617 return (pred_type (pathname, &sbuf, pred_ptr));
1620 /* 1) fork to get a child; parent remembers the child pid
1621 2) child execs the command requested
1622 3) parent waits for child; checks for proper pid of child
1624 Possible returns:
1626 ret errno status(h) status(l)
1628 pid x signal# 0177 stopped
1629 pid x exit arg 0 term by _exit
1630 pid x 0 signal # term by signal
1631 -1 EINTR parent got signal
1632 -1 other some other kind of error
1634 Return true only if the pid matches, status(l) is
1635 zero, and the exit arg (status high) is 0.
1636 Otherwise return false, possibly printing an error message. */
1639 static void
1640 prep_child_for_exec (boolean close_stdin)
1642 if (close_stdin)
1644 const char inputfile[] = "/dev/null";
1645 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1647 close(0);
1648 if (open(inputfile, O_RDONLY) < 0)
1650 /* This is not entirely fatal, since
1651 * executing the child with a closed
1652 * stdin is almost as good as executing it
1653 * with its stdin attached to /dev/null.
1655 error (0, errno, "%s", inputfile);
1663 launch (const struct buildcmd_control *ctl,
1664 struct buildcmd_state *buildstate)
1666 int wait_status;
1667 pid_t child_pid;
1668 static int first_time = 1;
1669 const struct exec_val *execp = buildstate->usercontext;
1671 /* Null terminate the arg list. */
1672 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false);
1674 /* Make sure output of command doesn't get mixed with find output. */
1675 fflush (stdout);
1676 fflush (stderr);
1678 /* Make sure to listen for the kids. */
1679 if (first_time)
1681 first_time = 0;
1682 signal (SIGCHLD, SIG_DFL);
1685 child_pid = fork ();
1686 if (child_pid == -1)
1687 error (1, errno, _("cannot fork"));
1688 if (child_pid == 0)
1690 /* We be the child. */
1691 prep_child_for_exec(execp->close_stdin);
1693 /* For -exec and -ok, change directory back to the starting directory.
1694 * for -execdir and -okdir, stay in the directory we are searching
1695 * (the latter is more secure).
1697 if (!execp->use_current_dir)
1699 /* Even if DebugSearch is set, don't announce our change of
1700 * directory, since we're not going to emit a subsequent
1701 * announcement of a call to stat() anyway, as we're about
1702 * to exec something.
1704 if (starting_desc < 0
1705 ? chdir (starting_dir) != 0
1706 : fchdir (starting_desc) != 0)
1708 error (0, errno, "%s", starting_dir);
1709 _exit (1);
1713 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv);
1714 error (0, errno, "%s", buildstate->cmd_argv[0]);
1715 _exit (1);
1719 /* In parent; set up for next time. */
1720 bc_clear_args(ctl, buildstate);
1723 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1)
1725 if (errno != EINTR)
1727 error (0, errno, _("error waiting for %s"), buildstate->cmd_argv[0]);
1728 state.exit_status = 1;
1729 return 0; /* FAIL */
1733 if (WIFSIGNALED (wait_status))
1735 error (0, 0, _("%s terminated by signal %d"),
1736 buildstate->cmd_argv[0], WTERMSIG (wait_status));
1738 if (execp->multiple)
1740 /* -exec \; just returns false if the invoked command fails.
1741 * -exec {} + returns true if the invoked command fails, but
1742 * sets the program exit status.
1744 state.exit_status = 1;
1747 return 1; /* OK */
1750 if (0 == WEXITSTATUS (wait_status))
1752 return 1; /* OK */
1754 else
1756 if (execp->multiple)
1758 /* -exec \; just returns false if the invoked command fails.
1759 * -exec {} + returns true if the invoked command fails, but
1760 * sets the program exit status.
1762 state.exit_status = 1;
1764 return 0; /* FAIL */
1770 /* Return a static string formatting the time WHEN according to the
1771 * strftime format character KIND.
1773 * This function contains a number of assertions. These look like
1774 * runtime checks of the results of computations, which would be a
1775 * problem since external events should not be tested for with
1776 * "assert" (instead you should use "if"). However, they are not
1777 * really runtime checks. The assertions actually exist to verify
1778 * that the various buffers are correctly sized.
1780 static char *
1781 format_date (struct timespec ts, int kind)
1783 /* Use an extra 10 characters for 9 digits of nanoseconds and 1 for
1784 * the decimal point
1786 enum {
1787 NS_BUF_LEN = 12,
1788 DATE_LEN_PERCENT_APLUS=21 /* length of result of %A+ (it's longer than %c)*/
1790 static char buf[10u + MAX(DATE_LEN_PERCENT_APLUS, MAX (LONGEST_HUMAN_READABLE + 2, 64))];
1791 char ns_buf[NS_BUF_LEN]; /* .9999999990 */
1792 int charsprinted, need_ns_suffix;
1793 struct tm *tm;
1794 char fmt[6];
1796 /* human_readable() assumes we pass a buffer which is at least as
1797 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
1798 * ensure that no nasty unsigned overflow happend in our calculation
1799 * of the size of buf. Do the assertion here rather than in the
1800 * code for %@ so that we find the problem quickly if it exists. If
1801 * you want to submit a patch to move this into the if statement, go
1802 * ahead, I'll apply it. But include performance timings
1803 * demonstrating that the performance difference is actually
1804 * measurable.
1806 assert(sizeof(buf) >= LONGEST_HUMAN_READABLE);
1808 /* Format the main part of the time. */
1809 if (kind == '+')
1811 strcpy (fmt, "%F+%T");
1812 need_ns_suffix = 1;
1814 else
1816 fmt[0] = '%';
1817 fmt[1] = kind;
1818 fmt[2] = '\0';
1820 /* %a, %c, and %t are handled in ctime_format() */
1821 switch (kind)
1823 case 'S':
1824 case 'T':
1825 case 'X':
1826 need_ns_suffix = 1;
1827 break;
1828 default:
1829 need_ns_suffix = 0;
1830 break;
1834 if (need_ns_suffix)
1836 /* Format the nanoseconds part. Leave a trailing zero to discourage people from
1837 * writing scripts which extract the fractional part of the timestamp by using
1838 * column offsets. The reason for discouraging this is that in the future, the
1839 * granularity may not be nanoseconds.
1841 charsprinted = snprintf(ns_buf, NS_BUF_LEN, ".%09ld0", (long int)ts.tv_nsec);
1842 assert(charsprinted < NS_BUF_LEN);
1845 if (kind != '@'
1846 && (tm = localtime (&ts.tv_sec))
1847 && strftime (buf, sizeof buf, fmt, tm))
1849 /* For %AS, %CS, %TS, add the fractional part of the seconds information. */
1850 if (need_ns_suffix)
1852 assert((sizeof buf - strlen(buf)) > strlen(ns_buf));
1853 strcat(buf, ns_buf);
1855 return buf;
1857 else
1859 uintmax_t w = ts.tv_sec;
1860 size_t used, len, remaining;
1862 /* XXX: note that we are negating an unsigned type which is the
1863 * widest possible unsigned type.
1865 char *p = human_readable (ts.tv_sec < 0 ? -w : w, buf + 1,
1866 human_ceiling, 1, 1);
1867 assert(p > buf);
1868 assert(p < (buf + (sizeof buf)));
1869 if (ts.tv_sec < 0)
1870 *--p = '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
1872 /* Add the nanoseconds part. Because we cannot enforce a particlar implementation
1873 * of human_readable, we cannot assume any particular value for (p-buf). So we
1874 * need to be careful that there is enough space remaining in the buffer.
1876 len = strlen(p);
1877 used = (p-buf) + len; /* Offset into buf of current end */
1878 assert(sizeof buf > used); /* Ensure we can perform subtraction safely. */
1879 remaining = sizeof buf - used - 1u; /* allow space for NUL */
1880 assert(strlen(ns_buf) < remaining);
1881 strcat(p, ns_buf);
1882 return p;
1886 static const char *weekdays[] =
1888 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1890 static char * months[] =
1892 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1893 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1897 static char *
1898 ctime_format (struct timespec ts)
1900 const struct tm * ptm;
1901 #define TIME_BUF_LEN 1024u
1902 static char resultbuf[TIME_BUF_LEN];
1903 int nout;
1905 ptm = localtime(&ts.tv_sec);
1906 if (ptm)
1908 assert(ptm->tm_wday >= 0);
1909 assert(ptm->tm_wday < 7);
1910 assert(ptm->tm_mon >= 0);
1911 assert(ptm->tm_mon < 12);
1912 assert(ptm->tm_hour >= 0);
1913 assert(ptm->tm_hour < 24);
1914 assert(ptm->tm_min < 60);
1915 assert(ptm->tm_sec <= 61); /* allows 2 leap seconds. */
1917 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
1918 nout = snprintf(resultbuf, TIME_BUF_LEN,
1919 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
1920 weekdays[ptm->tm_wday],
1921 months[ptm->tm_mon],
1922 ptm->tm_mday,
1923 ptm->tm_hour,
1924 ptm->tm_min,
1925 ptm->tm_sec,
1926 (long int)ts.tv_nsec,
1927 1900 + ptm->tm_year);
1929 assert(nout < TIME_BUF_LEN);
1930 return resultbuf;
1932 else
1934 /* The time cannot be represented as a struct tm.
1935 Output it as an integer. */
1936 return format_date (ts, '@');
1940 /* Copy STR into BUF and trim blanks from the end of BUF.
1941 Return BUF. */
1943 static char *
1944 blank_rtrim (str, buf)
1945 char *str;
1946 char *buf;
1948 int i;
1950 if (str == NULL)
1951 return (NULL);
1952 strcpy (buf, str);
1953 i = strlen (buf) - 1;
1954 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
1955 i--;
1956 buf[++i] = '\0';
1957 return (buf);
1960 /* Print out the predicate list starting at NODE. */
1961 void
1962 print_list (FILE *fp, struct predicate *node)
1964 struct predicate *cur;
1965 char name[256];
1967 cur = node;
1968 while (cur != NULL)
1970 fprintf (fp, "%s ", blank_rtrim (cur->p_name, name));
1971 cur = cur->pred_next;
1973 fprintf (fp, "\n");
1976 /* Print out the predicate list starting at NODE. */
1977 static void
1978 print_parenthesised(FILE *fp, struct predicate *node)
1980 int parens = 0;
1982 if (node)
1984 if ( ( (node->pred_func == pred_or)
1985 || (node->pred_func == pred_and) )
1986 && node->pred_left == NULL)
1988 /* We print "<nothing> or X" as just "X"
1989 * We print "<nothing> and X" as just "X"
1991 print_parenthesised(fp, node->pred_right);
1993 else
1995 if (node->pred_left || node->pred_right)
1996 parens = 1;
1998 if (parens)
1999 fprintf(fp, "%s", " ( ");
2000 print_optlist(fp, node);
2001 if (parens)
2002 fprintf(fp, "%s", " ) ");
2007 void
2008 print_optlist (FILE *fp, const struct predicate *p)
2010 if (p)
2012 print_parenthesised(fp, p->pred_left);
2013 fprintf (fp,
2014 "%s%s",
2015 p->need_stat ? "[call stat] " : "",
2016 p->need_type ? "[need type] " : "");
2017 print_predicate(fp, p);
2018 fprintf(fp, " [%g] ", p->est_success_rate);
2019 print_parenthesised(fp, p->pred_right);
2023 #ifdef _NDEBUG
2024 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2025 * there is no point in having a function body for pred_sanity_check()
2026 * if that preprocessor macro is defined.
2028 void
2029 pred_sanity_check(const struct predicate *predicates)
2031 /* Do nothing, since assert() is a no-op with _NDEBUG set */
2032 return;
2034 #else
2035 void
2036 pred_sanity_check(const struct predicate *predicates)
2038 const struct predicate *p;
2040 for (p=predicates; p != NULL; p=p->pred_next)
2042 /* All predicates must do something. */
2043 assert(p->pred_func != NULL);
2045 /* All predicates must have a parser table entry. */
2046 assert(p->parser_entry != NULL);
2048 /* If the parser table tells us that just one predicate function is
2049 * possible, verify that that is still the one that is in effect.
2050 * If the parser has NULL for the predicate function, that means that
2051 * the parse_xxx function fills it in, so we can't check it.
2053 if (p->parser_entry->pred_func)
2055 assert(p->parser_entry->pred_func == p->pred_func);
2058 switch (p->parser_entry->type)
2060 /* Options all take effect during parsing, so there should
2061 * be no predicate entries corresponding to them. Hence we
2062 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2063 * items.
2065 * This is a silly way of coding this test, but it prevents
2066 * a compiler warning (i.e. otherwise it would think that
2067 * there would be case statements missing).
2069 case ARG_OPTION:
2070 case ARG_POSITIONAL_OPTION:
2071 assert(p->parser_entry->type != ARG_OPTION);
2072 assert(p->parser_entry->type != ARG_POSITIONAL_OPTION);
2073 break;
2075 case ARG_ACTION:
2076 assert(p->side_effects); /* actions have side effects. */
2077 if (p->pred_func != pred_prune && p->pred_func != pred_quit)
2079 /* actions other than -prune and -quit should
2080 * inhibit the default -print
2082 assert(p->no_default_print);
2084 break;
2086 case ARG_PUNCTUATION:
2087 case ARG_TEST:
2088 case ARG_NOOP:
2089 /* Punctuation and tests should have no side
2090 * effects and not inhibit default print.
2092 assert(!p->no_default_print);
2093 assert(!p->side_effects);
2094 break;
2098 #endif