1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 #include <sys/types.h>
30 #include "../gnulib/lib/xalloc.h"
31 #include "../gnulib/lib/dirname.h"
32 #include "../gnulib/lib/human.h"
40 # define _(Text) gettext (Text)
45 # define N_(String) gettext_noop (String)
47 /* See locate.c for explanation as to why not use (String) */
48 # define N_(String) String
51 #if !defined(SIGCHLD) && defined(SIGCLD)
52 #define SIGCHLD SIGCLD
57 # define NAMLEN(dirent) strlen((dirent)->d_name)
59 # define dirent direct
60 # define NAMLEN(dirent) (dirent)->d_namlen
62 # include <sys/ndir.h>
73 /* Fake a return value. */
74 #define CLOSEDIR(d) (closedir (d), 0)
76 #define CLOSEDIR(d) closedir (d)
82 /* Get or fake the disk device blocksize.
83 Usually defined by sys/param.h (if at all). */
86 # define DEV_BSIZE BSIZE
88 # define DEV_BSIZE 4096
90 #endif /* !DEV_BSIZE */
92 /* Extract or fake data from a `struct stat'.
93 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
94 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
95 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
96 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
97 # define ST_BLKSIZE(statbuf) DEV_BSIZE
98 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
99 # define ST_NBLOCKS(statbuf) \
100 (S_ISREG ((statbuf).st_mode) \
101 || S_ISDIR ((statbuf).st_mode) \
102 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
103 # else /* !_POSIX_SOURCE && BSIZE */
104 # define ST_NBLOCKS(statbuf) \
105 (S_ISREG ((statbuf).st_mode) \
106 || S_ISDIR ((statbuf).st_mode) \
107 ? st_blocks ((statbuf).st_size) : 0)
108 # endif /* !_POSIX_SOURCE && BSIZE */
109 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
110 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
111 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
112 ? (statbuf).st_blksize : DEV_BSIZE)
113 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
114 /* HP-UX counts st_blocks in 1024-byte units.
115 This loses when mixing HP-UX and BSD filesystems with NFS. */
116 # define ST_NBLOCKSIZE 1024
118 # if defined(_AIX) && defined(_I386)
119 /* AIX PS/2 counts st_blocks in 4K units. */
120 # define ST_NBLOCKSIZE (4 * 1024)
121 # else /* not AIX PS/2 */
123 # define ST_NBLOCKS(statbuf) \
124 (S_ISREG ((statbuf).st_mode) \
125 || S_ISDIR ((statbuf).st_mode) \
126 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
128 # endif /* not AIX PS/2 */
130 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
133 # define ST_NBLOCKS(statbuf) \
134 (S_ISREG ((statbuf).st_mode) \
135 || S_ISDIR ((statbuf).st_mode) \
136 ? (statbuf).st_blocks : 0)
139 #ifndef ST_NBLOCKSIZE
140 # define ST_NBLOCKSIZE 512
144 #define MAX(a, b) ((a) > (b) ? (a) : (b))
146 static boolean insert_lname
PARAMS((char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
));
148 static char *format_date
PARAMS((time_t when
, int kind
));
149 static char *ctime_format
PARAMS((time_t when
));
158 struct pred_assoc pred_table
[] =
160 {pred_amin
, "amin "},
162 {pred_anewer
, "anewer "},
163 {pred_atime
, "atime "},
165 {pred_amin
, "cmin "},
166 {pred_cnewer
, "cnewer "},
168 {pred_ctime
, "ctime "},
169 {pred_delete
, "delete "},
170 {pred_empty
, "empty "},
171 {pred_exec
, "exec "},
172 {pred_execdir
, "execdir "},
173 {pred_false
, "false "},
174 {pred_fprint
, "fprint "},
175 {pred_fprint0
, "fprint0 "},
176 {pred_fprintf
, "fprintf "},
177 {pred_fstype
, "fstype "},
179 {pred_group
, "group "},
180 {pred_ilname
, "ilname "},
181 {pred_iname
, "iname "},
182 {pred_inum
, "inum "},
183 {pred_ipath
, "ipath "},
184 {pred_links
, "links "},
185 {pred_lname
, "lname "},
187 {pred_amin
, "mmin "},
188 {pred_mtime
, "mtime "},
189 {pred_name
, "name "},
190 {pred_negate
, "not "},
191 {pred_newer
, "newer "},
192 {pred_nogroup
, "nogroup "},
193 {pred_nouser
, "nouser "},
195 {pred_okdir
, "okdir "},
198 {pred_path
, "path "},
199 {pred_perm
, "perm "},
200 {pred_print
, "print "},
201 {pred_print0
, "print0 "},
202 {pred_prune
, "prune "},
203 {pred_regex
, "regex "},
204 {pred_samefile
,"samefile "},
205 {pred_size
, "size "},
206 {pred_true
, "true "},
207 {pred_type
, "type "},
209 {pred_used
, "used "},
210 {pred_user
, "user "},
211 {pred_xtype
, "xtype "},
221 struct op_assoc type_table
[] =
224 {PRIMARY_TYPE
, "primary "},
227 {OPEN_PAREN
, "open_paren "},
228 {CLOSE_PAREN
, "close_paren "},
238 struct prec_assoc prec_table
[] =
241 {COMMA_PREC
, "comma "},
244 {NEGATE_PREC
, "negate "},
250 /* Predicate processing routines.
252 PATHNAME is the full pathname of the file being checked.
253 *STAT_BUF contains information about PATHNAME.
254 *PRED_PTR contains information for applying the predicate.
256 Return true if the file passes this predicate, false if not. */
261 * Returns true if THE_TIME is
262 * COMP_GT: after the specified time
263 * COMP_LT: before the specified time
264 * COMP_EQ: less than WINDOW seconds after the specified time.
267 pred_timewindow(time_t the_time
, struct predicate
const *pred_ptr
, int window
)
269 switch (pred_ptr
->args
.info
.kind
)
272 if (the_time
> (time_t) pred_ptr
->args
.info
.l_val
)
276 if (the_time
< (time_t) pred_ptr
->args
.info
.l_val
)
280 if ((the_time
>= (time_t) pred_ptr
->args
.info
.l_val
)
281 && (the_time
< (time_t) pred_ptr
->args
.info
.l_val
+ window
))
290 pred_amin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
293 return pred_timewindow(stat_buf
->st_atime
, pred_ptr
, 60);
297 pred_and (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
299 if (pred_ptr
->pred_left
== NULL
300 || (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
301 pred_ptr
->pred_left
))
303 /* Check whether we need a stat here. */
304 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
306 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
307 pred_ptr
->pred_right
));
314 pred_anewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
318 if (stat_buf
->st_atime
> pred_ptr
->args
.time
)
324 pred_atime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
327 return pred_timewindow(stat_buf
->st_atime
, pred_ptr
, DAYSECS
);
331 pred_close (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
341 pred_cmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
344 return pred_timewindow(stat_buf
->st_ctime
, pred_ptr
, 60);
348 pred_cnewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
352 if (stat_buf
->st_ctime
> pred_ptr
->args
.time
)
359 pred_comma (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
361 if (pred_ptr
->pred_left
!= NULL
)
362 (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
363 pred_ptr
->pred_left
);
364 /* Check whether we need a stat here. */
365 /* TODO: what about need_type? */
366 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
368 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
369 pred_ptr
->pred_right
));
373 pred_ctime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
376 return pred_timewindow(stat_buf
->st_ctime
, pred_ptr
, DAYSECS
);
380 pred_delete (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
384 if (strcmp (state
.rel_pathname
, "."))
386 if (0 != remove (state
.rel_pathname
))
388 error (0, errno
, "cannot delete %s", pathname
);
402 pred_empty (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
407 if (S_ISDIR (stat_buf
->st_mode
))
411 boolean empty
= true;
414 d
= opendir (state
.rel_pathname
);
417 error (0, errno
, "%s", pathname
);
418 state
.exit_status
= 1;
421 for (dp
= readdir (d
); dp
; dp
= readdir (d
))
423 if (dp
->d_name
[0] != '.'
424 || (dp
->d_name
[1] != '\0'
425 && (dp
->d_name
[1] != '.' || dp
->d_name
[2] != '\0')))
433 error (0, errno
, "%s", pathname
);
434 state
.exit_status
= 1;
439 else if (S_ISREG (stat_buf
->st_mode
))
440 return (stat_buf
->st_size
== 0);
446 new_impl_pred_exec (const char *pathname
, struct stat
*stat_buf
,
447 struct predicate
*pred_ptr
,
448 const char *prefix
, size_t pfxlen
)
450 struct exec_val
*execp
= &pred_ptr
->args
.exec_vec
;
451 size_t len
= strlen(pathname
);
455 /* Push the argument onto the current list.
456 * The command may or may not be run at this point,
457 * depending on the command line length limits.
459 bc_push_arg(&execp
->ctl
,
465 /* POSIX: If the primary expression is punctuated by a plus
466 * sign, the primary shall always evaluate as true
474 for (i
=0; i
<execp
->num_args
; ++i
)
476 bc_do_insert(&execp
->ctl
,
478 execp
->replace_vec
[i
],
479 strlen(execp
->replace_vec
[i
]),
485 /* Actually invoke the command. */
486 return execp
->ctl
.exec_callback(&execp
->ctl
,
493 pred_exec (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
495 return new_impl_pred_exec(pathname
, stat_buf
, pred_ptr
, NULL
, 0);
499 pred_execdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
501 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
503 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
504 prefix
, (prefix
? 2 : 0));
508 pred_false (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
519 pred_fls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
521 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
522 options
.output_block_size
, pred_ptr
->args
.stream
);
527 pred_fprint (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
532 fputs (pathname
, pred_ptr
->args
.stream
);
533 putc ('\n', pred_ptr
->args
.stream
);
538 pred_fprint0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
543 fputs (pathname
, pred_ptr
->args
.stream
);
544 putc (0, pred_ptr
->args
.stream
);
549 pred_fprintf (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
551 FILE *fp
= pred_ptr
->args
.printf_vec
.stream
;
552 struct segment
*segment
;
554 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
556 for (segment
= pred_ptr
->args
.printf_vec
.segment
; segment
;
557 segment
= segment
->next
)
559 if (segment
->kind
& 0xff00) /* Component of date. */
563 switch (segment
->kind
& 0xff)
566 t
= stat_buf
->st_atime
;
569 t
= stat_buf
->st_ctime
;
572 t
= stat_buf
->st_mtime
;
577 fprintf (fp
, segment
->text
,
578 format_date (t
, (segment
->kind
>> 8) & 0xff));
582 switch (segment
->kind
)
584 case KIND_PLAIN
: /* Plain text string (no % conversion). */
585 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
587 case KIND_STOP
: /* Terminate argument and flush output. */
588 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
591 case 'a': /* atime in `ctime' format. */
592 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_atime
));
594 case 'b': /* size in 512-byte blocks */
595 fprintf (fp
, segment
->text
,
596 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
598 ST_NBLOCKSIZE
, 512));
600 case 'c': /* ctime in `ctime' format */
601 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_ctime
));
603 case 'd': /* depth in search tree */
604 fprintf (fp
, segment
->text
, state
.curdepth
);
606 case 'D': /* Device on which file exists (stat.st_dev) */
607 fprintf (fp
, segment
->text
,
608 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
609 human_ceiling
, 1, 1));
611 case 'f': /* base name of path */
612 fprintf (fp
, segment
->text
, base_name (pathname
));
614 case 'F': /* filesystem type */
615 fprintf (fp
, segment
->text
, filesystem_type (stat_buf
));
617 case 'g': /* group name */
621 g
= getgrgid (stat_buf
->st_gid
);
624 segment
->text
[segment
->text_len
] = 's';
625 fprintf (fp
, segment
->text
, g
->gr_name
);
630 case 'G': /* GID number */
631 fprintf (fp
, segment
->text
,
632 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
633 human_ceiling
, 1, 1));
635 case 'h': /* leading directories part of path */
639 cp
= strrchr (pathname
, '/');
640 if (cp
== NULL
) /* No leading directories. */
642 /* If there is no slash in the pathname, we still
643 * print the string because it contains characters
644 * other than just '%s'.
646 fprintf (fp
, segment
->text
, "");
652 fprintf (fp
, segment
->text
, pathname
);
657 case 'H': /* ARGV element file was found under */
659 char cc
= pathname
[state
.path_length
];
661 pathname
[state
.path_length
] = '\0';
662 fprintf (fp
, segment
->text
, pathname
);
663 pathname
[state
.path_length
] = cc
;
666 case 'i': /* inode number */
667 fprintf (fp
, segment
->text
,
668 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
672 case 'k': /* size in 1K blocks */
673 fprintf (fp
, segment
->text
,
674 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
676 ST_NBLOCKSIZE
, 1024));
678 case 'l': /* object of symlink */
683 if (S_ISLNK (stat_buf
->st_mode
))
685 linkname
= get_link_name (pathname
, state
.rel_pathname
);
687 state
.exit_status
= 1;
691 fprintf (fp
, segment
->text
, linkname
);
695 fprintf (fp
, segment
->text
, "");
700 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
702 char modestring
[16] ;
703 mode_string (stat_buf
->st_mode
, modestring
);
704 modestring
[10] = '\0';
705 fprintf (fp
, segment
->text
, modestring
);
709 case 'm': /* mode as octal number (perms only) */
711 /* Output the mode portably using the traditional numbers,
712 even if the host unwisely uses some other numbering
713 scheme. But help the compiler in the common case where
714 the host uses the traditional numbering scheme. */
715 mode_t m
= stat_buf
->st_mode
;
716 boolean traditional_numbering_scheme
=
717 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
718 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
719 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
720 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
721 fprintf (fp
, segment
->text
,
722 (traditional_numbering_scheme
724 : ((m
& S_ISUID
? 04000 : 0)
725 | (m
& S_ISGID
? 02000 : 0)
726 | (m
& S_ISVTX
? 01000 : 0)
727 | (m
& S_IRUSR
? 00400 : 0)
728 | (m
& S_IWUSR
? 00200 : 0)
729 | (m
& S_IXUSR
? 00100 : 0)
730 | (m
& S_IRGRP
? 00040 : 0)
731 | (m
& S_IWGRP
? 00020 : 0)
732 | (m
& S_IXGRP
? 00010 : 0)
733 | (m
& S_IROTH
? 00004 : 0)
734 | (m
& S_IWOTH
? 00002 : 0)
735 | (m
& S_IXOTH
? 00001 : 0))));
739 case 'n': /* number of links */
740 fprintf (fp
, segment
->text
,
741 human_readable ((uintmax_t) stat_buf
->st_nlink
,
746 case 'p': /* pathname */
747 fprintf (fp
, segment
->text
, pathname
);
749 case 'P': /* pathname with ARGV element stripped */
750 if (state
.curdepth
> 0)
752 cp
= pathname
+ state
.path_length
;
754 /* Move past the slash between the ARGV element
755 and the rest of the pathname. But if the ARGV element
756 ends in a slash, we didn't add another, so we've
757 already skipped past it. */
762 fprintf (fp
, segment
->text
, cp
);
764 case 's': /* size in bytes */
765 fprintf (fp
, segment
->text
,
766 human_readable ((uintmax_t) stat_buf
->st_size
,
767 hbuf
, human_ceiling
, 1, 1));
769 case 't': /* mtime in `ctime' format */
770 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_mtime
));
772 case 'u': /* user name */
776 p
= getpwuid (stat_buf
->st_uid
);
779 segment
->text
[segment
->text_len
] = 's';
780 fprintf (fp
, segment
->text
, p
->pw_name
);
786 case 'U': /* UID number */
787 fprintf (fp
, segment
->text
,
788 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
789 human_ceiling
, 1, 1));
792 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
793 case 'Y': /* in case of symlink */
796 if (S_ISLNK (stat_buf
->st_mode
))
799 /* If we would normally follow links, do not do so.
800 * If we would normally not follow links, do so.
802 if ((following_links() ? lstat
: stat
)
803 (state
.rel_pathname
, &sbuf
) != 0)
805 if ( errno
== ENOENT
) {
806 fprintf (fp
, segment
->text
, "N");
809 if ( errno
== ELOOP
) {
810 fprintf (fp
, segment
->text
, "L");
813 error (0, errno
, "%s", pathname
);
817 stat_buf
->st_mode
= sbuf
.st_mode
;
824 mode_t m
= stat_buf
->st_mode
& S_IFMT
;
826 fprintf (fp
, segment
->text
,
827 ( m
== S_IFSOCK
? "s" :
834 m
== S_IFDOOR
? "D" :
836 m
== S_IFIFO
? "p" : "U" ) );
846 pred_fstype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
850 if (strcmp (filesystem_type (stat_buf
), pred_ptr
->args
.str
) == 0)
857 pred_gid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
861 switch (pred_ptr
->args
.info
.kind
)
864 if (stat_buf
->st_gid
> pred_ptr
->args
.info
.l_val
)
868 if (stat_buf
->st_gid
< pred_ptr
->args
.info
.l_val
)
872 if (stat_buf
->st_gid
== pred_ptr
->args
.info
.l_val
)
880 pred_group (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
884 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
891 pred_ilname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
893 return insert_lname (pathname
, stat_buf
, pred_ptr
, true);
897 pred_iname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
903 /* FNM_PERIOD is not used here because POSIX requires that it not be.
904 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
906 base
= base_name (pathname
);
907 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
913 pred_inum (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
917 switch (pred_ptr
->args
.info
.kind
)
920 if (stat_buf
->st_ino
> pred_ptr
->args
.info
.l_val
)
924 if (stat_buf
->st_ino
< pred_ptr
->args
.info
.l_val
)
928 if (stat_buf
->st_ino
== pred_ptr
->args
.info
.l_val
)
936 pred_ipath (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
940 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
946 pred_links (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
950 switch (pred_ptr
->args
.info
.kind
)
953 if (stat_buf
->st_nlink
> pred_ptr
->args
.info
.l_val
)
957 if (stat_buf
->st_nlink
< pred_ptr
->args
.info
.l_val
)
961 if (stat_buf
->st_nlink
== pred_ptr
->args
.info
.l_val
)
969 pred_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
971 return insert_lname (pathname
, stat_buf
, pred_ptr
, false);
975 insert_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
979 if (S_ISLNK (stat_buf
->st_mode
))
981 char *linkname
= get_link_name (pathname
, state
.rel_pathname
);
984 if (fnmatch (pred_ptr
->args
.str
, linkname
,
985 ignore_case
? FNM_CASEFOLD
: 0) == 0)
995 pred_ls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
999 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
1000 options
.output_block_size
, stdout
);
1005 pred_mmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1008 return pred_timewindow(stat_buf
->st_mtime
, pred_ptr
, 60);
1012 pred_mtime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1015 return pred_timewindow(stat_buf
->st_mtime
, pred_ptr
, DAYSECS
);
1019 pred_name (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1024 base
= base_name (pathname
);
1026 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1027 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1029 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1035 pred_negate (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1037 /* Check whether we need a stat here. */
1038 /* TODO: what about need_type? */
1039 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1041 return (!(*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1042 pred_ptr
->pred_right
));
1046 pred_newer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1050 if (stat_buf
->st_mtime
> pred_ptr
->args
.time
)
1056 pred_nogroup (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1062 extern char *gid_unused
;
1064 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1066 return getgrgid (stat_buf
->st_gid
) == NULL
;
1071 pred_nouser (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1074 extern char *uid_unused
;
1081 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1083 return getpwuid (stat_buf
->st_uid
) == NULL
;
1089 is_ok(const char *program
, const char *arg
)
1092 /* The draft open standard requires that, in the POSIX locale,
1093 the last non-blank character of this prompt be '?'.
1094 The exact format is not specified.
1095 This standard does not have requirements for locales other than POSIX
1097 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1103 pred_ok (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1105 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1106 return new_impl_pred_exec (pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1112 pred_okdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1114 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
1115 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1116 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
1117 prefix
, (prefix
? 2 : 0));
1123 pred_open (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1132 pred_or (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1134 if (pred_ptr
->pred_left
== NULL
1135 || !(*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
1136 pred_ptr
->pred_left
))
1138 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1140 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1141 pred_ptr
->pred_right
));
1148 pred_path (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1151 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1157 pred_perm (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1160 switch (pred_ptr
->args
.perm
.kind
)
1163 return (stat_buf
->st_mode
& pred_ptr
->args
.perm
.val
) == pred_ptr
->args
.perm
.val
;
1167 return (stat_buf
->st_mode
& pred_ptr
->args
.perm
.val
) != 0;
1171 return (stat_buf
->st_mode
& MODE_ALL
) == pred_ptr
->args
.perm
.val
;
1181 pred_print (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1190 pred_print0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1194 fputs (pathname
, stdout
);
1200 pred_prune (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1205 state
.stop_at_current_level
= true;
1206 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1210 pred_quit (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1216 /* Run any cleanups. This includes executing any command lines
1217 * we have partly built but not executed.
1221 /* Since -exec and friends don't leave child processes running in the
1222 * background, there is no need to wait for them here.
1224 exit(state
.exit_status
); /* 0 for success, etc. */
1228 pred_regex (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1230 int len
= strlen (pathname
);
1232 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1233 (struct re_registers
*) NULL
) == len
)
1239 pred_size (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1244 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1245 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1246 switch (pred_ptr
->args
.size
.kind
)
1249 if (f_val
> pred_ptr
->args
.size
.size
)
1253 if (f_val
< pred_ptr
->args
.size
.size
)
1257 if (f_val
== pred_ptr
->args
.size
.size
)
1265 pred_samefile (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1267 /* Potential optimisation: because of the loop protection, we
1268 * always know the device of the current directory, hence the
1269 * device number of the current filesystem. If -L is not in
1270 * effect, and the device number of the file we're looking for
1271 * is not the same as the device number of the current directory,
1272 * this predicate cannot return true. Hence there would be no
1273 * need to stat the file.
1275 return stat_buf
->st_ino
== pred_ptr
->args
.fileid
.ino
1276 && stat_buf
->st_dev
== pred_ptr
->args
.fileid
.dev
;
1280 pred_true (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1289 pred_type (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1292 mode_t type
= pred_ptr
->args
.type
;
1294 assert(state
.have_type
);
1295 assert(state
.type
!= 0);
1299 if (state
.have_stat
)
1300 mode
= stat_buf
->st_mode
;
1305 /* POSIX system; check `mode' the slow way. */
1306 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1307 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1308 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1309 || (S_ISREG (mode
) && type
== S_IFREG
)
1311 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1314 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1317 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1320 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1324 /* Unix system; check `mode' the fast way. */
1325 if ((mode
& S_IFMT
) == type
)
1333 pred_uid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1336 switch (pred_ptr
->args
.info
.kind
)
1339 if (stat_buf
->st_uid
> pred_ptr
->args
.info
.l_val
)
1343 if (stat_buf
->st_uid
< pred_ptr
->args
.info
.l_val
)
1347 if (stat_buf
->st_uid
== pred_ptr
->args
.info
.l_val
)
1355 pred_used (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1360 delta
= stat_buf
->st_atime
- stat_buf
->st_ctime
; /* Use difftime? */
1361 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1365 pred_user (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1368 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1375 pred_xtype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1377 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1378 int (*ystat
) (const char*, struct stat
*p
);
1380 /* If we would normally stat the link itself, stat the target instead.
1381 * If we would normally follow the link, stat the link itself instead.
1383 if (following_links())
1384 ystat
= optionp_stat
;
1386 ystat
= optionl_stat
;
1388 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1390 if (following_links() && errno
== ENOENT
)
1392 /* If we failed to follow the symlink,
1393 * fall back on looking at the symlink itself.
1395 /* Mimic behavior of ls -lL. */
1396 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1400 error (0, errno
, "%s", pathname
);
1401 state
.exit_status
= 1;
1405 /* Now that we have our stat() information, query it in the same
1406 * way that -type does.
1408 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1411 /* 1) fork to get a child; parent remembers the child pid
1412 2) child execs the command requested
1413 3) parent waits for child; checks for proper pid of child
1417 ret errno status(h) status(l)
1419 pid x signal# 0177 stopped
1420 pid x exit arg 0 term by _exit
1421 pid x 0 signal # term by signal
1422 -1 EINTR parent got signal
1423 -1 other some other kind of error
1425 Return true only if the pid matches, status(l) is
1426 zero, and the exit arg (status high) is 0.
1427 Otherwise return false, possibly printing an error message. */
1431 prep_child_for_exec (void)
1433 const char inputfile
[] = "/dev/null";
1434 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1437 if (open(inputfile
, O_RDONLY
) < 0)
1439 /* This is not entirely fatal, since
1440 * executing the child with a closed
1441 * stdin is almost as good as executing it
1442 * with its stdin attached to /dev/null.
1444 error (0, errno
, "%s", inputfile
);
1451 launch (const struct buildcmd_control
*ctl
,
1452 struct buildcmd_state
*buildstate
)
1456 static int first_time
= 1;
1457 const struct exec_val
*execp
= buildstate
->usercontext
;
1459 /* Null terminate the arg list. */
1460 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1462 /* Make sure output of command doesn't get mixed with find output. */
1466 /* Make sure to listen for the kids. */
1470 signal (SIGCHLD
, SIG_DFL
);
1473 child_pid
= fork ();
1474 if (child_pid
== -1)
1475 error (1, errno
, _("cannot fork"));
1478 /* We be the child. */
1479 prep_child_for_exec();
1481 /* For -exec and -ok, change directory back to the starting directory.
1482 * for -execdir and -okdir, stay in the directory we are searching
1483 * (the latter is more secure).
1485 if (!execp
->use_current_dir
)
1487 /* Even if DEBUG_STAT is set, don't announce our change of
1488 * directory, since we're not going to emit a subsequent
1489 * announcement of a call to stat() anyway, as we're about
1490 * to exec something.
1492 if (starting_desc
< 0
1493 ? chdir (starting_dir
) != 0
1494 : fchdir (starting_desc
) != 0)
1496 error (0, errno
, "%s", starting_dir
);
1501 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1502 error (0, errno
, "%s", buildstate
->cmd_argv
[0]);
1507 /* In parent; set up for next time. */
1508 bc_clear_args(ctl
, buildstate
);
1511 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1515 error (0, errno
, _("error waiting for %s"), buildstate
->cmd_argv
[0]);
1516 state
.exit_status
= 1;
1517 return 0; /* FAIL */
1521 if (WIFSIGNALED (wait_status
))
1523 error (0, 0, _("%s terminated by signal %d"),
1524 buildstate
->cmd_argv
[0], WTERMSIG (wait_status
));
1526 if (execp
->multiple
)
1528 /* -exec \; just returns false if the invoked command fails.
1529 * -exec {} + returns true if the invoked command fails, but
1530 * sets the program exit status.
1532 state
.exit_status
= 1;
1538 if (0 == WEXITSTATUS (wait_status
))
1544 if (execp
->multiple
)
1546 /* -exec \; just returns false if the invoked command fails.
1547 * -exec {} + returns true if the invoked command fails, but
1548 * sets the program exit status.
1550 state
.exit_status
= 1;
1552 return 0; /* FAIL */
1558 /* Return a static string formatting the time WHEN according to the
1559 strftime format character KIND. */
1562 format_date (time_t when
, int kind
)
1564 static char buf
[MAX (LONGEST_HUMAN_READABLE
+ 2, 64)];
1572 strcpy (fmt
, "%F+%T");
1575 && (tm
= localtime (&when
))
1576 && strftime (buf
, sizeof buf
, fmt
, tm
))
1581 char *p
= human_readable (when
< 0 ? -w
: w
, buf
+ 1,
1582 human_ceiling
, 1, 1);
1593 char *r
= ctime (&when
);
1596 /* The time cannot be represented as a struct tm.
1597 Output it as an integer. */
1598 return format_date (when
, '@');
1602 /* Remove the trailing newline from the ctime output,
1603 being careful not to assume that the output is fixed-width. */
1604 *strchr (r
, '\n') = '\0';
1610 /* Return a pointer to the string representation of
1611 the predicate function PRED_FUNC. */
1614 find_pred_name (pred_func
)
1619 for (i
= 0; pred_table
[i
].pred_func
!= 0; i
++)
1620 if (pred_table
[i
].pred_func
== pred_func
)
1622 return (pred_table
[i
].pred_name
);
1631 for (i
= 0; type_table
[i
].type
!= (short) -1; i
++)
1632 if (type_table
[i
].type
== type
)
1634 return (type_table
[i
].type_name
);
1643 for (i
= 0; prec_table
[i
].prec
!= (short) -1; i
++)
1644 if (prec_table
[i
].prec
== prec
)
1646 return (prec_table
[i
].prec_name
);
1649 /* Walk the expression tree NODE to stdout.
1650 INDENT is the number of levels to indent the left margin. */
1653 print_tree (FILE *fp
, struct predicate
*node
, int indent
)
1659 for (i
= 0; i
< indent
; i
++)
1661 fprintf (fp
, "pred = %s type = %s prec = %s addr = %p\n",
1662 find_pred_name (node
->pred_func
),
1663 type_name (node
->p_type
), prec_name (node
->p_prec
), node
);
1664 if (node
->need_stat
|| node
->need_type
)
1668 for (i
= 0; i
< indent
; i
++)
1671 fprintf (fp
, "Needs ");
1672 if (node
->need_stat
)
1674 fprintf (fp
, "stat");
1677 if (node
->need_type
)
1679 fprintf (fp
, "%stype", comma
? "," : "");
1684 for (i
= 0; i
< indent
; i
++)
1686 fprintf (fp
, _("left:\n"));
1687 print_tree (fp
, node
->pred_left
, indent
+ 1);
1688 for (i
= 0; i
< indent
; i
++)
1690 fprintf (fp
, _("right:\n"));
1691 print_tree (fp
, node
->pred_right
, indent
+ 1);
1694 /* Copy STR into BUF and trim blanks from the end of BUF.
1698 blank_rtrim (str
, buf
)
1707 i
= strlen (buf
) - 1;
1708 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
1714 /* Print out the predicate list starting at NODE. */
1717 print_list (FILE *fp
, struct predicate
*node
)
1719 struct predicate
*cur
;
1725 fprintf (fp
, "%s ", blank_rtrim (find_pred_name (cur
->pred_func
), name
));
1726 cur
= cur
->pred_next
;
1732 /* Print out the predicate list starting at NODE. */
1736 print_parenthesised(FILE *fp
, struct predicate
*node
)
1742 if ( ( (node
->pred_func
== pred_or
)
1743 || (node
->pred_func
== pred_and
) )
1744 && node
->pred_left
== NULL
)
1746 /* We print "<nothing> or X" as just "X"
1747 * We print "<nothing> and X" as just "X"
1749 print_parenthesised(fp
, node
->pred_right
);
1753 if (node
->pred_left
|| node
->pred_right
)
1757 fprintf(fp
, "%s", " ( ");
1758 print_optlist(fp
, node
);
1760 fprintf(fp
, "%s", " ) ");
1766 print_optlist (FILE *fp
, struct predicate
*p
)
1772 print_parenthesised(fp
, p
->pred_left
);
1775 p
->need_stat
? _("[stat called here] ") : "",
1776 p
->need_type
? _("[type needed here] ") : "",
1777 blank_rtrim (find_pred_name (p
->pred_func
), name
));
1778 print_parenthesised(fp
, p
->pred_right
);