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
)
301 if (pred_ptr
->pred_left
== NULL
302 || (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
303 pred_ptr
->pred_left
))
305 /* Check whether we need a stat here. */
306 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
308 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
309 pred_ptr
->pred_right
));
316 pred_anewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
320 if (stat_buf
->st_atime
> pred_ptr
->args
.time
)
326 pred_atime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
329 return pred_timewindow(stat_buf
->st_atime
, pred_ptr
, DAYSECS
);
333 pred_close (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
343 pred_cmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
346 return pred_timewindow(stat_buf
->st_ctime
, pred_ptr
, 60);
350 pred_cnewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
354 if (stat_buf
->st_ctime
> pred_ptr
->args
.time
)
361 pred_comma (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
363 if (pred_ptr
->pred_left
!= NULL
)
364 (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
365 pred_ptr
->pred_left
);
366 /* Check whether we need a stat here. */
367 /* TODO: what about need_type? */
368 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
370 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
371 pred_ptr
->pred_right
));
375 pred_ctime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
378 return pred_timewindow(stat_buf
->st_ctime
, pred_ptr
, DAYSECS
);
382 pred_delete (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
386 if (strcmp (state
.rel_pathname
, "."))
388 if (0 != remove (state
.rel_pathname
))
390 error (0, errno
, "cannot delete %s", pathname
);
404 pred_empty (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
409 if (S_ISDIR (stat_buf
->st_mode
))
413 boolean empty
= true;
416 d
= opendir (state
.rel_pathname
);
419 error (0, errno
, "%s", pathname
);
420 state
.exit_status
= 1;
423 for (dp
= readdir (d
); dp
; dp
= readdir (d
))
425 if (dp
->d_name
[0] != '.'
426 || (dp
->d_name
[1] != '\0'
427 && (dp
->d_name
[1] != '.' || dp
->d_name
[2] != '\0')))
435 error (0, errno
, "%s", pathname
);
436 state
.exit_status
= 1;
441 else if (S_ISREG (stat_buf
->st_mode
))
442 return (stat_buf
->st_size
== 0);
447 #if defined(NEW_EXEC)
449 new_impl_pred_exec (const char *pathname
, struct stat
*stat_buf
,
450 struct predicate
*pred_ptr
,
451 const char *prefix
, size_t pfxlen
)
453 struct exec_val
*execp
= &pred_ptr
->args
.exec_vec
;
454 size_t len
= strlen(pathname
);
458 /* Push the argument onto the current list.
459 * The command may or may not be run at this point,
460 * depending on the command line length limits.
462 bc_push_arg(&execp
->ctl
,
468 /* POSIX: If the primary expression is punctuated by a plus
469 * sign, the primary shall always evaluate as true
477 for (i
=0; i
<execp
->num_args
; ++i
)
479 bc_do_insert(&execp
->ctl
,
481 execp
->replace_vec
[i
],
482 strlen(execp
->replace_vec
[i
]),
488 /* Actually invoke the command. */
489 return execp
->ctl
.exec_callback(&execp
->ctl
,
495 old_impl_pred_exec (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
499 struct exec_val
*execp
; /* Pointer for efficiency. */
504 execp
= &pred_ptr
->args
.exec_vec
;
506 /* Replace "{}" with the real path in each affected arg. */
507 for (path_pos
= 0; execp
->paths
[path_pos
].offset
>= 0; path_pos
++)
509 register char *from
, *to
;
511 i
= execp
->paths
[path_pos
].offset
;
513 xmalloc (strlen (execp
->paths
[path_pos
].origarg
) + 1
514 + (strlen (pathname
) - 2) * execp
->paths
[path_pos
].count
);
515 for (from
= execp
->paths
[path_pos
].origarg
, to
= execp
->vec
[i
]; *from
; )
516 if (from
[0] == '{' && from
[1] == '}')
518 to
= stpcpy (to
, pathname
);
523 *to
= *from
; /* Copy null. */
526 i
= launch (pred_ptr
);
528 /* Free the temporary args. */
529 for (path_pos
= 0; execp
->paths
[path_pos
].offset
>= 0; path_pos
++)
530 free (execp
->vec
[execp
->paths
[path_pos
].offset
]);
537 pred_exec (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
539 #if defined(NEW_EXEC)
540 return new_impl_pred_exec(pathname
, stat_buf
, pred_ptr
, NULL
, 0);
542 return old_impl_pred_exec(pathname
, stat_buf
, pred_ptr
);
547 pred_execdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
549 const char *s
= basename(pathname
);
550 return new_impl_pred_exec(s
, stat_buf
, pred_ptr
, "./", 2);
554 pred_false (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
565 pred_fls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
567 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
568 options
.output_block_size
, pred_ptr
->args
.stream
);
573 pred_fprint (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
578 fputs (pathname
, pred_ptr
->args
.stream
);
579 putc ('\n', pred_ptr
->args
.stream
);
584 pred_fprint0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
589 fputs (pathname
, pred_ptr
->args
.stream
);
590 putc (0, pred_ptr
->args
.stream
);
595 pred_fprintf (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
597 FILE *fp
= pred_ptr
->args
.printf_vec
.stream
;
598 struct segment
*segment
;
600 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
602 for (segment
= pred_ptr
->args
.printf_vec
.segment
; segment
;
603 segment
= segment
->next
)
605 if (segment
->kind
& 0xff00) /* Component of date. */
609 switch (segment
->kind
& 0xff)
612 t
= stat_buf
->st_atime
;
615 t
= stat_buf
->st_ctime
;
618 t
= stat_buf
->st_mtime
;
623 fprintf (fp
, segment
->text
,
624 format_date (t
, (segment
->kind
>> 8) & 0xff));
628 switch (segment
->kind
)
630 case KIND_PLAIN
: /* Plain text string (no % conversion). */
631 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
633 case KIND_STOP
: /* Terminate argument and flush output. */
634 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
637 case 'a': /* atime in `ctime' format. */
638 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_atime
));
640 case 'b': /* size in 512-byte blocks */
641 fprintf (fp
, segment
->text
,
642 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
644 ST_NBLOCKSIZE
, 512));
646 case 'c': /* ctime in `ctime' format */
647 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_ctime
));
649 case 'd': /* depth in search tree */
650 fprintf (fp
, segment
->text
, state
.curdepth
);
652 case 'D': /* Device on which file exists (stat.st_dev) */
653 fprintf (fp
, segment
->text
,
654 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
655 human_ceiling
, 1, 1));
657 case 'f': /* basename of path */
658 fprintf (fp
, segment
->text
, base_name (pathname
));
660 case 'F': /* filesystem type */
661 fprintf (fp
, segment
->text
, filesystem_type (stat_buf
));
663 case 'g': /* group name */
667 g
= getgrgid (stat_buf
->st_gid
);
670 segment
->text
[segment
->text_len
] = 's';
671 fprintf (fp
, segment
->text
, g
->gr_name
);
676 case 'G': /* GID number */
677 fprintf (fp
, segment
->text
,
678 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
679 human_ceiling
, 1, 1));
681 case 'h': /* leading directories part of path */
685 cp
= strrchr (pathname
, '/');
686 if (cp
== NULL
) /* No leading directories. */
690 fprintf (fp
, segment
->text
, pathname
);
694 case 'H': /* ARGV element file was found under */
696 char cc
= pathname
[state
.path_length
];
698 pathname
[state
.path_length
] = '\0';
699 fprintf (fp
, segment
->text
, pathname
);
700 pathname
[state
.path_length
] = cc
;
703 case 'i': /* inode number */
704 fprintf (fp
, segment
->text
,
705 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
709 case 'k': /* size in 1K blocks */
710 fprintf (fp
, segment
->text
,
711 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
713 ST_NBLOCKSIZE
, 1024));
715 case 'l': /* object of symlink */
720 if (S_ISLNK (stat_buf
->st_mode
))
722 linkname
= get_link_name (pathname
, state
.rel_pathname
);
724 state
.exit_status
= 1;
728 fprintf (fp
, segment
->text
, linkname
);
732 fprintf (fp
, segment
->text
, "");
737 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
739 char modestring
[16] ;
740 mode_string (stat_buf
->st_mode
, modestring
);
741 modestring
[10] = '\0';
742 fprintf (fp
, segment
->text
, modestring
);
746 case 'm': /* mode as octal number (perms only) */
748 /* Output the mode portably using the traditional numbers,
749 even if the host unwisely uses some other numbering
750 scheme. But help the compiler in the common case where
751 the host uses the traditional numbering scheme. */
752 mode_t m
= stat_buf
->st_mode
;
753 boolean traditional_numbering_scheme
=
754 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
755 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
756 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
757 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
758 fprintf (fp
, segment
->text
,
759 (traditional_numbering_scheme
761 : ((m
& S_ISUID
? 04000 : 0)
762 | (m
& S_ISGID
? 02000 : 0)
763 | (m
& S_ISVTX
? 01000 : 0)
764 | (m
& S_IRUSR
? 00400 : 0)
765 | (m
& S_IWUSR
? 00200 : 0)
766 | (m
& S_IXUSR
? 00100 : 0)
767 | (m
& S_IRGRP
? 00040 : 0)
768 | (m
& S_IWGRP
? 00020 : 0)
769 | (m
& S_IXGRP
? 00010 : 0)
770 | (m
& S_IROTH
? 00004 : 0)
771 | (m
& S_IWOTH
? 00002 : 0)
772 | (m
& S_IXOTH
? 00001 : 0))));
776 case 'n': /* number of links */
777 fprintf (fp
, segment
->text
,
778 human_readable ((uintmax_t) stat_buf
->st_nlink
,
783 case 'p': /* pathname */
784 fprintf (fp
, segment
->text
, pathname
);
786 case 'P': /* pathname with ARGV element stripped */
787 if (state
.curdepth
> 0)
789 cp
= pathname
+ state
.path_length
;
791 /* Move past the slash between the ARGV element
792 and the rest of the pathname. But if the ARGV element
793 ends in a slash, we didn't add another, so we've
794 already skipped past it. */
799 fprintf (fp
, segment
->text
, cp
);
801 case 's': /* size in bytes */
802 fprintf (fp
, segment
->text
,
803 human_readable ((uintmax_t) stat_buf
->st_size
,
804 hbuf
, human_ceiling
, 1, 1));
806 case 't': /* mtime in `ctime' format */
807 fprintf (fp
, segment
->text
, ctime_format (stat_buf
->st_mtime
));
809 case 'u': /* user name */
813 p
= getpwuid (stat_buf
->st_uid
);
816 segment
->text
[segment
->text_len
] = 's';
817 fprintf (fp
, segment
->text
, p
->pw_name
);
823 case 'U': /* UID number */
824 fprintf (fp
, segment
->text
,
825 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
826 human_ceiling
, 1, 1));
829 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
830 case 'Y': /* in case of symlink */
833 if (S_ISLNK (stat_buf
->st_mode
))
837 ystat
= options
.xstat
== lstat
? stat
: lstat
;
838 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
840 if ( errno
== ENOENT
) {
841 fprintf (fp
, segment
->text
, "N");
844 if ( errno
== ELOOP
) {
845 fprintf (fp
, segment
->text
, "L");
848 error (0, errno
, "%s", pathname
);
852 stat_buf
->st_mode
= sbuf
.st_mode
;
859 mode_t m
= stat_buf
->st_mode
& S_IFMT
;
861 fprintf (fp
, segment
->text
,
862 ( m
== S_IFSOCK
? "s" :
869 m
== S_IFDOOR
? "D" :
871 m
== S_IFIFO
? "p" : "U" ) );
881 pred_fstype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
885 if (strcmp (filesystem_type (stat_buf
), pred_ptr
->args
.str
) == 0)
892 pred_gid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
896 switch (pred_ptr
->args
.info
.kind
)
899 if (stat_buf
->st_gid
> pred_ptr
->args
.info
.l_val
)
903 if (stat_buf
->st_gid
< pred_ptr
->args
.info
.l_val
)
907 if (stat_buf
->st_gid
== pred_ptr
->args
.info
.l_val
)
915 pred_group (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
919 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
926 pred_ilname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
928 return insert_lname (pathname
, stat_buf
, pred_ptr
, true);
932 pred_iname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
938 /* FNM_PERIOD is not used here because POSIX requires that it not be.
939 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
941 base
= base_name (pathname
);
942 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
948 pred_inum (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
952 switch (pred_ptr
->args
.info
.kind
)
955 if (stat_buf
->st_ino
> pred_ptr
->args
.info
.l_val
)
959 if (stat_buf
->st_ino
< pred_ptr
->args
.info
.l_val
)
963 if (stat_buf
->st_ino
== pred_ptr
->args
.info
.l_val
)
971 pred_ipath (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
975 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
981 pred_links (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
985 switch (pred_ptr
->args
.info
.kind
)
988 if (stat_buf
->st_nlink
> pred_ptr
->args
.info
.l_val
)
992 if (stat_buf
->st_nlink
< pred_ptr
->args
.info
.l_val
)
996 if (stat_buf
->st_nlink
== pred_ptr
->args
.info
.l_val
)
1004 pred_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1006 return insert_lname (pathname
, stat_buf
, pred_ptr
, false);
1010 insert_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
1012 boolean ret
= false;
1014 if (S_ISLNK (stat_buf
->st_mode
))
1016 char *linkname
= get_link_name (pathname
, state
.rel_pathname
);
1019 if (fnmatch (pred_ptr
->args
.str
, linkname
,
1020 ignore_case
? FNM_CASEFOLD
: 0) == 0)
1025 #endif /* S_ISLNK */
1030 pred_ls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1034 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
1035 options
.output_block_size
, stdout
);
1040 pred_mmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1043 return pred_timewindow(stat_buf
->st_mtime
, pred_ptr
, 60);
1047 pred_mtime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1050 return pred_timewindow(stat_buf
->st_mtime
, pred_ptr
, DAYSECS
);
1054 pred_name (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1059 base
= base_name (pathname
);
1061 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1062 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1064 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1070 pred_negate (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1072 /* Check whether we need a stat here. */
1073 /* TODO: what about need_type? */
1074 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1076 return (!(*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1077 pred_ptr
->pred_right
));
1081 pred_newer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1085 if (stat_buf
->st_mtime
> pred_ptr
->args
.time
)
1091 pred_nogroup (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1097 extern char *gid_unused
;
1099 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1101 return getgrgid (stat_buf
->st_gid
) == NULL
;
1106 pred_nouser (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1109 extern char *uid_unused
;
1116 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1118 return getpwuid (stat_buf
->st_uid
) == NULL
;
1122 #if defined(NEW_EXEC)
1125 is_ok(const char *program
, const char *arg
)
1128 /* The draft open standard requires that, in the POSIX locale,
1129 the last non-blank character of this prompt be '?'.
1130 The exact format is not specified.
1131 This standard does not have requirements for locales other than POSIX
1133 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1139 pred_ok (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1141 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1142 return new_impl_pred_exec (pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1148 pred_okdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1150 const char *s
= basename(pathname
);
1152 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1153 return new_impl_pred_exec (s
, stat_buf
, pred_ptr
, "./", 2);
1162 pred_ok (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1165 /* The draft open standard requires that, in the POSIX locale,
1166 the last non-blank character of this prompt be '?'.
1167 The exact format is not specified.
1168 This standard does not have requirements for locales other than POSIX
1170 fprintf (stderr
, _("< %s ... %s > ? "),
1171 pred_ptr
->args
.exec_vec
.vec
[0], pathname
);
1174 return pred_exec (pathname
, stat_buf
, pred_ptr
);
1180 pred_okdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1182 error(1, 0, "-okdir is not yet implemented.");
1191 pred_open (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1200 pred_or (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1202 if (pred_ptr
->pred_left
== NULL
1203 || !(*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
1204 pred_ptr
->pred_left
))
1206 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1208 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1209 pred_ptr
->pred_right
));
1216 pred_path (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1219 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1225 pred_perm (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1228 switch (pred_ptr
->args
.perm
.kind
)
1231 return (stat_buf
->st_mode
& pred_ptr
->args
.perm
.val
) == pred_ptr
->args
.perm
.val
;
1235 return (stat_buf
->st_mode
& pred_ptr
->args
.perm
.val
) != 0;
1239 return (stat_buf
->st_mode
& MODE_ALL
) == pred_ptr
->args
.perm
.val
;
1249 pred_print (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1258 pred_print0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1262 fputs (pathname
, stdout
);
1268 pred_prune (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1273 state
.stop_at_current_level
= true;
1274 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1278 pred_quit (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1284 /* Run any cleanups. This includes executing any command lines
1285 * we have partly built but not executed.
1289 /* Since -exec and friends don't leave child processes running in the
1290 * background, there is no need to wait for them here.
1292 exit(state
.exit_status
); /* 0 for success, etc. */
1296 pred_regex (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1298 int len
= strlen (pathname
);
1300 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1301 (struct re_registers
*) NULL
) == len
)
1307 pred_size (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1312 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1313 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1314 switch (pred_ptr
->args
.size
.kind
)
1317 if (f_val
> pred_ptr
->args
.size
.size
)
1321 if (f_val
< pred_ptr
->args
.size
.size
)
1325 if (f_val
== pred_ptr
->args
.size
.size
)
1333 pred_samefile (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1335 /* Potential optimisation: because of the loop protection, we
1336 * always know the device of the current directory, hence the
1337 * device number of the current filesystem. If -L is not in
1338 * effect, and the device number of the file we're looking for
1339 * is not the same as the device number of the current directory,
1340 * this predicate cannot return true. Hence there would be no
1341 * need to stat the file.
1343 return stat_buf
->st_ino
== pred_ptr
->args
.fileid
.ino
1344 && stat_buf
->st_dev
== pred_ptr
->args
.fileid
.dev
;
1348 pred_true (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1357 pred_type (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1360 mode_t type
= pred_ptr
->args
.type
;
1362 assert(state
.have_type
);
1363 assert(state
.type
!= 0);
1367 if (state
.have_stat
)
1368 mode
= stat_buf
->st_mode
;
1373 /* POSIX system; check `mode' the slow way. */
1374 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1375 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1376 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1377 || (S_ISREG (mode
) && type
== S_IFREG
)
1379 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1382 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1385 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1388 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1392 /* Unix system; check `mode' the fast way. */
1393 if ((mode
& S_IFMT
) == type
)
1401 pred_uid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1404 switch (pred_ptr
->args
.info
.kind
)
1407 if (stat_buf
->st_uid
> pred_ptr
->args
.info
.l_val
)
1411 if (stat_buf
->st_uid
< pred_ptr
->args
.info
.l_val
)
1415 if (stat_buf
->st_uid
== pred_ptr
->args
.info
.l_val
)
1423 pred_used (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1428 delta
= stat_buf
->st_atime
- stat_buf
->st_ctime
; /* Use difftime? */
1429 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1433 pred_user (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1436 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1443 pred_xtype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1445 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1446 int (*ystat
) (const char*, struct stat
*p
);
1448 switch (options
.symlink_handling
)
1450 case SYMLINK_ALWAYS_DEREF
:
1451 ystat
= optionl_stat
;
1452 case SYMLINK_DEREF_ARGSONLY
:
1453 case SYMLINK_NEVER_DEREF
:
1454 ystat
= optionp_stat
;
1457 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1459 if (ystat
== optionl_stat
&& errno
== ENOENT
)
1461 /* If we failed to follow the symlink,
1462 * fall back on looking at the symlink itself.
1464 /* Mimic behavior of ls -lL. */
1465 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1469 error (0, errno
, "%s", pathname
);
1470 state
.exit_status
= 1;
1474 /* Now that we have our stat() information, query it in the same
1475 * way that -type does.
1477 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1480 /* 1) fork to get a child; parent remembers the child pid
1481 2) child execs the command requested
1482 3) parent waits for child; checks for proper pid of child
1486 ret errno status(h) status(l)
1488 pid x signal# 0177 stopped
1489 pid x exit arg 0 term by _exit
1490 pid x 0 signal # term by signal
1491 -1 EINTR parent got signal
1492 -1 other some other kind of error
1494 Return true only if the pid matches, status(l) is
1495 zero, and the exit arg (status high) is 0.
1496 Otherwise return false, possibly printing an error message. */
1498 #if defined(NEW_EXEC)
1500 prep_child_for_exec (void)
1502 const char inputfile
[] = "/dev/null";
1503 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1506 if (open(inputfile
, O_RDONLY
) < 0)
1508 /* This is not entirely fatal, since
1509 * executing the child with a closed
1510 * stdin is almost as good as executing it
1511 * with its stdin attached to /dev/null.
1513 error (0, errno
, "%s", inputfile
);
1520 launch (const struct buildcmd_control
*ctl
,
1521 struct buildcmd_state
*buildstate
)
1525 static int first_time
= 1;
1526 const struct exec_val
*execp
= buildstate
->usercontext
;
1528 /* Null terminate the arg list. */
1529 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1531 /* Make sure output of command doesn't get mixed with find output. */
1535 /* Make sure to listen for the kids. */
1539 signal (SIGCHLD
, SIG_DFL
);
1542 child_pid
= fork ();
1543 if (child_pid
== -1)
1544 error (1, errno
, _("cannot fork"));
1547 /* We be the child. */
1548 prep_child_for_exec();
1550 /* For -exec and -ok, change directory back to the starting directory.
1551 * for -execdir and -okdir, stay in the directory we are searching
1552 * (the latter is more secure).
1554 if (!execp
->use_current_dir
)
1556 /* Even if DEBUG_STAT is set, don't announce our change of
1557 * directory, since we're not going to emit a subsequent
1558 * announcement of a call to stat() anyway, as we're about
1559 * to exec something.
1561 if (starting_desc
< 0
1562 ? chdir (starting_dir
) != 0
1563 : fchdir (starting_desc
) != 0)
1565 error (0, errno
, "%s", starting_dir
);
1570 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1571 error (0, errno
, "%s", buildstate
->cmd_argv
[0]);
1576 /* In parent; set up for next time. */
1577 bc_clear_args(ctl
, buildstate
);
1580 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1584 error (0, errno
, _("error waiting for %s"), buildstate
->cmd_argv
[0]);
1585 state
.exit_status
= 1;
1586 return 0; /* FAIL */
1590 if (WIFSIGNALED (wait_status
))
1592 error (0, 0, _("%s terminated by signal %d"),
1593 buildstate
->cmd_argv
[0], WTERMSIG (wait_status
));
1595 if (execp
->multiple
)
1597 /* -exec \; just returns false if the invoked command fails.
1598 * -exec {} + returns true if the invoked command fails, but
1599 * sets the program exit status.
1601 state
.exit_status
= 1;
1607 if (0 == WEXITSTATUS (wait_status
))
1613 if (execp
->multiple
)
1615 /* -exec \; just returns false if the invoked command fails.
1616 * -exec {} + returns true if the invoked command fails, but
1617 * sets the program exit status.
1619 state
.exit_status
= 1;
1621 return 0; /* FAIL */
1627 launch (struct predicate
*pred_ptr
)
1631 struct exec_val
*execp
; /* Pointer for efficiency. */
1632 static int first_time
= 1;
1634 execp
= &pred_ptr
->args
.exec_vec
;
1636 /* Make sure output of command doesn't get mixed with find output. */
1640 /* Make sure to listen for the kids. */
1644 signal (SIGCHLD
, SIG_DFL
);
1647 child_pid
= fork ();
1648 if (child_pid
== -1)
1649 error (1, errno
, _("cannot fork"));
1652 /* We be the child. */
1653 if (starting_desc
< 0
1654 ? chdir (starting_dir
) != 0
1655 : fchdir (starting_desc
) != 0)
1657 error (0, errno
, "%s", starting_dir
);
1660 execvp (execp
->vec
[0], execp
->vec
);
1661 error (0, errno
, "%s", execp
->vec
[0]);
1666 while (waitpid (child_pid
, &status
, 0) == (pid_t
) -1)
1669 error (0, errno
, _("error waiting for %s"), execp
->vec
[0]);
1670 state
.exit_status
= 1;
1673 if (WIFSIGNALED (status
))
1675 error (0, 0, _("%s terminated by signal %d"),
1676 execp
->vec
[0], WTERMSIG (status
));
1677 state
.exit_status
= 1;
1680 return (!WEXITSTATUS (status
));
1685 /* Return a static string formatting the time WHEN according to the
1686 strftime format character KIND. */
1689 format_date (time_t when
, int kind
)
1691 static char buf
[MAX (LONGEST_HUMAN_READABLE
+ 2, 64)];
1699 strcpy (fmt
, "%F+%T");
1702 && (tm
= localtime (&when
))
1703 && strftime (buf
, sizeof buf
, fmt
, tm
))
1708 char *p
= human_readable (when
< 0 ? -w
: w
, buf
+ 1,
1709 human_ceiling
, 1, 1);
1720 char *r
= ctime (&when
);
1723 /* The time cannot be represented as a struct tm.
1724 Output it as an integer. */
1725 return format_date (when
, '@');
1729 /* Remove the trailing newline from the ctime output,
1730 being careful not to assume that the output is fixed-width. */
1731 *strchr (r
, '\n') = '\0';
1737 /* Return a pointer to the string representation of
1738 the predicate function PRED_FUNC. */
1741 find_pred_name (pred_func
)
1746 for (i
= 0; pred_table
[i
].pred_func
!= 0; i
++)
1747 if (pred_table
[i
].pred_func
== pred_func
)
1749 return (pred_table
[i
].pred_name
);
1758 for (i
= 0; type_table
[i
].type
!= (short) -1; i
++)
1759 if (type_table
[i
].type
== type
)
1761 return (type_table
[i
].type_name
);
1770 for (i
= 0; prec_table
[i
].prec
!= (short) -1; i
++)
1771 if (prec_table
[i
].prec
== prec
)
1773 return (prec_table
[i
].prec_name
);
1776 /* Walk the expression tree NODE to stdout.
1777 INDENT is the number of levels to indent the left margin. */
1780 print_tree (FILE *fp
, struct predicate
*node
, int indent
)
1786 for (i
= 0; i
< indent
; i
++)
1788 fprintf (fp
, "pred = %s type = %s prec = %s addr = %p\n",
1789 find_pred_name (node
->pred_func
),
1790 type_name (node
->p_type
), prec_name (node
->p_prec
), node
);
1791 if (node
->need_stat
|| node
->need_type
)
1795 for (i
= 0; i
< indent
; i
++)
1798 fprintf (fp
, "Needs ");
1799 if (node
->need_stat
)
1801 fprintf (fp
, "stat");
1804 if (node
->need_type
)
1806 fprintf (fp
, "%stype", comma
? "," : "");
1811 for (i
= 0; i
< indent
; i
++)
1813 fprintf (fp
, _("left:\n"));
1814 print_tree (fp
, node
->pred_left
, indent
+ 1);
1815 for (i
= 0; i
< indent
; i
++)
1817 fprintf (fp
, _("right:\n"));
1818 print_tree (fp
, node
->pred_right
, indent
+ 1);
1821 /* Copy STR into BUF and trim blanks from the end of BUF.
1825 blank_rtrim (str
, buf
)
1834 i
= strlen (buf
) - 1;
1835 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
1841 /* Print out the predicate list starting at NODE. */
1844 print_list (FILE *fp
, struct predicate
*node
)
1846 struct predicate
*cur
;
1852 fprintf (fp
, "%s ", blank_rtrim (find_pred_name (cur
->pred_func
), name
));
1853 cur
= cur
->pred_next
;
1859 /* Print out the predicate list starting at NODE. */
1863 print_parenthesised(FILE *fp
, struct predicate
*node
)
1869 if ( ( (node
->pred_func
== pred_or
)
1870 || (node
->pred_func
== pred_and
) )
1871 && node
->pred_left
== NULL
)
1873 /* We print "<nothing> or X" as just "X"
1874 * We print "<nothing> and X" as just "X"
1876 print_parenthesised(fp
, node
->pred_right
);
1880 if (node
->pred_left
|| node
->pred_right
)
1884 fprintf(fp
, "%s", " ( ");
1885 print_optlist(fp
, node
);
1887 fprintf(fp
, "%s", " ) ");
1893 print_optlist (FILE *fp
, struct predicate
*p
)
1899 print_parenthesised(fp
, p
->pred_left
);
1902 p
->need_stat
? _("[stat called here] ") : "",
1903 p
->need_type
? _("[type needed here] ") : "",
1904 blank_rtrim (find_pred_name (p
->pred_func
), name
));
1905 print_parenthesised(fp
, p
->pred_right
);