1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
3 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
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,
29 #include <sys/types.h>
43 #include "printquoted.h"
47 #include "stat-time.h"
48 #include "dircallback.h"
54 # define _(Text) gettext (Text)
59 # define N_(String) gettext_noop (String)
61 /* See locate.c for explanation as to why not use (String) */
62 # define N_(String) String
65 #if !defined(SIGCHLD) && defined(SIGCLD)
66 #define SIGCHLD SIGCLD
73 # define NAMLEN(dirent) strlen((dirent)->d_name)
75 # define dirent direct
76 # define NAMLEN(dirent) (dirent)->d_namlen
78 # include <sys/ndir.h>
89 /* Fake a return value. */
90 #define CLOSEDIR(d) (closedir (d), 0)
92 #define CLOSEDIR(d) closedir (d)
98 /* Get or fake the disk device blocksize.
99 Usually defined by sys/param.h (if at all). */
102 # define DEV_BSIZE BSIZE
104 # define DEV_BSIZE 4096
106 #endif /* !DEV_BSIZE */
108 /* Extract or fake data from a `struct stat'.
109 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
110 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
111 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
112 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
113 # define ST_BLKSIZE(statbuf) DEV_BSIZE
114 # if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
115 # define ST_NBLOCKS(statbuf) \
116 (S_ISREG ((statbuf).st_mode) \
117 || S_ISDIR ((statbuf).st_mode) \
118 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
119 # else /* !_POSIX_SOURCE && BSIZE */
120 # define ST_NBLOCKS(statbuf) \
121 (S_ISREG ((statbuf).st_mode) \
122 || S_ISDIR ((statbuf).st_mode) \
123 ? st_blocks ((statbuf).st_size) : 0)
124 # endif /* !_POSIX_SOURCE && BSIZE */
125 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
126 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
127 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
128 ? (statbuf).st_blksize : DEV_BSIZE)
129 # if defined hpux || defined __hpux__ || defined __hpux
130 /* HP-UX counts st_blocks in 1024-byte units.
131 This loses when mixing HP-UX and BSD file systems with NFS. */
132 # define ST_NBLOCKSIZE 1024
134 # if defined _AIX && defined _I386
135 /* AIX PS/2 counts st_blocks in 4K units. */
136 # define ST_NBLOCKSIZE (4 * 1024)
137 # else /* not AIX PS/2 */
139 # define ST_NBLOCKS(statbuf) \
140 (S_ISREG ((statbuf).st_mode) \
141 || S_ISDIR ((statbuf).st_mode) \
142 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
144 # endif /* not AIX PS/2 */
146 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
149 # define ST_NBLOCKS(statbuf) \
150 (S_ISREG ((statbuf).st_mode) \
151 || S_ISDIR ((statbuf).st_mode) \
152 ? (statbuf).st_blocks : 0)
155 #ifndef ST_NBLOCKSIZE
156 # define ST_NBLOCKSIZE 512
161 #define MAX(a, b) ((a) > (b) ? (a) : (b))
163 static boolean match_lname
PARAMS((const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
));
165 static char *format_date
PARAMS((struct timespec ts
, int kind
));
166 static char *ctime_format
PARAMS((struct timespec ts
));
175 struct pred_assoc pred_table
[] =
177 {pred_amin
, "amin "},
179 {pred_anewer
, "anewer "},
180 {pred_atime
, "atime "},
181 {pred_closeparen
, ") "},
182 {pred_cmin
, "cmin "},
183 {pred_cnewer
, "cnewer "},
185 {pred_ctime
, "ctime "},
186 {pred_delete
, "delete "},
187 {pred_empty
, "empty "},
188 {pred_exec
, "exec "},
189 {pred_execdir
, "execdir "},
190 {pred_executable
, "executable "},
191 {pred_false
, "false "},
192 {pred_fprint
, "fprint "},
193 {pred_fprint0
, "fprint0 "},
194 {pred_fprintf
, "fprintf "},
195 {pred_fstype
, "fstype "},
197 {pred_group
, "group "},
198 {pred_ilname
, "ilname "},
199 {pred_iname
, "iname "},
200 {pred_inum
, "inum "},
201 {pred_ipath
, "ipath "},
202 {pred_links
, "links "},
203 {pred_lname
, "lname "},
205 {pred_mmin
, "mmin "},
206 {pred_mtime
, "mtime "},
207 {pred_name
, "name "},
208 {pred_negate
, "not "},
209 {pred_newer
, "newer "},
210 {pred_newerXY
, "newerXY "},
211 {pred_nogroup
, "nogroup "},
212 {pred_nouser
, "nouser "},
214 {pred_okdir
, "okdir "},
215 {pred_openparen
, "( "},
217 {pred_path
, "path "},
218 {pred_perm
, "perm "},
219 {pred_print
, "print "},
220 {pred_print0
, "print0 "},
221 {pred_prune
, "prune "},
222 {pred_quit
, "quit "},
223 {pred_readable
, "readable "},
224 {pred_regex
, "regex "},
225 {pred_samefile
,"samefile "},
226 {pred_size
, "size "},
227 {pred_true
, "true "},
228 {pred_type
, "type "},
230 {pred_used
, "used "},
231 {pred_user
, "user "},
232 {pred_writable
, "writable "},
233 {pred_xtype
, "xtype "},
238 /* Returns ts1 - ts2 */
239 static double ts_difference(struct timespec ts1
,
242 double d
= difftime(ts1
.tv_sec
, ts2
.tv_sec
)
243 + (1.0e-9 * (ts1
.tv_nsec
- ts2
.tv_nsec
));
249 compare_ts(struct timespec ts1
,
252 if ((ts1
.tv_sec
== ts2
.tv_sec
) &&
253 (ts1
.tv_nsec
== ts2
.tv_nsec
))
259 double diff
= ts_difference(ts1
, ts2
);
260 return diff
< 0.0 ? -1 : +1;
264 /* Predicate processing routines.
266 PATHNAME is the full pathname of the file being checked.
267 *STAT_BUF contains information about PATHNAME.
268 *PRED_PTR contains information for applying the predicate.
270 Return true if the file passes this predicate, false if not. */
275 * Returns true if THE_TIME is
276 * COMP_GT: after the specified time
277 * COMP_LT: before the specified time
278 * COMP_EQ: less than WINDOW seconds after the specified time.
281 pred_timewindow(struct timespec ts
, struct predicate
const *pred_ptr
, int window
)
283 switch (pred_ptr
->args
.reftime
.kind
)
286 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
289 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) < 0;
293 double delta
= ts_difference(ts
, pred_ptr
->args
.reftime
.ts
);
294 return (delta
>= 0.0 && delta
< window
);
303 pred_amin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
306 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, 60);
310 pred_and (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
312 if (pred_ptr
->pred_left
== NULL
313 || apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_left
))
315 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
322 pred_anewer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
325 assert (COMP_GT
== pred_ptr
->args
.reftime
.kind
);
326 return compare_ts(get_stat_atime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
330 pred_atime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
333 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, DAYSECS
);
337 pred_closeparen (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
347 pred_cmin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
350 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, 60);
354 pred_cnewer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
358 assert (COMP_GT
== pred_ptr
->args
.reftime
.kind
);
359 return compare_ts(get_stat_ctime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
363 pred_comma (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
365 if (pred_ptr
->pred_left
!= NULL
)
367 apply_predicate(pathname
, stat_buf
,pred_ptr
->pred_left
);
369 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
373 pred_ctime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
376 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, DAYSECS
);
380 perform_delete(int flags
)
382 return 0 == unlinkat(state
.cwd_dir_fd
, state
.rel_pathname
, flags
);
387 pred_delete (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
391 if (strcmp (state
.rel_pathname
, "."))
394 if (state
.have_stat
&& S_ISDIR(stat_buf
->st_mode
))
395 flags
|= AT_REMOVEDIR
;
396 if (perform_delete(flags
))
404 if ((flags
& AT_REMOVEDIR
) == 0)
406 /* unlink() operation failed because we should have done rmdir(). */
407 flags
|= AT_REMOVEDIR
;
408 if (perform_delete(flags
))
413 error (0, errno
, _("cannot delete %s"),
414 safely_quote_err_filename(0, pathname
));
425 pred_empty (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
430 if (S_ISDIR (stat_buf
->st_mode
))
435 boolean empty
= true;
438 if ((fd
= openat(state
.cwd_dir_fd
, state
.rel_pathname
, O_RDONLY
439 #if defined O_LARGEFILE
444 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
445 state
.exit_status
= 1;
451 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
452 state
.exit_status
= 1;
455 for (dp
= readdir (d
); dp
; dp
= readdir (d
))
457 if (dp
->d_name
[0] != '.'
458 || (dp
->d_name
[1] != '\0'
459 && (dp
->d_name
[1] != '.' || dp
->d_name
[2] != '\0')))
467 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
468 state
.exit_status
= 1;
473 else if (S_ISREG (stat_buf
->st_mode
))
474 return (stat_buf
->st_size
== 0);
480 new_impl_pred_exec (int dirfd
, const char *pathname
,
481 struct stat
*stat_buf
,
482 struct predicate
*pred_ptr
,
483 const char *prefix
, size_t pfxlen
)
485 struct exec_val
*execp
= &pred_ptr
->args
.exec_vec
;
486 size_t len
= strlen(pathname
);
489 execp
->dirfd
= dirfd
;
492 /* Push the argument onto the current list.
493 * The command may or may not be run at this point,
494 * depending on the command line length limits.
496 bc_push_arg(&execp
->ctl
,
502 /* remember that there are pending execdirs. */
503 state
.execdirs_outstanding
= true;
505 /* POSIX: If the primary expression is punctuated by a plus
506 * sign, the primary shall always evaluate as true
514 for (i
=0; i
<execp
->num_args
; ++i
)
516 bc_do_insert(&execp
->ctl
,
518 execp
->replace_vec
[i
],
519 strlen(execp
->replace_vec
[i
]),
525 /* Actually invoke the command. */
526 return execp
->ctl
.exec_callback(&execp
->ctl
,
533 pred_exec (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
535 return new_impl_pred_exec(get_start_dirfd(),
536 pathname
, stat_buf
, pred_ptr
, NULL
, 0);
540 pred_execdir (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
542 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
544 return new_impl_pred_exec (get_current_dirfd(),
545 state
.rel_pathname
, stat_buf
, pred_ptr
,
546 prefix
, (prefix
? 2 : 0));
550 pred_false (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
561 pred_fls (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
563 FILE * stream
= pred_ptr
->args
.printf_vec
.stream
;
564 list_file (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
, stat_buf
,
565 options
.start_time
.tv_sec
,
566 options
.output_block_size
,
567 pred_ptr
->literal_control_chars
, stream
);
572 pred_fprint (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
577 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
578 pred_ptr
->args
.printf_vec
.quote_opts
,
579 pred_ptr
->args
.printf_vec
.dest_is_tty
,
586 pred_fprint0 (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
588 FILE * fp
= pred_ptr
->args
.printf_vec
.stream
;
592 fputs (pathname
, fp
);
600 mode_to_filetype(mode_t m
)
602 #define HANDLE_TYPE(t,letter) if (m==t) { return letter; }
604 HANDLE_TYPE(S_IFREG
, "f"); /* regular file */
607 HANDLE_TYPE(S_IFDIR
, "d"); /* directory */
610 HANDLE_TYPE(S_IFLNK
, "l"); /* symbolic link */
613 HANDLE_TYPE(S_IFSOCK
, "s"); /* Unix domain socket */
616 HANDLE_TYPE(S_IFBLK
, "b"); /* block device */
619 HANDLE_TYPE(S_IFCHR
, "c"); /* character device */
622 HANDLE_TYPE(S_IFIFO
, "p"); /* FIFO */
625 HANDLE_TYPE(S_IFDOOR
, "D"); /* Door (e.g. on Solaris) */
627 return "U"; /* Unknown */
631 file_sparseness(const struct stat
*p
)
633 #if defined HAVE_STRUCT_STAT_ST_BLOCKS
636 if (0 == p
->st_blocks
)
639 return p
->st_blocks
< 0 ? -HUGE_VAL
: HUGE_VAL
;
643 double blklen
= file_blocksize(p
) * (double)p
->st_blocks
;
644 return blklen
/ p
->st_size
;
654 checked_fprintf(struct format_val
*dest
, const char *fmt
, ...)
660 rv
= vfprintf(dest
->stream
, fmt
, ap
);
662 nonfatal_file_error(dest
->filename
);
667 checked_print_quoted (struct format_val
*dest
,
668 const char *format
, const char *s
)
670 int rv
= print_quoted(dest
->stream
, dest
->quote_opts
, dest
->dest_is_tty
,
673 nonfatal_file_error(dest
->filename
);
678 checked_fwrite(void *p
, size_t siz
, size_t nmemb
, struct format_val
*dest
)
680 int items_written
= fwrite(p
, siz
, nmemb
, dest
->stream
);
681 if (items_written
< nmemb
)
682 nonfatal_file_error(dest
->filename
);
686 checked_fflush(struct format_val
*dest
)
688 if (0 != fflush(dest
->stream
))
690 nonfatal_file_error(dest
->filename
);
695 do_fprintf(struct format_val
*dest
,
696 struct segment
*segment
,
697 const char *pathname
,
698 const struct stat
*stat_buf
)
700 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
703 switch (segment
->segkind
)
705 case KIND_PLAIN
: /* Plain text string (no % conversion). */
707 checked_fwrite(segment
->text
, 1, segment
->text_len
, dest
);
710 case KIND_STOP
: /* Terminate argument and flush output. */
712 checked_fwrite(segment
->text
, 1, segment
->text_len
, dest
);
713 checked_fflush(dest
);
717 switch (segment
->format_char
[0])
719 case 'a': /* atime in `ctime' format. */
720 /* UNTRUSTED, probably unexploitable */
721 checked_fprintf (dest
, segment
->text
, ctime_format (get_stat_atime(stat_buf
)));
723 case 'b': /* size in 512-byte blocks */
724 /* UNTRUSTED, probably unexploitable */
725 checked_fprintf (dest
, segment
->text
,
726 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
728 ST_NBLOCKSIZE
, 512));
730 case 'c': /* ctime in `ctime' format */
731 /* UNTRUSTED, probably unexploitable */
732 checked_fprintf (dest
, segment
->text
, ctime_format (get_stat_ctime(stat_buf
)));
734 case 'd': /* depth in search tree */
735 /* UNTRUSTED, probably unexploitable */
736 checked_fprintf (dest
, segment
->text
, state
.curdepth
);
738 case 'D': /* Device on which file exists (stat.st_dev) */
740 checked_fprintf (dest
, segment
->text
,
741 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
742 human_ceiling
, 1, 1));
744 case 'f': /* base name of path */
746 checked_print_quoted (dest
, segment
->text
, base_name (pathname
));
748 case 'F': /* file system type */
750 checked_print_quoted (dest
, segment
->text
, filesystem_type (stat_buf
, pathname
));
752 case 'g': /* group name */
754 /* (well, the actual group is selected by the user but
755 * its name was selected by the system administrator)
760 g
= getgrgid (stat_buf
->st_gid
);
763 segment
->text
[segment
->text_len
] = 's';
764 checked_fprintf (dest
, segment
->text
, g
->gr_name
);
773 /*FALLTHROUGH*/ /*...sometimes, so 'G' case.*/
775 case 'G': /* GID number */
776 /* UNTRUSTED, probably unexploitable */
777 checked_fprintf (dest
, segment
->text
,
778 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
779 human_ceiling
, 1, 1));
781 case 'h': /* leading directories part of path */
784 cp
= strrchr (pathname
, '/');
785 if (cp
== NULL
) /* No leading directories. */
787 /* If there is no slash in the pathname, we still
788 * print the string because it contains characters
789 * other than just '%s'. The %h expands to ".".
791 checked_print_quoted (dest
, segment
->text
, ".");
795 char *s
= strdup(pathname
);
796 s
[cp
- pathname
] = 0;
797 checked_print_quoted (dest
, segment
->text
, s
);
803 case 'H': /* ARGV element file was found under */
806 char *s
= xmalloc(state
.starting_path_length
+1);
807 memcpy(s
, pathname
, state
.starting_path_length
);
808 s
[state
.starting_path_length
] = 0;
809 checked_fprintf (dest
, segment
->text
, s
);
814 case 'i': /* inode number */
815 /* UNTRUSTED, but not exploitable I think */
816 checked_fprintf (dest
, segment
->text
,
817 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
821 case 'k': /* size in 1K blocks */
822 /* UNTRUSTED, but not exploitable I think */
823 checked_fprintf (dest
, segment
->text
,
824 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
826 ST_NBLOCKSIZE
, 1024));
828 case 'l': /* object of symlink */
834 if (S_ISLNK (stat_buf
->st_mode
))
836 linkname
= get_link_name_at (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
);
838 state
.exit_status
= 1;
842 checked_print_quoted (dest
, segment
->text
, linkname
);
847 /* We still need to honour the field width etc., so this is
850 checked_print_quoted (dest
, segment
->text
, "");
856 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
857 /* UNTRUSTED, probably unexploitable */
859 char modestring
[16] ;
860 filemodestring (stat_buf
, modestring
);
861 modestring
[10] = '\0';
862 checked_fprintf (dest
, segment
->text
, modestring
);
866 case 'm': /* mode as octal number (perms only) */
867 /* UNTRUSTED, probably unexploitable */
869 /* Output the mode portably using the traditional numbers,
870 even if the host unwisely uses some other numbering
871 scheme. But help the compiler in the common case where
872 the host uses the traditional numbering scheme. */
873 mode_t m
= stat_buf
->st_mode
;
874 boolean traditional_numbering_scheme
=
875 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
876 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
877 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
878 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
879 checked_fprintf (dest
, segment
->text
,
880 (traditional_numbering_scheme
882 : ((m
& S_ISUID
? 04000 : 0)
883 | (m
& S_ISGID
? 02000 : 0)
884 | (m
& S_ISVTX
? 01000 : 0)
885 | (m
& S_IRUSR
? 00400 : 0)
886 | (m
& S_IWUSR
? 00200 : 0)
887 | (m
& S_IXUSR
? 00100 : 0)
888 | (m
& S_IRGRP
? 00040 : 0)
889 | (m
& S_IWGRP
? 00020 : 0)
890 | (m
& S_IXGRP
? 00010 : 0)
891 | (m
& S_IROTH
? 00004 : 0)
892 | (m
& S_IWOTH
? 00002 : 0)
893 | (m
& S_IXOTH
? 00001 : 0))));
897 case 'n': /* number of links */
898 /* UNTRUSTED, probably unexploitable */
899 checked_fprintf (dest
, segment
->text
,
900 human_readable ((uintmax_t) stat_buf
->st_nlink
,
906 case 'p': /* pathname */
908 checked_print_quoted (dest
, segment
->text
, pathname
);
911 case 'P': /* pathname with ARGV element stripped */
913 if (state
.curdepth
> 0)
915 cp
= pathname
+ state
.starting_path_length
;
917 /* Move past the slash between the ARGV element
918 and the rest of the pathname. But if the ARGV element
919 ends in a slash, we didn't add another, so we've
920 already skipped past it. */
927 checked_print_quoted (dest
, segment
->text
, cp
);
930 case 's': /* size in bytes */
931 /* UNTRUSTED, probably unexploitable */
932 checked_fprintf (dest
, segment
->text
,
933 human_readable ((uintmax_t) stat_buf
->st_size
,
934 hbuf
, human_ceiling
, 1, 1));
937 case 'S': /* sparseness */
938 /* UNTRUSTED, probably unexploitable */
939 checked_fprintf (dest
, segment
->text
, file_sparseness(stat_buf
));;
942 case 't': /* mtime in `ctime' format */
943 /* UNTRUSTED, probably unexploitable */
944 checked_fprintf (dest
, segment
->text
,
945 ctime_format (get_stat_mtime(stat_buf
)));
948 case 'u': /* user name */
950 /* (well, the actual user is selected by the user on systems
951 * where chown is not restricted, but the user name was
952 * selected by the system administrator)
957 p
= getpwuid (stat_buf
->st_uid
);
960 segment
->text
[segment
->text_len
] = 's';
961 checked_fprintf (dest
, segment
->text
, p
->pw_name
);
966 /* FALLTHROUGH*/ /* .. to case U */
968 case 'U': /* UID number */
969 /* UNTRUSTED, probably unexploitable */
970 checked_fprintf (dest
, segment
->text
,
971 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
972 human_ceiling
, 1, 1));
975 /* %Y: type of file system entry like `ls -l`:
976 * (d,-,l,s,p,b,c,n) n=nonexistent(symlink)
978 case 'Y': /* in case of symlink */
982 if (S_ISLNK (stat_buf
->st_mode
))
985 /* If we would normally follow links, do not do so.
986 * If we would normally not follow links, do so.
988 if ((following_links() ? lstat
: stat
)
989 (state
.rel_pathname
, &sbuf
) != 0)
991 if ( errno
== ENOENT
)
993 checked_fprintf (dest
, segment
->text
, "N");
996 else if ( errno
== ELOOP
)
998 checked_fprintf (dest
, segment
->text
, "L");
1003 checked_fprintf (dest
, segment
->text
, "?");
1004 error (0, errno
, "%s",
1005 safely_quote_err_filename(0, pathname
));
1011 checked_fprintf (dest
, segment
->text
,
1012 mode_to_filetype(sbuf
.st_mode
& S_IFMT
));
1014 #endif /* S_ISLNK */
1017 checked_fprintf (dest
, segment
->text
,
1018 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
1026 checked_fprintf (dest
, segment
->text
,
1027 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
1031 /* end of KIND_FORMAT case */
1037 pred_fprintf (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1039 struct format_val
*dest
= &pred_ptr
->args
.printf_vec
;
1040 struct segment
*segment
;
1042 for (segment
= dest
->segment
; segment
; segment
= segment
->next
)
1044 if ( (KIND_FORMAT
== segment
->segkind
) && segment
->format_char
[1]) /* Component of date. */
1049 switch (segment
->format_char
[0])
1052 ts
= get_stat_atime(stat_buf
);
1056 ts
= get_stat_birthtime(stat_buf
);
1057 if ('@' == segment
->format_char
[1])
1060 valid
= (ts
.tv_nsec
>= 0);
1063 ts
= get_stat_ctime(stat_buf
);
1067 ts
= get_stat_mtime(stat_buf
);
1074 /* We trust the output of format_date not to contain
1075 * nasty characters, though the value of the date
1076 * is itself untrusted data.
1081 checked_fprintf (dest
, segment
->text
,
1082 format_date (ts
, segment
->format_char
[1]));
1086 /* The specified timestamp is not available, output
1087 * nothing for the timestamp, but use the rest (so that
1088 * for example find foo -printf '[%Bs] %p\n' can print
1092 checked_fprintf (dest
, segment
->text
, "");
1097 /* Print a segment which is not a date. */
1098 do_fprintf(dest
, segment
, pathname
, stat_buf
);
1105 pred_fstype (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1109 if (strcmp (filesystem_type (stat_buf
, pathname
), pred_ptr
->args
.str
) == 0)
1116 pred_gid (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1120 switch (pred_ptr
->args
.numinfo
.kind
)
1123 if (stat_buf
->st_gid
> pred_ptr
->args
.numinfo
.l_val
)
1127 if (stat_buf
->st_gid
< pred_ptr
->args
.numinfo
.l_val
)
1131 if (stat_buf
->st_gid
== pred_ptr
->args
.numinfo
.l_val
)
1139 pred_group (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1143 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
1150 pred_ilname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1152 return match_lname (pathname
, stat_buf
, pred_ptr
, true);
1156 pred_iname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1162 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1163 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1165 base
= base_name (pathname
);
1166 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
1172 pred_inum (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1176 switch (pred_ptr
->args
.numinfo
.kind
)
1179 if (stat_buf
->st_ino
> pred_ptr
->args
.numinfo
.l_val
)
1183 if (stat_buf
->st_ino
< pred_ptr
->args
.numinfo
.l_val
)
1187 if (stat_buf
->st_ino
== pred_ptr
->args
.numinfo
.l_val
)
1195 pred_ipath (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1199 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
1205 pred_links (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1209 switch (pred_ptr
->args
.numinfo
.kind
)
1212 if (stat_buf
->st_nlink
> pred_ptr
->args
.numinfo
.l_val
)
1216 if (stat_buf
->st_nlink
< pred_ptr
->args
.numinfo
.l_val
)
1220 if (stat_buf
->st_nlink
== pred_ptr
->args
.numinfo
.l_val
)
1228 pred_lname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1230 return match_lname (pathname
, stat_buf
, pred_ptr
, false);
1234 match_lname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
1236 boolean ret
= false;
1238 if (S_ISLNK (stat_buf
->st_mode
))
1240 char *linkname
= get_link_name_at (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
);
1243 if (fnmatch (pred_ptr
->args
.str
, linkname
,
1244 ignore_case
? FNM_CASEFOLD
: 0) == 0)
1249 #endif /* S_ISLNK */
1254 pred_ls (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1256 return pred_fls(pathname
, stat_buf
, pred_ptr
);
1260 pred_mmin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1263 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, 60);
1267 pred_mtime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1270 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, DAYSECS
);
1274 pred_name (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1279 base
= base_name (pathname
);
1281 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1282 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1284 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1290 pred_negate (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1292 return !apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
1296 pred_newer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1300 assert (COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1301 return compare_ts(get_stat_mtime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
1305 pred_newerXY (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1308 boolean collected
= false;
1310 assert (COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1312 switch (pred_ptr
->args
.reftime
.xval
)
1315 assert (pred_ptr
->args
.reftime
.xval
!= XVAL_TIME
);
1319 ts
= get_stat_atime(stat_buf
);
1323 case XVAL_BIRTHTIME
:
1324 ts
= get_stat_birthtime(stat_buf
);
1326 if (ts
.tv_nsec
< 0);
1328 /* XXX: Cannot determine birth time. Warn once. */
1329 error(0, 0, _("Warning: cannot determine birth time of file %s"),
1330 safely_quote_err_filename(0, pathname
));
1336 ts
= get_stat_ctime(stat_buf
);
1341 ts
= get_stat_mtime(stat_buf
);
1347 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
1351 pred_nogroup (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1357 extern char *gid_unused
;
1359 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1361 return getgrgid (stat_buf
->st_gid
) == NULL
;
1366 pred_nouser (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1369 extern char *uid_unused
;
1376 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1378 return getpwuid (stat_buf
->st_uid
) == NULL
;
1384 is_ok(const char *program
, const char *arg
)
1387 /* The draft open standard requires that, in the POSIX locale,
1388 the last non-blank character of this prompt be '?'.
1389 The exact format is not specified.
1390 This standard does not have requirements for locales other than POSIX
1392 /* XXX: printing UNTRUSTED data here. */
1393 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1399 pred_ok (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1401 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1402 return new_impl_pred_exec (get_start_dirfd(),
1403 pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1409 pred_okdir (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1411 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
1412 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1413 return new_impl_pred_exec (get_current_dirfd(),
1414 state
.rel_pathname
, stat_buf
, pred_ptr
,
1415 prefix
, (prefix
? 2 : 0));
1421 pred_openparen (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1430 pred_or (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1432 if (pred_ptr
->pred_left
== NULL
1433 || !apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_left
))
1435 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
1442 pred_path (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1445 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1451 pred_perm (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1453 mode_t mode
= stat_buf
->st_mode
;
1454 mode_t perm_val
= pred_ptr
->args
.perm
.val
[S_ISDIR (mode
) != 0];
1456 switch (pred_ptr
->args
.perm
.kind
)
1459 return (mode
& perm_val
) == perm_val
;
1463 /* True if any of the bits set in the mask are also set in the file's mode.
1466 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1467 * evaluate as true if at least all of the bits specified in
1468 * onum that are also set in the octal mask 07777 are set.
1470 * Eric Blake's interpretation is that the mode argument is zero,
1474 return true; /* Savannah bug 14748; we used to return false */
1476 return (mode
& perm_val
) != 0;
1480 return (mode
& MODE_ALL
) == perm_val
;
1490 struct access_check_args
1492 const char *filename
;
1499 access_callback(void *context
)
1502 struct access_check_args
*args
= context
;
1503 if ((rv
= access(args
->filename
, args
->access_type
)) < 0)
1504 args
->cb_errno
= errno
;
1509 can_access(int access_type
)
1511 struct access_check_args args
;
1512 args
.filename
= state
.rel_pathname
;
1513 args
.access_type
= access_type
;
1515 return 0 == run_in_dir(state
.cwd_dir_fd
, access_callback
, &args
);
1520 pred_executable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1526 return can_access(X_OK
);
1530 pred_readable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1536 return can_access(R_OK
);
1540 pred_writable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1546 return can_access(W_OK
);
1550 pred_print (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1555 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
1556 pred_ptr
->args
.printf_vec
.quote_opts
,
1557 pred_ptr
->args
.printf_vec
.dest_is_tty
,
1563 pred_print0 (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1565 return pred_fprint0(pathname
, stat_buf
, pred_ptr
);
1569 pred_prune (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1574 if (options
.do_dir_first
== true &&
1576 S_ISDIR(stat_buf
->st_mode
))
1577 state
.stop_at_current_level
= true;
1579 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1583 pred_quit (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1589 /* Run any cleanups. This includes executing any command lines
1590 * we have partly built but not executed.
1594 /* Since -exec and friends don't leave child processes running in the
1595 * background, there is no need to wait for them here.
1597 exit(state
.exit_status
); /* 0 for success, etc. */
1601 pred_regex (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1603 int len
= strlen (pathname
);
1605 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1606 (struct re_registers
*) NULL
) == len
)
1612 pred_size (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1617 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1618 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1619 switch (pred_ptr
->args
.size
.kind
)
1622 if (f_val
> pred_ptr
->args
.size
.size
)
1626 if (f_val
< pred_ptr
->args
.size
.size
)
1630 if (f_val
== pred_ptr
->args
.size
.size
)
1638 pred_samefile (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1640 /* Potential optimisation: because of the loop protection, we always
1641 * know the device of the current directory, hence the device number
1642 * of the file we're currently considering. If -L is not in effect,
1643 * and the device number of the file we're looking for is not the
1644 * same as the device number of the current directory, this
1645 * predicate cannot return true. Hence there would be no need to
1646 * stat the file we're looking at.
1650 /* We will often still have an fd open on the file under consideration,
1651 * but that's just to ensure inode number stability by maintaining
1652 * a reference to it; we don't need the file for anything else.
1654 return stat_buf
->st_ino
== pred_ptr
->args
.samefileid
.ino
1655 && stat_buf
->st_dev
== pred_ptr
->args
.samefileid
.dev
;
1659 pred_true (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1668 pred_type (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1671 mode_t type
= pred_ptr
->args
.type
;
1673 assert (state
.have_type
);
1675 if (0 == state
.type
)
1677 /* This can sometimes happen with broken NFS servers.
1678 * See Savannah bug #16378.
1685 if (state
.have_stat
)
1686 mode
= stat_buf
->st_mode
;
1691 /* POSIX system; check `mode' the slow way. */
1692 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1693 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1694 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1695 || (S_ISREG (mode
) && type
== S_IFREG
)
1697 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1700 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1703 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1706 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1710 /* Unix system; check `mode' the fast way. */
1711 if ((mode
& S_IFMT
) == type
)
1719 pred_uid (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1722 switch (pred_ptr
->args
.numinfo
.kind
)
1725 if (stat_buf
->st_uid
> pred_ptr
->args
.numinfo
.l_val
)
1729 if (stat_buf
->st_uid
< pred_ptr
->args
.numinfo
.l_val
)
1733 if (stat_buf
->st_uid
== pred_ptr
->args
.numinfo
.l_val
)
1741 pred_used (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1743 struct timespec delta
, at
, ct
;
1747 /* TODO: this needs to be retested carefully (manually, if necessary) */
1748 at
= get_stat_atime(stat_buf
);
1749 ct
= get_stat_ctime(stat_buf
);
1750 delta
.tv_sec
= at
.tv_sec
- ct
.tv_sec
;
1751 delta
.tv_nsec
= at
.tv_nsec
- ct
.tv_nsec
;
1752 if (delta
.tv_nsec
< 0)
1754 delta
.tv_nsec
+= 1000000000;
1757 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1761 pred_user (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1764 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1771 pred_xtype (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1773 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1774 int (*ystat
) (const char*, struct stat
*p
);
1776 /* If we would normally stat the link itself, stat the target instead.
1777 * If we would normally follow the link, stat the link itself instead.
1779 if (following_links())
1780 ystat
= optionp_stat
;
1782 ystat
= optionl_stat
;
1784 set_stat_placeholders(&sbuf
);
1785 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1787 if (following_links() && errno
== ENOENT
)
1789 /* If we failed to follow the symlink,
1790 * fall back on looking at the symlink itself.
1792 /* Mimic behavior of ls -lL. */
1793 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1797 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
1798 state
.exit_status
= 1;
1802 /* Now that we have our stat() information, query it in the same
1803 * way that -type does.
1805 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1808 /* 1) fork to get a child; parent remembers the child pid
1809 2) child execs the command requested
1810 3) parent waits for child; checks for proper pid of child
1814 ret errno status(h) status(l)
1816 pid x signal# 0177 stopped
1817 pid x exit arg 0 term by _exit
1818 pid x 0 signal # term by signal
1819 -1 EINTR parent got signal
1820 -1 other some other kind of error
1822 Return true only if the pid matches, status(l) is
1823 zero, and the exit arg (status high) is 0.
1824 Otherwise return false, possibly printing an error message. */
1828 prep_child_for_exec (boolean close_stdin
, int dirfd
)
1833 const char inputfile
[] = "/dev/null";
1837 error(0, errno
, _("Cannot close standard input"));
1842 if (open(inputfile
, O_RDONLY
1843 #if defined O_LARGEFILE
1848 /* This is not entirely fatal, since
1849 * executing the child with a closed
1850 * stdin is almost as good as executing it
1851 * with its stdin attached to /dev/null.
1853 error (0, errno
, "%s", safely_quote_err_filename(0, inputfile
));
1854 /* do not set ok=false, it is OK to continue anyway. */
1859 /* Even if DebugSearch is set, don't announce our change of
1860 * directory, since we're not going to emit a subsequent
1861 * announcement of a call to stat() anyway, as we're about to exec
1864 if (dirfd
!= AT_FDCWD
)
1866 assert (dirfd
>= 0);
1867 if (0 != fchdir(dirfd
))
1869 /* If we cannot execute our command in the correct directory,
1870 * we should not execute it at all.
1872 error(0, errno
, _("Failed to change directory"));
1882 launch (const struct buildcmd_control
*ctl
,
1883 struct buildcmd_state
*buildstate
)
1887 static int first_time
= 1;
1888 const struct exec_val
*execp
= buildstate
->usercontext
;
1890 if (!execp
->use_current_dir
)
1892 assert (starting_desc
>= 0);
1893 assert (execp
->dirfd
== starting_desc
);
1897 /* Null terminate the arg list. */
1898 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1900 /* Make sure output of command doesn't get mixed with find output. */
1904 /* Make sure to listen for the kids. */
1908 signal (SIGCHLD
, SIG_DFL
);
1911 child_pid
= fork ();
1912 if (child_pid
== -1)
1913 error (1, errno
, _("cannot fork"));
1916 /* We are the child. */
1917 assert (starting_desc
>= 0);
1918 if (!prep_child_for_exec(execp
->close_stdin
, execp
->dirfd
))
1923 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1924 error (0, errno
, "%s",
1925 safely_quote_err_filename(0, buildstate
->cmd_argv
[0]));
1930 /* In parent; set up for next time. */
1931 bc_clear_args(ctl
, buildstate
);
1934 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1938 error (0, errno
, _("error waiting for %s"),
1939 safely_quote_err_filename(0, buildstate
->cmd_argv
[0]));
1940 state
.exit_status
= 1;
1941 return 0; /* FAIL */
1945 if (WIFSIGNALED (wait_status
))
1947 error (0, 0, _("%s terminated by signal %d"),
1948 quotearg_n_style(0, options
.err_quoting_style
,
1949 buildstate
->cmd_argv
[0]),
1950 WTERMSIG (wait_status
));
1952 if (execp
->multiple
)
1954 /* -exec \; just returns false if the invoked command fails.
1955 * -exec {} + returns true if the invoked command fails, but
1956 * sets the program exit status.
1958 state
.exit_status
= 1;
1964 if (0 == WEXITSTATUS (wait_status
))
1970 if (execp
->multiple
)
1972 /* -exec \; just returns false if the invoked command fails.
1973 * -exec {} + returns true if the invoked command fails, but
1974 * sets the program exit status.
1976 state
.exit_status
= 1;
1978 return 0; /* FAIL */
1984 /* Return a static string formatting the time WHEN according to the
1985 * strftime format character KIND.
1987 * This function contains a number of assertions. These look like
1988 * runtime checks of the results of computations, which would be a
1989 * problem since external events should not be tested for with
1990 * "assert" (instead you should use "if"). However, they are not
1991 * really runtime checks. The assertions actually exist to verify
1992 * that the various buffers are correctly sized.
1995 format_date (struct timespec ts
, int kind
)
1997 /* In theory, we use an extra 10 characters for 9 digits of
1998 * nanoseconds and 1 for the decimal point. However, the real
1999 * world is more complex than that.
2001 * For example, some systems return junk in the tv_nsec part of
2002 * st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
2003 * (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
2004 * runtime and examining files on an msdos filesytem. So for that
2005 * reason we set NS_BUF_LEN to 32, which is simply "long enough" as
2006 * opposed to "exactly the right size". Note that the behaviour of
2007 * NetBSD appears to be a result of the use of uninitialised data,
2008 * as it's not 100% reproducible (more like 25%).
2012 DATE_LEN_PERCENT_APLUS
=21 /* length of result of %A+ (it's longer than %c)*/
2014 static char buf
[128u+10u + MAX(DATE_LEN_PERCENT_APLUS
,
2015 MAX (LONGEST_HUMAN_READABLE
+ 2, NS_BUF_LEN
+64+200))];
2016 char ns_buf
[NS_BUF_LEN
]; /* -.9999999990 (- sign can happen!)*/
2017 int charsprinted
, need_ns_suffix
;
2021 /* human_readable() assumes we pass a buffer which is at least as
2022 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
2023 * ensure that no nasty unsigned overflow happend in our calculation
2024 * of the size of buf. Do the assertion here rather than in the
2025 * code for %@ so that we find the problem quickly if it exists. If
2026 * you want to submit a patch to move this into the if statement, go
2027 * ahead, I'll apply it. But include performance timings
2028 * demonstrating that the performance difference is actually
2031 verify (sizeof(buf
) >= LONGEST_HUMAN_READABLE
);
2036 /* Format the main part of the time. */
2039 strcpy (fmt
, "%F+%T");
2048 /* %a, %c, and %t are handled in ctime_format() */
2065 /* Format the nanoseconds part. Leave a trailing zero to
2066 * discourage people from writing scripts which extract the
2067 * fractional part of the timestamp by using column offsets.
2068 * The reason for discouraging this is that in the future, the
2069 * granularity may not be nanoseconds.
2072 charsprinted
= snprintf(ns_buf
, NS_BUF_LEN
, ".%09ld0", (long int)ts
.tv_nsec
);
2073 assert (charsprinted
< NS_BUF_LEN
);
2077 && (tm
= localtime (&ts
.tv_sec
))
2078 && strftime (buf
, sizeof buf
, fmt
, tm
))
2080 /* For %AS, %CS, %TS, add the fractional part of the seconds
2085 assert ((sizeof buf
- strlen(buf
)) > strlen(ns_buf
));
2086 strcat(buf
, ns_buf
);
2092 uintmax_t w
= ts
.tv_sec
;
2093 size_t used
, len
, remaining
;
2095 /* XXX: note that we are negating an unsigned type which is the
2096 * widest possible unsigned type.
2098 char *p
= human_readable (ts
.tv_sec
< 0 ? -w
: w
, buf
+ 1,
2099 human_ceiling
, 1, 1);
2101 assert (p
< (buf
+ (sizeof buf
)));
2103 *--p
= '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
2105 /* Add the nanoseconds part. Because we cannot enforce a
2106 * particlar implementation of human_readable, we cannot assume
2107 * any particular value for (p-buf). So we need to be careful
2108 * that there is enough space remaining in the buffer.
2113 used
= (p
-buf
) + len
; /* Offset into buf of current end */
2114 assert (sizeof buf
> used
); /* Ensure we can perform subtraction safely. */
2115 remaining
= sizeof buf
- used
- 1u; /* allow space for NUL */
2117 if (strlen(ns_buf
) >= remaining
)
2120 "charsprinted=%ld but remaining=%lu: ns_buf=%s",
2121 (long)charsprinted
, (unsigned long)remaining
, ns_buf
);
2123 assert (strlen(ns_buf
) < remaining
);
2130 static const char *weekdays
[] =
2132 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
2134 static char * months
[] =
2136 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2137 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2142 ctime_format (struct timespec ts
)
2144 const struct tm
* ptm
;
2145 #define TIME_BUF_LEN 1024u
2146 static char resultbuf
[TIME_BUF_LEN
];
2149 ptm
= localtime(&ts
.tv_sec
);
2152 assert (ptm
->tm_wday
>= 0);
2153 assert (ptm
->tm_wday
< 7);
2154 assert (ptm
->tm_mon
>= 0);
2155 assert (ptm
->tm_mon
< 12);
2156 assert (ptm
->tm_hour
>= 0);
2157 assert (ptm
->tm_hour
< 24);
2158 assert (ptm
->tm_min
< 60);
2159 assert (ptm
->tm_sec
<= 61); /* allows 2 leap seconds. */
2161 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
2162 nout
= snprintf(resultbuf
, TIME_BUF_LEN
,
2163 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
2164 weekdays
[ptm
->tm_wday
],
2165 months
[ptm
->tm_mon
],
2170 (long int)ts
.tv_nsec
,
2171 1900 + ptm
->tm_year
);
2173 assert (nout
< TIME_BUF_LEN
);
2178 /* The time cannot be represented as a struct tm.
2179 Output it as an integer. */
2180 return format_date (ts
, '@');
2184 /* Copy STR into BUF and trim blanks from the end of BUF.
2188 blank_rtrim (str
, buf
)
2197 i
= strlen (buf
) - 1;
2198 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
2204 /* Print out the predicate list starting at NODE. */
2206 print_list (FILE *fp
, struct predicate
*node
)
2208 struct predicate
*cur
;
2214 fprintf (fp
, "[%s] ", blank_rtrim (cur
->p_name
, name
));
2215 cur
= cur
->pred_next
;
2220 /* Print out the predicate list starting at NODE. */
2222 print_parenthesised(FILE *fp
, struct predicate
*node
)
2228 if ((pred_is(node
, pred_or
) || pred_is(node
, pred_and
))
2229 && node
->pred_left
== NULL
)
2231 /* We print "<nothing> or X" as just "X"
2232 * We print "<nothing> and X" as just "X"
2234 print_parenthesised(fp
, node
->pred_right
);
2238 if (node
->pred_left
|| node
->pred_right
)
2242 fprintf(fp
, "%s", " ( ");
2243 print_optlist(fp
, node
);
2245 fprintf(fp
, "%s", " ) ");
2251 print_optlist (FILE *fp
, const struct predicate
*p
)
2255 print_parenthesised(fp
, p
->pred_left
);
2258 p
->need_stat
? "[call stat] " : "",
2259 p
->need_type
? "[need type] " : "");
2260 print_predicate(fp
, p
);
2261 fprintf(fp
, " [%g] ", p
->est_success_rate
);
2262 if (options
.debug_options
& DebugSuccessRates
)
2264 fprintf(fp
, "[%ld/%ld", p
->perf
.successes
, p
->perf
.visits
);
2267 double real_rate
= (double)p
->perf
.successes
/ (double)p
->perf
.visits
;
2268 fprintf(fp
, "=%g] ", real_rate
);
2272 fprintf(fp
, "=_] ");
2275 print_parenthesised(fp
, p
->pred_right
);
2279 void show_success_rates(const struct predicate
*p
)
2281 if (options
.debug_options
& DebugSuccessRates
)
2283 fprintf(stderr
, "Predicate success rates after completion:\n");
2284 print_optlist(stderr
, p
);
2285 fprintf(stderr
, "\n");
2293 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2294 * there is no point in having a function body for pred_sanity_check()
2295 * if that preprocessor macro is defined.
2298 pred_sanity_check(const struct predicate
*predicates
)
2300 /* Do nothing, since assert is a no-op with _NDEBUG set */
2305 pred_sanity_check(const struct predicate
*predicates
)
2307 const struct predicate
*p
;
2309 for (p
=predicates
; p
!= NULL
; p
=p
->pred_next
)
2311 /* All predicates must do something. */
2312 assert (p
->pred_func
!= NULL
);
2314 /* All predicates must have a parser table entry. */
2315 assert (p
->parser_entry
!= NULL
);
2317 /* If the parser table tells us that just one predicate function is
2318 * possible, verify that that is still the one that is in effect.
2319 * If the parser has NULL for the predicate function, that means that
2320 * the parse_xxx function fills it in, so we can't check it.
2322 if (p
->parser_entry
->pred_func
)
2324 assert (p
->parser_entry
->pred_func
== p
->pred_func
);
2327 switch (p
->parser_entry
->type
)
2329 /* Options all take effect during parsing, so there should
2330 * be no predicate entries corresponding to them. Hence we
2331 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2334 * This is a silly way of coding this test, but it prevents
2335 * a compiler warning (i.e. otherwise it would think that
2336 * there would be case statements missing).
2339 case ARG_POSITIONAL_OPTION
:
2340 assert (p
->parser_entry
->type
!= ARG_OPTION
);
2341 assert (p
->parser_entry
->type
!= ARG_POSITIONAL_OPTION
);
2345 assert(p
->side_effects
); /* actions have side effects. */
2346 if (!pred_is(p
, pred_prune
) && !pred_is(p
, pred_quit
))
2348 /* actions other than -prune and -quit should
2349 * inhibit the default -print
2351 assert (p
->no_default_print
);
2355 /* We happen to know that the only user of ARG_SPECIAL_PARSE
2356 * is a test, so handle it like ARG_TEST.
2358 case ARG_SPECIAL_PARSE
:
2360 case ARG_PUNCTUATION
:
2362 /* Punctuation and tests should have no side
2363 * effects and not inhibit default print.
2365 assert (!p
->no_default_print
);
2366 assert (!p
->side_effects
);