Bugfixes for Savannah bugs #19768 and #19766
[findutils.git] / find / pred.c
blobe8c6e969c01c2186c956bcad7de96d1863a7430c
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 <openat.h>
34 #include "xalloc.h"
35 #include "dirname.h"
36 #include "human.h"
37 #include "modetype.h"
38 #include "filemode.h"
39 #include "wait.h"
40 #include "printquoted.h"
41 #include "buildcmd.h"
42 #include "yesno.h"
43 #include "listfile.h"
44 #include "stat-time.h"
45 #include "dircallback.h"
46 #include "error.h"
48 #if ENABLE_NLS
49 # include <libintl.h>
50 # define _(Text) gettext (Text)
51 #else
52 # define _(Text) Text
53 #endif
54 #ifdef gettext_noop
55 # define N_(String) gettext_noop (String)
56 #else
57 /* See locate.c for explanation as to why not use (String) */
58 # define N_(String) String
59 #endif
61 #if !defined(SIGCHLD) && defined(SIGCLD)
62 #define SIGCHLD SIGCLD
63 #endif
67 #if HAVE_DIRENT_H
68 # include <dirent.h>
69 # define NAMLEN(dirent) strlen((dirent)->d_name)
70 #else
71 # define dirent direct
72 # define NAMLEN(dirent) (dirent)->d_namlen
73 # if HAVE_SYS_NDIR_H
74 # include <sys/ndir.h>
75 # endif
76 # if HAVE_SYS_DIR_H
77 # include <sys/dir.h>
78 # endif
79 # if HAVE_NDIR_H
80 # include <ndir.h>
81 # endif
82 #endif
84 #ifdef CLOSEDIR_VOID
85 /* Fake a return value. */
86 #define CLOSEDIR(d) (closedir (d), 0)
87 #else
88 #define CLOSEDIR(d) closedir (d)
89 #endif
94 /* Get or fake the disk device blocksize.
95 Usually defined by sys/param.h (if at all). */
96 #ifndef DEV_BSIZE
97 # ifdef BSIZE
98 # define DEV_BSIZE BSIZE
99 # else /* !BSIZE */
100 # define DEV_BSIZE 4096
101 # endif /* !BSIZE */
102 #endif /* !DEV_BSIZE */
104 /* Extract or fake data from a `struct stat'.
105 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
106 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
107 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
108 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
109 # define ST_BLKSIZE(statbuf) DEV_BSIZE
110 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
111 # define ST_NBLOCKS(statbuf) \
112 (S_ISREG ((statbuf).st_mode) \
113 || S_ISDIR ((statbuf).st_mode) \
114 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
115 # else /* !_POSIX_SOURCE && BSIZE */
116 # define ST_NBLOCKS(statbuf) \
117 (S_ISREG ((statbuf).st_mode) \
118 || S_ISDIR ((statbuf).st_mode) \
119 ? st_blocks ((statbuf).st_size) : 0)
120 # endif /* !_POSIX_SOURCE && BSIZE */
121 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
122 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
123 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
124 ? (statbuf).st_blksize : DEV_BSIZE)
125 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
126 /* HP-UX counts st_blocks in 1024-byte units.
127 This loses when mixing HP-UX and BSD filesystems with NFS. */
128 # define ST_NBLOCKSIZE 1024
129 # else /* !hpux */
130 # if defined(_AIX) && defined(_I386)
131 /* AIX PS/2 counts st_blocks in 4K units. */
132 # define ST_NBLOCKSIZE (4 * 1024)
133 # else /* not AIX PS/2 */
134 # if defined(_CRAY)
135 # define ST_NBLOCKS(statbuf) \
136 (S_ISREG ((statbuf).st_mode) \
137 || S_ISDIR ((statbuf).st_mode) \
138 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
139 # endif /* _CRAY */
140 # endif /* not AIX PS/2 */
141 # endif /* !hpux */
142 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
144 #ifndef ST_NBLOCKS
145 # define ST_NBLOCKS(statbuf) \
146 (S_ISREG ((statbuf).st_mode) \
147 || S_ISDIR ((statbuf).st_mode) \
148 ? (statbuf).st_blocks : 0)
149 #endif
151 #ifndef ST_NBLOCKSIZE
152 # define ST_NBLOCKSIZE 512
153 #endif
156 #undef MAX
157 #define MAX(a, b) ((a) > (b) ? (a) : (b))
159 static boolean match_lname PARAMS((const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case));
161 static char *format_date PARAMS((struct timespec ts, int kind));
162 static char *ctime_format PARAMS((struct timespec ts));
164 #ifdef DEBUG
165 struct pred_assoc
167 PRED_FUNC pred_func;
168 char *pred_name;
171 struct pred_assoc pred_table[] =
173 {pred_amin, "amin "},
174 {pred_and, "and "},
175 {pred_anewer, "anewer "},
176 {pred_atime, "atime "},
177 {pred_closeparen, ") "},
178 {pred_cmin, "cmin "},
179 {pred_cnewer, "cnewer "},
180 {pred_comma, ", "},
181 {pred_ctime, "ctime "},
182 {pred_delete, "delete "},
183 {pred_empty, "empty "},
184 {pred_exec, "exec "},
185 {pred_execdir, "execdir "},
186 {pred_executable, "executable "},
187 {pred_false, "false "},
188 {pred_fprint, "fprint "},
189 {pred_fprint0, "fprint0 "},
190 {pred_fprintf, "fprintf "},
191 {pred_fstype, "fstype "},
192 {pred_gid, "gid "},
193 {pred_group, "group "},
194 {pred_ilname, "ilname "},
195 {pred_iname, "iname "},
196 {pred_inum, "inum "},
197 {pred_ipath, "ipath "},
198 {pred_links, "links "},
199 {pred_lname, "lname "},
200 {pred_ls, "ls "},
201 {pred_mmin, "mmin "},
202 {pred_mtime, "mtime "},
203 {pred_name, "name "},
204 {pred_negate, "not "},
205 {pred_newer, "newer "},
206 {pred_newerXY, "newerXY "},
207 {pred_nogroup, "nogroup "},
208 {pred_nouser, "nouser "},
209 {pred_ok, "ok "},
210 {pred_okdir, "okdir "},
211 {pred_openparen, "( "},
212 {pred_or, "or "},
213 {pred_path, "path "},
214 {pred_perm, "perm "},
215 {pred_print, "print "},
216 {pred_print0, "print0 "},
217 {pred_prune, "prune "},
218 {pred_quit, "quit "},
219 {pred_readable, "readable "},
220 {pred_regex, "regex "},
221 {pred_samefile,"samefile "},
222 {pred_size, "size "},
223 {pred_true, "true "},
224 {pred_type, "type "},
225 {pred_uid, "uid "},
226 {pred_used, "used "},
227 {pred_user, "user "},
228 {pred_writable, "writable "},
229 {pred_xtype, "xtype "},
230 {0, "none "}
232 #endif
234 /* Returns ts1 - ts2 */
235 static double ts_difference(struct timespec ts1,
236 struct timespec ts2)
238 double d = difftime(ts1.tv_sec, ts2.tv_sec)
239 + (1.0e-9 * (ts1.tv_nsec - ts2.tv_nsec));
240 return d;
244 static int
245 compare_ts(struct timespec ts1,
246 struct timespec ts2)
248 if ((ts1.tv_sec == ts2.tv_sec) &&
249 (ts1.tv_nsec == ts2.tv_nsec))
251 return 0;
253 else
255 double diff = ts_difference(ts1, ts2);
256 return diff < 0.0 ? -1 : +1;
260 /* Predicate processing routines.
262 PATHNAME is the full pathname of the file being checked.
263 *STAT_BUF contains information about PATHNAME.
264 *PRED_PTR contains information for applying the predicate.
266 Return true if the file passes this predicate, false if not. */
269 /* pred_timewindow
271 * Returns true if THE_TIME is
272 * COMP_GT: after the specified time
273 * COMP_LT: before the specified time
274 * COMP_EQ: less than WINDOW seconds after the specified time.
276 static boolean
277 pred_timewindow(struct timespec ts, struct predicate const *pred_ptr, int window)
279 switch (pred_ptr->args.reftime.kind)
281 case COMP_GT:
282 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
284 case COMP_LT:
285 return compare_ts(ts, pred_ptr->args.reftime.ts) < 0;
287 case COMP_EQ:
289 double delta = ts_difference(ts, pred_ptr->args.reftime.ts);
290 return (delta >= 0.0 && delta < window);
296 boolean
297 pred_amin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
299 (void) &pathname;
300 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, 60);
303 boolean
304 pred_and (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
306 if (pred_ptr->pred_left == NULL
307 || apply_predicate(pathname, stat_buf, pred_ptr->pred_left))
309 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
311 else
312 return false;
315 boolean
316 pred_anewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
318 (void) &pathname;
319 assert(COMP_GT == pred_ptr->args.reftime.kind);
320 return compare_ts(get_stat_atime(stat_buf), pred_ptr->args.reftime.ts) > 0;
323 boolean
324 pred_atime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
326 (void) &pathname;
327 return pred_timewindow(get_stat_atime(stat_buf), pred_ptr, DAYSECS);
330 boolean
331 pred_closeparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
333 (void) &pathname;
334 (void) &stat_buf;
335 (void) &pred_ptr;
337 return true;
340 boolean
341 pred_cmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
343 (void) pathname;
344 return pred_timewindow(get_stat_ctime(stat_buf), pred_ptr, 60);
347 boolean
348 pred_cnewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
350 (void) pathname;
352 assert(COMP_GT == pred_ptr->args.reftime.kind);
353 return compare_ts(get_stat_ctime(stat_buf), pred_ptr->args.reftime.ts) > 0;
356 boolean
357 pred_comma (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
359 if (pred_ptr->pred_left != NULL)
361 apply_predicate(pathname, stat_buf,pred_ptr->pred_left);
363 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
366 boolean
367 pred_ctime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
369 (void) &pathname;
370 return pred_timewindow(get_stat_ctime(stat_buf), pred_ptr, DAYSECS);
373 static boolean
374 perform_delete(int flags)
376 return 0 == unlinkat(state.cwd_dir_fd, state.rel_pathname, flags);
380 boolean
381 pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
383 (void) pred_ptr;
384 (void) stat_buf;
385 if (strcmp (state.rel_pathname, "."))
387 int flags=0;
388 if (state.have_stat && S_ISDIR(stat_buf->st_mode))
389 flags |= AT_REMOVEDIR;
390 if (perform_delete(flags))
392 return true;
394 else
396 if (EISDIR == errno)
398 if ((flags & AT_REMOVEDIR) == 0)
400 /* unlink() operation failed because we should have done rmdir(). */
401 flags |= AT_REMOVEDIR;
402 if (perform_delete(flags))
403 return true;
407 error (0, errno, "cannot delete %s",
408 safely_quote_err_filename(0, pathname));
409 return false;
411 else
413 /* nothing to do. */
414 return true;
418 boolean
419 pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
421 (void) pathname;
422 (void) pred_ptr;
424 if (S_ISDIR (stat_buf->st_mode))
426 int fd;
427 DIR *d;
428 struct dirent *dp;
429 boolean empty = true;
431 errno = 0;
432 if ((fd = openat(state.cwd_dir_fd, state.rel_pathname, O_RDONLY
433 #if defined O_LARGEFILE
434 |O_LARGEFILE
435 #endif
436 )) < 0)
438 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
439 state.exit_status = 1;
440 return false;
442 d = fdopendir (fd);
443 if (d == NULL)
445 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
446 state.exit_status = 1;
447 return false;
449 for (dp = readdir (d); dp; dp = readdir (d))
451 if (dp->d_name[0] != '.'
452 || (dp->d_name[1] != '\0'
453 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
455 empty = false;
456 break;
459 if (CLOSEDIR (d))
461 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
462 state.exit_status = 1;
463 return false;
465 return (empty);
467 else if (S_ISREG (stat_buf->st_mode))
468 return (stat_buf->st_size == 0);
469 else
470 return (false);
473 static boolean
474 new_impl_pred_exec (int dirfd, const char *pathname,
475 struct stat *stat_buf,
476 struct predicate *pred_ptr,
477 const char *prefix, size_t pfxlen)
479 struct exec_val *execp = &pred_ptr->args.exec_vec;
480 size_t len = strlen(pathname);
482 (void) stat_buf;
483 execp->dirfd = dirfd;
484 if (execp->multiple)
486 /* Push the argument onto the current list.
487 * The command may or may not be run at this point,
488 * depending on the command line length limits.
490 bc_push_arg(&execp->ctl,
491 &execp->state,
492 pathname, len+1,
493 prefix, pfxlen,
496 /* remember that there are pending execdirs. */
497 state.execdirs_outstanding = true;
499 /* POSIX: If the primary expression is punctuated by a plus
500 * sign, the primary shall always evaluate as true
502 return true;
504 else
506 int i;
508 for (i=0; i<execp->num_args; ++i)
510 bc_do_insert(&execp->ctl,
511 &execp->state,
512 execp->replace_vec[i],
513 strlen(execp->replace_vec[i]),
514 prefix, pfxlen,
515 pathname, len,
519 /* Actually invoke the command. */
520 return execp->ctl.exec_callback(&execp->ctl,
521 &execp->state);
526 boolean
527 pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
529 return new_impl_pred_exec(get_start_dirfd(),
530 pathname, stat_buf, pred_ptr, NULL, 0);
533 boolean
534 pred_execdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
536 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
537 (void) &pathname;
538 return new_impl_pred_exec (get_current_dirfd(),
539 state.rel_pathname, stat_buf, pred_ptr,
540 prefix, (prefix ? 2 : 0));
543 boolean
544 pred_false (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
546 (void) &pathname;
547 (void) &stat_buf;
548 (void) &pred_ptr;
551 return (false);
554 boolean
555 pred_fls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
557 list_file (pathname, state.cwd_dir_fd, state.rel_pathname, stat_buf, options.start_time.tv_sec,
558 options.output_block_size,
559 pred_ptr->literal_control_chars, pred_ptr->args.stream);
560 return true;
563 boolean
564 pred_fprint (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
566 (void) &pathname;
567 (void) &stat_buf;
569 print_quoted(pred_ptr->args.printf_vec.stream,
570 pred_ptr->args.printf_vec.quote_opts,
571 pred_ptr->args.printf_vec.dest_is_tty,
572 "%s\n",
573 pathname);
574 return true;
577 boolean
578 pred_fprint0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
580 (void) &pathname;
581 (void) &stat_buf;
583 fputs (pathname, pred_ptr->args.stream);
584 putc (0, pred_ptr->args.stream);
585 return (true);
590 static char*
591 mode_to_filetype(mode_t m)
593 return
594 m == S_IFSOCK ? "s" :
595 m == S_IFLNK ? "l" :
596 m == S_IFREG ? "f" :
597 m == S_IFBLK ? "b" :
598 m == S_IFDIR ? "d" :
599 m == S_IFCHR ? "c" :
600 #ifdef S_IFDOOR
601 m == S_IFDOOR ? "D" :
602 #endif
603 m == S_IFIFO ? "p" : "U";
606 static double
607 file_sparseness(const struct stat *p)
609 if (0 == p->st_size)
611 if (0 == p->st_blocks)
612 return 1.0;
613 else
614 return p->st_blocks < 0 ? -HUGE_VAL : HUGE_VAL;
616 else
618 double blklen = file_blocksize(p) * (double)p->st_blocks;
619 return blklen / p->st_size;
625 static boolean
626 do_fprintf(FILE *fp,
627 struct segment *segment,
628 const char *pathname,
629 const struct stat *stat_buf,
630 boolean ttyflag,
631 const struct quoting_options *qopts)
633 char hbuf[LONGEST_HUMAN_READABLE + 1];
634 const char *cp;
636 switch (segment->segkind)
638 case KIND_PLAIN: /* Plain text string (no % conversion). */
639 /* trusted */
640 fwrite (segment->text, 1, segment->text_len, fp);
641 break;
643 case KIND_STOP: /* Terminate argument and flush output. */
644 /* trusted */
645 fwrite (segment->text, 1, segment->text_len, fp);
646 fflush (fp);
647 return (true);
649 case KIND_FORMAT:
650 switch (segment->format_char[0])
652 case 'a': /* atime in `ctime' format. */
653 /* UNTRUSTED, probably unexploitable */
654 fprintf (fp, segment->text, ctime_format (get_stat_atime(stat_buf)));
655 break;
656 case 'b': /* size in 512-byte blocks */
657 /* UNTRUSTED, probably unexploitable */
658 fprintf (fp, segment->text,
659 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
660 hbuf, human_ceiling,
661 ST_NBLOCKSIZE, 512));
662 break;
663 case 'c': /* ctime in `ctime' format */
664 /* UNTRUSTED, probably unexploitable */
665 fprintf (fp, segment->text, ctime_format (get_stat_ctime(stat_buf)));
666 break;
667 case 'd': /* depth in search tree */
668 /* UNTRUSTED, probably unexploitable */
669 fprintf (fp, segment->text, state.curdepth);
670 break;
671 case 'D': /* Device on which file exists (stat.st_dev) */
672 /* trusted */
673 fprintf (fp, segment->text,
674 human_readable ((uintmax_t) stat_buf->st_dev, hbuf,
675 human_ceiling, 1, 1));
676 break;
677 case 'f': /* base name of path */
678 /* sanitised */
679 print_quoted (fp, qopts, ttyflag, segment->text, base_name (pathname));
680 break;
681 case 'F': /* filesystem type */
682 /* trusted */
683 print_quoted (fp, qopts, ttyflag, segment->text, filesystem_type (stat_buf, pathname));
684 break;
685 case 'g': /* group name */
686 /* trusted */
687 /* (well, the actual group is selected by the user but
688 * its name was selected by the system administrator)
691 struct group *g;
693 g = getgrgid (stat_buf->st_gid);
694 if (g)
696 segment->text[segment->text_len] = 's';
697 fprintf (fp, segment->text, g->gr_name);
698 break;
700 else
702 /* Do nothing. */
703 /*FALLTHROUGH*/
706 case 'G': /* GID number */
707 /* UNTRUSTED, probably unexploitable */
708 fprintf (fp, segment->text,
709 human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
710 human_ceiling, 1, 1));
711 break;
712 case 'h': /* leading directories part of path */
713 /* sanitised */
715 cp = strrchr (pathname, '/');
716 if (cp == NULL) /* No leading directories. */
718 /* If there is no slash in the pathname, we still
719 * print the string because it contains characters
720 * other than just '%s'. The %h expands to ".".
722 print_quoted (fp, qopts, ttyflag, segment->text, ".");
724 else
726 char *s = strdup(pathname);
727 s[cp - pathname] = 0;
728 print_quoted (fp, qopts, ttyflag, segment->text, s);
729 free(s);
731 break;
733 case 'H': /* ARGV element file was found under */
734 /* trusted */
736 char *s = xmalloc(state.starting_path_length+1);
737 memcpy(s, pathname, state.starting_path_length);
738 s[state.starting_path_length] = 0;
739 fprintf (fp, segment->text, s);
740 free(s);
741 break;
743 case 'i': /* inode number */
744 /* UNTRUSTED, but not exploitable I think */
745 fprintf (fp, segment->text,
746 human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
747 human_ceiling,
748 1, 1));
749 break;
750 case 'k': /* size in 1K blocks */
751 /* UNTRUSTED, but not exploitable I think */
752 fprintf (fp, segment->text,
753 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
754 hbuf, human_ceiling,
755 ST_NBLOCKSIZE, 1024));
756 break;
757 case 'l': /* object of symlink */
758 /* sanitised */
759 #ifdef S_ISLNK
761 char *linkname = 0;
763 if (S_ISLNK (stat_buf->st_mode))
765 linkname = get_link_name_at (pathname, state.cwd_dir_fd, state.rel_pathname);
766 if (linkname == 0)
767 state.exit_status = 1;
769 if (linkname)
771 print_quoted (fp, qopts, ttyflag, segment->text, linkname);
772 free (linkname);
774 else
776 /* We still need to honour the field width etc., so this is
777 * not a no-op.
779 print_quoted (fp, qopts, ttyflag, segment->text, "");
782 #endif /* S_ISLNK */
783 break;
785 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
786 /* UNTRUSTED, probably unexploitable */
788 char modestring[16] ;
789 filemodestring (stat_buf, modestring);
790 modestring[10] = '\0';
791 fprintf (fp, segment->text, modestring);
793 break;
795 case 'm': /* mode as octal number (perms only) */
796 /* UNTRUSTED, probably unexploitable */
798 /* Output the mode portably using the traditional numbers,
799 even if the host unwisely uses some other numbering
800 scheme. But help the compiler in the common case where
801 the host uses the traditional numbering scheme. */
802 mode_t m = stat_buf->st_mode;
803 boolean traditional_numbering_scheme =
804 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
805 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
806 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
807 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
808 fprintf (fp, segment->text,
809 (traditional_numbering_scheme
810 ? m & MODE_ALL
811 : ((m & S_ISUID ? 04000 : 0)
812 | (m & S_ISGID ? 02000 : 0)
813 | (m & S_ISVTX ? 01000 : 0)
814 | (m & S_IRUSR ? 00400 : 0)
815 | (m & S_IWUSR ? 00200 : 0)
816 | (m & S_IXUSR ? 00100 : 0)
817 | (m & S_IRGRP ? 00040 : 0)
818 | (m & S_IWGRP ? 00020 : 0)
819 | (m & S_IXGRP ? 00010 : 0)
820 | (m & S_IROTH ? 00004 : 0)
821 | (m & S_IWOTH ? 00002 : 0)
822 | (m & S_IXOTH ? 00001 : 0))));
824 break;
826 case 'n': /* number of links */
827 /* UNTRUSTED, probably unexploitable */
828 fprintf (fp, segment->text,
829 human_readable ((uintmax_t) stat_buf->st_nlink,
830 hbuf,
831 human_ceiling,
832 1, 1));
833 break;
834 case 'p': /* pathname */
835 /* sanitised */
836 print_quoted (fp, qopts, ttyflag, segment->text, pathname);
837 break;
838 case 'P': /* pathname with ARGV element stripped */
839 /* sanitised */
840 if (state.curdepth > 0)
842 cp = pathname + state.starting_path_length;
843 if (*cp == '/')
844 /* Move past the slash between the ARGV element
845 and the rest of the pathname. But if the ARGV element
846 ends in a slash, we didn't add another, so we've
847 already skipped past it. */
848 cp++;
850 else
851 cp = "";
852 print_quoted (fp, qopts, ttyflag, segment->text, cp);
853 break;
854 case 's': /* size in bytes */
855 /* UNTRUSTED, probably unexploitable */
856 fprintf (fp, segment->text,
857 human_readable ((uintmax_t) stat_buf->st_size,
858 hbuf, human_ceiling, 1, 1));
859 break;
861 case 'S': /* sparseness */
862 /* UNTRUSTED, probably unexploitable */
863 fprintf (fp, segment->text, file_sparseness(stat_buf));;
864 break;
866 case 't': /* mtime in `ctime' format */
867 /* UNTRUSTED, probably unexploitable */
868 fprintf (fp, segment->text, ctime_format (get_stat_mtime(stat_buf)));
869 break;
871 case 'u': /* user name */
872 /* trusted */
873 /* (well, the actual user is selected by the user on systems
874 * where chown is not restricted, but the user name was
875 * selected by the system administrator)
878 struct passwd *p;
880 p = getpwuid (stat_buf->st_uid);
881 if (p)
883 segment->text[segment->text_len] = 's';
884 fprintf (fp, segment->text, p->pw_name);
885 break;
887 /* else fallthru */
890 case 'U': /* UID number */
891 /* UNTRUSTED, probably unexploitable */
892 fprintf (fp, segment->text,
893 human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
894 human_ceiling, 1, 1));
895 break;
897 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
898 case 'Y': /* in case of symlink */
899 /* trusted */
901 #ifdef S_ISLNK
902 if (S_ISLNK (stat_buf->st_mode))
904 struct stat sbuf;
905 /* If we would normally follow links, do not do so.
906 * If we would normally not follow links, do so.
908 if ((following_links() ? lstat : stat)
909 (state.rel_pathname, &sbuf) != 0)
911 if ( errno == ENOENT ) {
912 fprintf (fp, segment->text, "N");
913 break;
915 if ( errno == ELOOP ) {
916 fprintf (fp, segment->text, "L");
917 break;
919 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
920 /* exit_status = 1;
921 return (false); */
923 fprintf (fp, segment->text,
924 mode_to_filetype(sbuf.st_mode & S_IFMT));
926 #endif /* S_ISLNK */
927 else
929 fprintf (fp, segment->text,
930 mode_to_filetype(stat_buf->st_mode & S_IFMT));
933 break;
935 case 'y':
936 /* trusted */
938 fprintf (fp, segment->text,
939 mode_to_filetype(stat_buf->st_mode & S_IFMT));
941 break;
943 break;
945 #warning this function needs a return statement. See Savannah bug#19146.
948 boolean
949 pred_fprintf (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
951 FILE *fp = pred_ptr->args.printf_vec.stream;
952 struct segment *segment;
953 boolean ttyflag = pred_ptr->args.printf_vec.dest_is_tty;
954 const struct quoting_options *qopts = pred_ptr->args.printf_vec.quote_opts;
956 for (segment = pred_ptr->args.printf_vec.segment; segment;
957 segment = segment->next)
959 if ( (KIND_FORMAT == segment->segkind) && segment->format_char[1]) /* Component of date. */
961 struct timespec ts;
962 int valid = 0;
964 switch (segment->format_char[0])
966 case 'A':
967 ts = get_stat_atime(stat_buf);
968 valid = 1;
969 break;
970 case 'B':
971 ts = get_stat_birthtime(stat_buf);
972 if ('@' == segment->format_char[1])
973 valid = 1;
974 else
975 valid = (ts.tv_nsec >= 0);
976 break;
977 case 'C':
978 ts = get_stat_ctime(stat_buf);
979 valid = 1;
980 break;
981 case 'T':
982 ts = get_stat_mtime(stat_buf);
983 valid = 1;
984 break;
985 default:
986 assert(0);
987 abort ();
989 /* We trust the output of format_date not to contain
990 * nasty characters, though the value of the date
991 * is itself untrusted data.
993 if (valid)
995 /* trusted */
996 fprintf (fp, segment->text,
997 format_date (ts, segment->format_char[1]));
999 else
1001 /* The specified timestamp is not available, output
1002 * nothing for the timestamp, but use the rest (so that
1003 * for example find foo -printf '[%Bs] %p\n' can print
1004 * "[] foo").
1006 /* trusted */
1007 fprintf (fp, segment->text, "");
1010 else
1012 do_fprintf(fp, segment, pathname, stat_buf, ttyflag, qopts);
1015 return true;
1018 boolean
1019 pred_fstype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1021 (void) pathname;
1023 if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0)
1024 return true;
1025 else
1026 return false;
1029 boolean
1030 pred_gid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1032 (void) pathname;
1034 switch (pred_ptr->args.numinfo.kind)
1036 case COMP_GT:
1037 if (stat_buf->st_gid > pred_ptr->args.numinfo.l_val)
1038 return (true);
1039 break;
1040 case COMP_LT:
1041 if (stat_buf->st_gid < pred_ptr->args.numinfo.l_val)
1042 return (true);
1043 break;
1044 case COMP_EQ:
1045 if (stat_buf->st_gid == pred_ptr->args.numinfo.l_val)
1046 return (true);
1047 break;
1049 return (false);
1052 boolean
1053 pred_group (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1055 (void) pathname;
1057 if (pred_ptr->args.gid == stat_buf->st_gid)
1058 return (true);
1059 else
1060 return (false);
1063 boolean
1064 pred_ilname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1066 return match_lname (pathname, stat_buf, pred_ptr, true);
1069 boolean
1070 pred_iname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1072 const char *base;
1074 (void) stat_buf;
1076 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1077 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1079 base = base_name (pathname);
1080 if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0)
1081 return (true);
1082 return (false);
1085 boolean
1086 pred_inum (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1088 (void) pathname;
1090 switch (pred_ptr->args.numinfo.kind)
1092 case COMP_GT:
1093 if (stat_buf->st_ino > pred_ptr->args.numinfo.l_val)
1094 return (true);
1095 break;
1096 case COMP_LT:
1097 if (stat_buf->st_ino < pred_ptr->args.numinfo.l_val)
1098 return (true);
1099 break;
1100 case COMP_EQ:
1101 if (stat_buf->st_ino == pred_ptr->args.numinfo.l_val)
1102 return (true);
1103 break;
1105 return (false);
1108 boolean
1109 pred_ipath (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1111 (void) stat_buf;
1113 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
1114 return (true);
1115 return (false);
1118 boolean
1119 pred_links (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1121 (void) pathname;
1123 switch (pred_ptr->args.numinfo.kind)
1125 case COMP_GT:
1126 if (stat_buf->st_nlink > pred_ptr->args.numinfo.l_val)
1127 return (true);
1128 break;
1129 case COMP_LT:
1130 if (stat_buf->st_nlink < pred_ptr->args.numinfo.l_val)
1131 return (true);
1132 break;
1133 case COMP_EQ:
1134 if (stat_buf->st_nlink == pred_ptr->args.numinfo.l_val)
1135 return (true);
1136 break;
1138 return (false);
1141 boolean
1142 pred_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1144 return match_lname (pathname, stat_buf, pred_ptr, false);
1147 static boolean
1148 match_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)
1150 boolean ret = false;
1151 #ifdef S_ISLNK
1152 if (S_ISLNK (stat_buf->st_mode))
1154 char *linkname = get_link_name_at (pathname, state.cwd_dir_fd, state.rel_pathname);
1155 if (linkname)
1157 if (fnmatch (pred_ptr->args.str, linkname,
1158 ignore_case ? FNM_CASEFOLD : 0) == 0)
1159 ret = true;
1160 free (linkname);
1163 #endif /* S_ISLNK */
1164 return ret;
1167 boolean
1168 pred_ls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1170 list_file (pathname, state.cwd_dir_fd, state.rel_pathname,
1171 stat_buf, options.start_time.tv_sec,
1172 options.output_block_size,
1173 pred_ptr->literal_control_chars,
1174 stdout);
1175 return true;
1178 boolean
1179 pred_mmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1181 (void) &pathname;
1182 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, 60);
1185 boolean
1186 pred_mtime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1188 (void) pathname;
1189 return pred_timewindow(get_stat_mtime(stat_buf), pred_ptr, DAYSECS);
1192 boolean
1193 pred_name (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1195 const char *base;
1197 (void) stat_buf;
1198 base = base_name (pathname);
1200 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1201 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1203 if (fnmatch (pred_ptr->args.str, base, 0) == 0)
1204 return (true);
1205 return (false);
1208 boolean
1209 pred_negate (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1211 return !apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
1214 boolean
1215 pred_newer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1217 (void) pathname;
1219 assert(COMP_GT == pred_ptr->args.reftime.kind);
1220 return compare_ts(get_stat_mtime(stat_buf), pred_ptr->args.reftime.ts) > 0;
1223 boolean
1224 pred_newerXY (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1226 struct timespec ts;
1227 boolean collected = false;
1229 assert(COMP_GT == pred_ptr->args.reftime.kind);
1231 switch (pred_ptr->args.reftime.xval)
1233 case XVAL_TIME:
1234 assert(pred_ptr->args.reftime.xval != XVAL_TIME);
1235 return false;
1237 case XVAL_ATIME:
1238 ts = get_stat_atime(stat_buf);
1239 collected = true;
1240 break;
1242 case XVAL_BIRTHTIME:
1243 ts = get_stat_birthtime(stat_buf);
1244 collected = true;
1245 if (ts.tv_nsec < 0);
1247 /* XXX: Cannot determine birth time. Warn once. */
1248 error(0, 0, _("Warning: cannot determine birth time of file %s"),
1249 safely_quote_err_filename(0, pathname));
1250 return false;
1252 break;
1254 case XVAL_CTIME:
1255 ts = get_stat_ctime(stat_buf);
1256 collected = true;
1257 break;
1259 case XVAL_MTIME:
1260 ts = get_stat_mtime(stat_buf);
1261 collected = true;
1262 break;
1265 assert(collected);
1266 return compare_ts(ts, pred_ptr->args.reftime.ts) > 0;
1269 boolean
1270 pred_nogroup (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1272 (void) pathname;
1273 (void) pred_ptr;
1275 #ifdef CACHE_IDS
1276 extern char *gid_unused;
1278 return gid_unused[(unsigned) stat_buf->st_gid];
1279 #else
1280 return getgrgid (stat_buf->st_gid) == NULL;
1281 #endif
1284 boolean
1285 pred_nouser (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1287 #ifdef CACHE_IDS
1288 extern char *uid_unused;
1289 #endif
1291 (void) pathname;
1292 (void) pred_ptr;
1294 #ifdef CACHE_IDS
1295 return uid_unused[(unsigned) stat_buf->st_uid];
1296 #else
1297 return getpwuid (stat_buf->st_uid) == NULL;
1298 #endif
1302 static boolean
1303 is_ok(const char *program, const char *arg)
1305 fflush (stdout);
1306 /* The draft open standard requires that, in the POSIX locale,
1307 the last non-blank character of this prompt be '?'.
1308 The exact format is not specified.
1309 This standard does not have requirements for locales other than POSIX
1311 /* XXX: printing UNTRUSTED data here. */
1312 fprintf (stderr, _("< %s ... %s > ? "), program, arg);
1313 fflush (stderr);
1314 return yesno();
1317 boolean
1318 pred_ok (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1320 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1321 return new_impl_pred_exec (get_start_dirfd(),
1322 pathname, stat_buf, pred_ptr, NULL, 0);
1323 else
1324 return false;
1327 boolean
1328 pred_okdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1330 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./";
1331 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
1332 return new_impl_pred_exec (get_current_dirfd(),
1333 state.rel_pathname, stat_buf, pred_ptr,
1334 prefix, (prefix ? 2 : 0));
1335 else
1336 return false;
1339 boolean
1340 pred_openparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1342 (void) pathname;
1343 (void) stat_buf;
1344 (void) pred_ptr;
1345 return true;
1348 boolean
1349 pred_or (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1351 if (pred_ptr->pred_left == NULL
1352 || !apply_predicate(pathname, stat_buf, pred_ptr->pred_left))
1354 return apply_predicate(pathname, stat_buf, pred_ptr->pred_right);
1356 else
1357 return true;
1360 boolean
1361 pred_path (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1363 (void) stat_buf;
1364 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
1365 return (true);
1366 return (false);
1369 boolean
1370 pred_perm (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1372 mode_t mode = stat_buf->st_mode;
1373 mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0];
1374 (void) pathname;
1375 switch (pred_ptr->args.perm.kind)
1377 case PERM_AT_LEAST:
1378 return (mode & perm_val) == perm_val;
1379 break;
1381 case PERM_ANY:
1382 /* True if any of the bits set in the mask are also set in the file's mode.
1385 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1386 * evaluate as true if at least all of the bits specified in
1387 * onum that are also set in the octal mask 07777 are set.
1389 * Eric Blake's interpretation is that the mode argument is zero,
1392 if (0 == perm_val)
1393 return true; /* Savannah bug 14748; we used to return false */
1394 else
1395 return (mode & perm_val) != 0;
1396 break;
1398 case PERM_EXACT:
1399 return (mode & MODE_ALL) == perm_val;
1400 break;
1402 default:
1403 abort ();
1404 break;
1409 struct access_check_args
1411 const char *filename;
1412 int access_type;
1413 int cb_errno;
1417 static int
1418 access_callback(void *context)
1420 int rv;
1421 struct access_check_args *args = context;
1422 if ((rv = access(args->filename, args->access_type)) < 0)
1423 args->cb_errno = errno;
1424 return rv;
1427 static int
1428 can_access(int access_type)
1430 struct access_check_args args;
1431 args.filename = state.rel_pathname;
1432 args.access_type = access_type;
1433 args.cb_errno = 0;
1434 return 0 == run_in_dir(state.cwd_dir_fd, access_callback, &args);
1438 boolean
1439 pred_executable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1441 (void) pathname;
1442 (void) stat_buf;
1443 (void) pred_ptr;
1445 return can_access(X_OK);
1448 boolean
1449 pred_readable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1451 (void) pathname;
1452 (void) stat_buf;
1453 (void) pred_ptr;
1455 return can_access(R_OK);
1458 boolean
1459 pred_writable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1461 (void) pathname;
1462 (void) stat_buf;
1463 (void) pred_ptr;
1465 return can_access(W_OK);
1468 boolean
1469 pred_print (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1471 (void) stat_buf;
1472 (void) pred_ptr;
1473 /* puts (pathname); */
1474 print_quoted(pred_ptr->args.printf_vec.stream,
1475 pred_ptr->args.printf_vec.quote_opts,
1476 pred_ptr->args.printf_vec.dest_is_tty,
1477 "%s\n", pathname);
1478 return true;
1481 boolean
1482 pred_print0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1484 (void) stat_buf;
1485 (void) pred_ptr;
1486 fputs (pathname, stdout);
1487 putc (0, stdout);
1488 return (true);
1491 boolean
1492 pred_prune (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1494 (void) pathname;
1495 (void) pred_ptr;
1497 if (options.do_dir_first == true &&
1498 stat_buf != NULL &&
1499 S_ISDIR(stat_buf->st_mode))
1500 state.stop_at_current_level = true;
1502 return (options.do_dir_first); /* This is what SunOS find seems to do. */
1505 boolean
1506 pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1508 (void) pathname;
1509 (void) stat_buf;
1510 (void) pred_ptr;
1512 /* Run any cleanups. This includes executing any command lines
1513 * we have partly built but not executed.
1515 cleanup();
1517 /* Since -exec and friends don't leave child processes running in the
1518 * background, there is no need to wait for them here.
1520 exit(state.exit_status); /* 0 for success, etc. */
1523 boolean
1524 pred_regex (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1526 int len = strlen (pathname);
1527 (void) stat_buf;
1528 if (re_match (pred_ptr->args.regex, pathname, len, 0,
1529 (struct re_registers *) NULL) == len)
1530 return (true);
1531 return (false);
1534 boolean
1535 pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1537 uintmax_t f_val;
1539 (void) pathname;
1540 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
1541 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
1542 switch (pred_ptr->args.size.kind)
1544 case COMP_GT:
1545 if (f_val > pred_ptr->args.size.size)
1546 return (true);
1547 break;
1548 case COMP_LT:
1549 if (f_val < pred_ptr->args.size.size)
1550 return (true);
1551 break;
1552 case COMP_EQ:
1553 if (f_val == pred_ptr->args.size.size)
1554 return (true);
1555 break;
1557 return (false);
1560 boolean
1561 pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1563 /* Potential optimisation: because of the loop protection, we always
1564 * know the device of the current directory, hence the device number
1565 * of the file we're currently considering. If -L is not in effect,
1566 * and the device number of the file we're looking for is not the
1567 * same as the device number of the current directory, this
1568 * predicate cannot return true. Hence there would be no need to
1569 * stat the file we're looking at.
1571 (void) pathname;
1573 return stat_buf->st_ino == pred_ptr->args.fileid.ino
1574 && stat_buf->st_dev == pred_ptr->args.fileid.dev;
1577 boolean
1578 pred_true (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1580 (void) pathname;
1581 (void) stat_buf;
1582 (void) pred_ptr;
1583 return true;
1586 boolean
1587 pred_type (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1589 mode_t mode;
1590 mode_t type = pred_ptr->args.type;
1592 assert(state.have_type);
1593 assert(state.type != 0);
1595 (void) pathname;
1597 if (state.have_stat)
1598 mode = stat_buf->st_mode;
1599 else
1600 mode = state.type;
1602 #ifndef S_IFMT
1603 /* POSIX system; check `mode' the slow way. */
1604 if ((S_ISBLK (mode) && type == S_IFBLK)
1605 || (S_ISCHR (mode) && type == S_IFCHR)
1606 || (S_ISDIR (mode) && type == S_IFDIR)
1607 || (S_ISREG (mode) && type == S_IFREG)
1608 #ifdef S_IFLNK
1609 || (S_ISLNK (mode) && type == S_IFLNK)
1610 #endif
1611 #ifdef S_IFIFO
1612 || (S_ISFIFO (mode) && type == S_IFIFO)
1613 #endif
1614 #ifdef S_IFSOCK
1615 || (S_ISSOCK (mode) && type == S_IFSOCK)
1616 #endif
1617 #ifdef S_IFDOOR
1618 || (S_ISDOOR (mode) && type == S_IFDOOR)
1619 #endif
1621 #else /* S_IFMT */
1622 /* Unix system; check `mode' the fast way. */
1623 if ((mode & S_IFMT) == type)
1624 #endif /* S_IFMT */
1625 return (true);
1626 else
1627 return (false);
1630 boolean
1631 pred_uid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1633 (void) pathname;
1634 switch (pred_ptr->args.numinfo.kind)
1636 case COMP_GT:
1637 if (stat_buf->st_uid > pred_ptr->args.numinfo.l_val)
1638 return (true);
1639 break;
1640 case COMP_LT:
1641 if (stat_buf->st_uid < pred_ptr->args.numinfo.l_val)
1642 return (true);
1643 break;
1644 case COMP_EQ:
1645 if (stat_buf->st_uid == pred_ptr->args.numinfo.l_val)
1646 return (true);
1647 break;
1649 return (false);
1652 boolean
1653 pred_used (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1655 struct timespec delta, at, ct;
1657 (void) pathname;
1659 /* TODO: this needs to be retested carefully (manually, if necessary) */
1660 at = get_stat_atime(stat_buf);
1661 ct = get_stat_ctime(stat_buf);
1662 delta.tv_sec = at.tv_sec - ct.tv_sec;
1663 delta.tv_nsec = at.tv_nsec - ct.tv_nsec;
1664 if (delta.tv_nsec < 0)
1666 delta.tv_nsec += 1000000000;
1667 delta.tv_sec -= 1;
1669 return pred_timewindow(delta, pred_ptr, DAYSECS);
1672 boolean
1673 pred_user (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1675 (void) pathname;
1676 if (pred_ptr->args.uid == stat_buf->st_uid)
1677 return (true);
1678 else
1679 return (false);
1682 boolean
1683 pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
1685 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
1686 int (*ystat) (const char*, struct stat *p);
1688 /* If we would normally stat the link itself, stat the target instead.
1689 * If we would normally follow the link, stat the link itself instead.
1691 if (following_links())
1692 ystat = optionp_stat;
1693 else
1694 ystat = optionl_stat;
1696 set_stat_placeholders(&sbuf);
1697 if ((*ystat) (state.rel_pathname, &sbuf) != 0)
1699 if (following_links() && errno == ENOENT)
1701 /* If we failed to follow the symlink,
1702 * fall back on looking at the symlink itself.
1704 /* Mimic behavior of ls -lL. */
1705 return (pred_type (pathname, stat_buf, pred_ptr));
1707 else
1709 error (0, errno, "%s", safely_quote_err_filename(0, pathname));
1710 state.exit_status = 1;
1712 return false;
1714 /* Now that we have our stat() information, query it in the same
1715 * way that -type does.
1717 return (pred_type (pathname, &sbuf, pred_ptr));
1720 /* 1) fork to get a child; parent remembers the child pid
1721 2) child execs the command requested
1722 3) parent waits for child; checks for proper pid of child
1724 Possible returns:
1726 ret errno status(h) status(l)
1728 pid x signal# 0177 stopped
1729 pid x exit arg 0 term by _exit
1730 pid x 0 signal # term by signal
1731 -1 EINTR parent got signal
1732 -1 other some other kind of error
1734 Return true only if the pid matches, status(l) is
1735 zero, and the exit arg (status high) is 0.
1736 Otherwise return false, possibly printing an error message. */
1739 static boolean
1740 prep_child_for_exec (boolean close_stdin, int dirfd)
1742 boolean ok = true;
1743 if (close_stdin)
1745 const char inputfile[] = "/dev/null";
1747 if (close(0) < 0)
1749 error(0, errno, _("Cannot close standard input"));
1750 ok = false;
1752 else
1754 if (open(inputfile, O_RDONLY
1755 #if defined O_LARGEFILE
1756 |O_LARGEFILE
1757 #endif
1758 ) < 0)
1760 /* This is not entirely fatal, since
1761 * executing the child with a closed
1762 * stdin is almost as good as executing it
1763 * with its stdin attached to /dev/null.
1765 error (0, errno, "%s", safely_quote_err_filename(0, inputfile));
1766 /* do not set ok=false, it is OK to continue anyway. */
1771 /* Even if DebugSearch is set, don't announce our change of
1772 * directory, since we're not going to emit a subsequent
1773 * announcement of a call to stat() anyway, as we're about to exec
1774 * something.
1776 if (dirfd != AT_FDCWD)
1778 assert(dirfd >= 0);
1779 if (0 != fchdir(dirfd))
1781 /* If we cannot execute our command in the correct directory,
1782 * we should not execute it at all.
1784 error(0, errno, _("Failed to change directory"));
1785 ok = false;
1788 return ok;
1794 launch (const struct buildcmd_control *ctl,
1795 struct buildcmd_state *buildstate)
1797 int wait_status;
1798 pid_t child_pid;
1799 static int first_time = 1;
1800 const struct exec_val *execp = buildstate->usercontext;
1802 if (!execp->use_current_dir)
1804 assert(starting_desc >= 0);
1805 assert(execp->dirfd == starting_desc);
1809 /* Null terminate the arg list. */
1810 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false);
1812 /* Make sure output of command doesn't get mixed with find output. */
1813 fflush (stdout);
1814 fflush (stderr);
1816 /* Make sure to listen for the kids. */
1817 if (first_time)
1819 first_time = 0;
1820 signal (SIGCHLD, SIG_DFL);
1823 child_pid = fork ();
1824 if (child_pid == -1)
1825 error (1, errno, _("cannot fork"));
1826 if (child_pid == 0)
1828 /* We are the child. */
1829 assert(starting_desc >= 0);
1830 if (!prep_child_for_exec(execp->close_stdin, execp->dirfd))
1832 _exit(1);
1835 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv);
1836 error (0, errno, "%s",
1837 safely_quote_err_filename(0, buildstate->cmd_argv[0]));
1838 _exit (1);
1842 /* In parent; set up for next time. */
1843 bc_clear_args(ctl, buildstate);
1846 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1)
1848 if (errno != EINTR)
1850 error (0, errno, _("error waiting for %s"),
1851 safely_quote_err_filename(0, buildstate->cmd_argv[0]));
1852 state.exit_status = 1;
1853 return 0; /* FAIL */
1857 if (WIFSIGNALED (wait_status))
1859 error (0, 0, _("%s terminated by signal %d"),
1860 quotearg_n_style(0, options.err_quoting_style,
1861 buildstate->cmd_argv[0]),
1862 WTERMSIG (wait_status));
1864 if (execp->multiple)
1866 /* -exec \; just returns false if the invoked command fails.
1867 * -exec {} + returns true if the invoked command fails, but
1868 * sets the program exit status.
1870 state.exit_status = 1;
1873 return 1; /* OK */
1876 if (0 == WEXITSTATUS (wait_status))
1878 return 1; /* OK */
1880 else
1882 if (execp->multiple)
1884 /* -exec \; just returns false if the invoked command fails.
1885 * -exec {} + returns true if the invoked command fails, but
1886 * sets the program exit status.
1888 state.exit_status = 1;
1890 return 0; /* FAIL */
1896 /* Return a static string formatting the time WHEN according to the
1897 * strftime format character KIND.
1899 * This function contains a number of assertions. These look like
1900 * runtime checks of the results of computations, which would be a
1901 * problem since external events should not be tested for with
1902 * "assert" (instead you should use "if"). However, they are not
1903 * really runtime checks. The assertions actually exist to verify
1904 * that the various buffers are correctly sized.
1906 static char *
1907 format_date (struct timespec ts, int kind)
1909 /* In theory, we use an extra 10 characters for 9 digits of
1910 * nanoseconds and 1 for the decimal point. However, the real
1911 * world is more complex than that.
1913 * For example, some systems return junk in the tv_nsec part of
1914 * st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
1915 * (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
1916 * runtime and examining files on an msdos filesytem. So for that
1917 * reason we set NS_BUF_LEN to 32, which is simply "long enough" as
1918 * opposed to "exactly the right size". Note that the behaviour of
1919 * NetBSD appears to be a result of the use of uninitialised data,
1920 * as it's not 100% reproducible (more like 25%).
1922 enum {
1923 NS_BUF_LEN = 32,
1924 DATE_LEN_PERCENT_APLUS=21 /* length of result of %A+ (it's longer than %c)*/
1926 static char buf[128u+10u + MAX(DATE_LEN_PERCENT_APLUS,
1927 MAX (LONGEST_HUMAN_READABLE + 2, NS_BUF_LEN+64+200))];
1928 char ns_buf[NS_BUF_LEN]; /* -.9999999990 (- sign can happen!)*/
1929 int charsprinted, need_ns_suffix;
1930 struct tm *tm;
1931 char fmt[6];
1933 /* human_readable() assumes we pass a buffer which is at least as
1934 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
1935 * ensure that no nasty unsigned overflow happend in our calculation
1936 * of the size of buf. Do the assertion here rather than in the
1937 * code for %@ so that we find the problem quickly if it exists. If
1938 * you want to submit a patch to move this into the if statement, go
1939 * ahead, I'll apply it. But include performance timings
1940 * demonstrating that the performance difference is actually
1941 * measurable.
1943 assert(sizeof(buf) >= LONGEST_HUMAN_READABLE);
1945 charsprinted = 0;
1946 need_ns_suffix = 0;
1948 /* Format the main part of the time. */
1949 if (kind == '+')
1951 strcpy (fmt, "%F+%T");
1952 need_ns_suffix = 1;
1954 else
1956 fmt[0] = '%';
1957 fmt[1] = kind;
1958 fmt[2] = '\0';
1960 /* %a, %c, and %t are handled in ctime_format() */
1961 switch (kind)
1963 case 'S':
1964 case 'T':
1965 case 'X':
1966 case '@':
1967 need_ns_suffix = 1;
1968 break;
1969 default:
1970 need_ns_suffix = 0;
1971 break;
1975 if (need_ns_suffix)
1977 /* Format the nanoseconds part. Leave a trailing zero to
1978 * discourage people from writing scripts which extract the
1979 * fractional part of the timestamp by using column offsets.
1980 * The reason for discouraging this is that in the future, the
1981 * granularity may not be nanoseconds.
1983 ns_buf[0] = 0;
1984 charsprinted = snprintf(ns_buf, NS_BUF_LEN, ".%09ld0", (long int)ts.tv_nsec);
1985 assert(charsprinted < NS_BUF_LEN);
1988 if (kind != '@'
1989 && (tm = localtime (&ts.tv_sec))
1990 && strftime (buf, sizeof buf, fmt, tm))
1992 /* For %AS, %CS, %TS, add the fractional part of the seconds
1993 * information.
1995 if (need_ns_suffix)
1997 assert((sizeof buf - strlen(buf)) > strlen(ns_buf));
1998 strcat(buf, ns_buf);
2000 return buf;
2002 else
2004 uintmax_t w = ts.tv_sec;
2005 size_t used, len, remaining;
2007 /* XXX: note that we are negating an unsigned type which is the
2008 * widest possible unsigned type.
2010 char *p = human_readable (ts.tv_sec < 0 ? -w : w, buf + 1,
2011 human_ceiling, 1, 1);
2012 assert(p > buf);
2013 assert(p < (buf + (sizeof buf)));
2014 if (ts.tv_sec < 0)
2015 *--p = '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
2017 /* Add the nanoseconds part. Because we cannot enforce a
2018 * particlar implementation of human_readable, we cannot assume
2019 * any particular value for (p-buf). So we need to be careful
2020 * that there is enough space remaining in the buffer.
2022 if (need_ns_suffix)
2024 len = strlen(p);
2025 used = (p-buf) + len; /* Offset into buf of current end */
2026 assert(sizeof buf > used); /* Ensure we can perform subtraction safely. */
2027 remaining = sizeof buf - used - 1u; /* allow space for NUL */
2029 if (strlen(ns_buf) >= remaining)
2031 error(0, 0,
2032 "charsprinted=%ld but remaining=%lu: ns_buf=%s",
2033 (long)charsprinted, (unsigned long)remaining, ns_buf);
2035 assert(strlen(ns_buf) < remaining);
2036 strcat(p, ns_buf);
2038 return p;
2042 static const char *weekdays[] =
2044 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
2046 static char * months[] =
2048 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2049 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2053 static char *
2054 ctime_format (struct timespec ts)
2056 const struct tm * ptm;
2057 #define TIME_BUF_LEN 1024u
2058 static char resultbuf[TIME_BUF_LEN];
2059 int nout;
2061 ptm = localtime(&ts.tv_sec);
2062 if (ptm)
2064 assert(ptm->tm_wday >= 0);
2065 assert(ptm->tm_wday < 7);
2066 assert(ptm->tm_mon >= 0);
2067 assert(ptm->tm_mon < 12);
2068 assert(ptm->tm_hour >= 0);
2069 assert(ptm->tm_hour < 24);
2070 assert(ptm->tm_min < 60);
2071 assert(ptm->tm_sec <= 61); /* allows 2 leap seconds. */
2073 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
2074 nout = snprintf(resultbuf, TIME_BUF_LEN,
2075 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
2076 weekdays[ptm->tm_wday],
2077 months[ptm->tm_mon],
2078 ptm->tm_mday,
2079 ptm->tm_hour,
2080 ptm->tm_min,
2081 ptm->tm_sec,
2082 (long int)ts.tv_nsec,
2083 1900 + ptm->tm_year);
2085 assert(nout < TIME_BUF_LEN);
2086 return resultbuf;
2088 else
2090 /* The time cannot be represented as a struct tm.
2091 Output it as an integer. */
2092 return format_date (ts, '@');
2096 /* Copy STR into BUF and trim blanks from the end of BUF.
2097 Return BUF. */
2099 static char *
2100 blank_rtrim (str, buf)
2101 char *str;
2102 char *buf;
2104 int i;
2106 if (str == NULL)
2107 return (NULL);
2108 strcpy (buf, str);
2109 i = strlen (buf) - 1;
2110 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
2111 i--;
2112 buf[++i] = '\0';
2113 return (buf);
2116 /* Print out the predicate list starting at NODE. */
2117 void
2118 print_list (FILE *fp, struct predicate *node)
2120 struct predicate *cur;
2121 char name[256];
2123 cur = node;
2124 while (cur != NULL)
2126 fprintf (fp, "%s ", blank_rtrim (cur->p_name, name));
2127 cur = cur->pred_next;
2129 fprintf (fp, "\n");
2132 /* Print out the predicate list starting at NODE. */
2133 static void
2134 print_parenthesised(FILE *fp, struct predicate *node)
2136 int parens = 0;
2138 if (node)
2140 if ((pred_is(node, pred_or) || pred_is(node, pred_and))
2141 && node->pred_left == NULL)
2143 /* We print "<nothing> or X" as just "X"
2144 * We print "<nothing> and X" as just "X"
2146 print_parenthesised(fp, node->pred_right);
2148 else
2150 if (node->pred_left || node->pred_right)
2151 parens = 1;
2153 if (parens)
2154 fprintf(fp, "%s", " ( ");
2155 print_optlist(fp, node);
2156 if (parens)
2157 fprintf(fp, "%s", " ) ");
2162 void
2163 print_optlist (FILE *fp, const struct predicate *p)
2165 if (p)
2167 print_parenthesised(fp, p->pred_left);
2168 fprintf (fp,
2169 "%s%s",
2170 p->need_stat ? "[call stat] " : "",
2171 p->need_type ? "[need type] " : "");
2172 print_predicate(fp, p);
2173 fprintf(fp, " [%g] ", p->est_success_rate);
2174 if (options.debug_options & DebugSuccessRates)
2176 fprintf(fp, "[%ld/%ld", p->perf.successes, p->perf.visits);
2177 if (p->perf.visits)
2179 double real_rate = (double)p->perf.successes / (double)p->perf.visits;
2180 fprintf(fp, "=%g] ", real_rate);
2182 else
2184 fprintf(fp, "=_] ");
2187 print_parenthesised(fp, p->pred_right);
2191 void show_success_rates(const struct predicate *p)
2193 if (options.debug_options & DebugSuccessRates)
2195 fprintf(stderr, "Predicate success rates after completion:\n");
2196 print_optlist(stderr, p);
2197 fprintf(stderr, "\n");
2204 #ifdef _NDEBUG
2205 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2206 * there is no point in having a function body for pred_sanity_check()
2207 * if that preprocessor macro is defined.
2209 void
2210 pred_sanity_check(const struct predicate *predicates)
2212 /* Do nothing, since assert() is a no-op with _NDEBUG set */
2213 return;
2215 #else
2216 void
2217 pred_sanity_check(const struct predicate *predicates)
2219 const struct predicate *p;
2221 for (p=predicates; p != NULL; p=p->pred_next)
2223 /* All predicates must do something. */
2224 assert(p->pred_func != NULL);
2226 /* All predicates must have a parser table entry. */
2227 assert(p->parser_entry != NULL);
2229 /* If the parser table tells us that just one predicate function is
2230 * possible, verify that that is still the one that is in effect.
2231 * If the parser has NULL for the predicate function, that means that
2232 * the parse_xxx function fills it in, so we can't check it.
2234 if (p->parser_entry->pred_func)
2236 assert(p->parser_entry->pred_func == p->pred_func);
2239 switch (p->parser_entry->type)
2241 /* Options all take effect during parsing, so there should
2242 * be no predicate entries corresponding to them. Hence we
2243 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2244 * items.
2246 * This is a silly way of coding this test, but it prevents
2247 * a compiler warning (i.e. otherwise it would think that
2248 * there would be case statements missing).
2250 case ARG_OPTION:
2251 case ARG_POSITIONAL_OPTION:
2252 assert(p->parser_entry->type != ARG_OPTION);
2253 assert(p->parser_entry->type != ARG_POSITIONAL_OPTION);
2254 break;
2256 case ARG_ACTION:
2257 assert(p->side_effects); /* actions have side effects. */
2258 if (!pred_is(p, pred_prune) && !pred_is(p, pred_quit))
2260 /* actions other than -prune and -quit should
2261 * inhibit the default -print
2263 assert(p->no_default_print);
2265 break;
2267 /* We happen to know that the only user of ARG_SPECIAL_PARSE
2268 * is a test, so handle it like ARG_TEST.
2270 case ARG_SPECIAL_PARSE:
2271 case ARG_TEST:
2272 case ARG_PUNCTUATION:
2273 case ARG_NOOP:
2274 /* Punctuation and tests should have no side
2275 * effects and not inhibit default print.
2277 assert(!p->no_default_print);
2278 assert(!p->side_effects);
2279 break;
2283 #endif