1 /* pred.c -- execute the expression tree.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
3 2004, 2005 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
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,
28 #include <sys/types.h>
39 #include "printquoted.h"
43 #include "stat-time.h"
47 # define _(Text) gettext (Text)
52 # define N_(String) gettext_noop (String)
54 /* See locate.c for explanation as to why not use (String) */
55 # define N_(String) String
58 #if !defined(SIGCHLD) && defined(SIGCLD)
59 #define SIGCHLD SIGCLD
66 # define NAMLEN(dirent) strlen((dirent)->d_name)
68 # define dirent direct
69 # define NAMLEN(dirent) (dirent)->d_namlen
71 # include <sys/ndir.h>
82 /* Fake a return value. */
83 #define CLOSEDIR(d) (closedir (d), 0)
85 #define CLOSEDIR(d) closedir (d)
91 /* Get or fake the disk device blocksize.
92 Usually defined by sys/param.h (if at all). */
95 # define DEV_BSIZE BSIZE
97 # define DEV_BSIZE 4096
99 #endif /* !DEV_BSIZE */
101 /* Extract or fake data from a `struct stat'.
102 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
103 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
104 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
105 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
106 # define ST_BLKSIZE(statbuf) DEV_BSIZE
107 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
108 # define ST_NBLOCKS(statbuf) \
109 (S_ISREG ((statbuf).st_mode) \
110 || S_ISDIR ((statbuf).st_mode) \
111 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
112 # else /* !_POSIX_SOURCE && BSIZE */
113 # define ST_NBLOCKS(statbuf) \
114 (S_ISREG ((statbuf).st_mode) \
115 || S_ISDIR ((statbuf).st_mode) \
116 ? st_blocks ((statbuf).st_size) : 0)
117 # endif /* !_POSIX_SOURCE && BSIZE */
118 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
119 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
120 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
121 ? (statbuf).st_blksize : DEV_BSIZE)
122 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
123 /* HP-UX counts st_blocks in 1024-byte units.
124 This loses when mixing HP-UX and BSD filesystems with NFS. */
125 # define ST_NBLOCKSIZE 1024
127 # if defined(_AIX) && defined(_I386)
128 /* AIX PS/2 counts st_blocks in 4K units. */
129 # define ST_NBLOCKSIZE (4 * 1024)
130 # else /* not AIX PS/2 */
132 # define ST_NBLOCKS(statbuf) \
133 (S_ISREG ((statbuf).st_mode) \
134 || S_ISDIR ((statbuf).st_mode) \
135 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
137 # endif /* not AIX PS/2 */
139 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
142 # define ST_NBLOCKS(statbuf) \
143 (S_ISREG ((statbuf).st_mode) \
144 || S_ISDIR ((statbuf).st_mode) \
145 ? (statbuf).st_blocks : 0)
148 #ifndef ST_NBLOCKSIZE
149 # define ST_NBLOCKSIZE 512
154 #define MAX(a, b) ((a) > (b) ? (a) : (b))
156 static boolean match_lname
PARAMS((char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
));
158 static char *format_date
PARAMS((struct timespec ts
, int kind
));
159 static char *ctime_format
PARAMS((struct timespec ts
));
168 struct pred_assoc pred_table
[] =
170 {pred_amin
, "amin "},
172 {pred_anewer
, "anewer "},
173 {pred_atime
, "atime "},
175 {pred_cmin
, "cmin "},
176 {pred_cnewer
, "cnewer "},
178 {pred_ctime
, "ctime "},
179 {pred_delete
, "delete "},
180 {pred_empty
, "empty "},
181 {pred_exec
, "exec "},
182 {pred_execdir
, "execdir "},
183 {pred_executable
, "executable "},
184 {pred_false
, "false "},
185 {pred_fprint
, "fprint "},
186 {pred_fprint0
, "fprint0 "},
187 {pred_fprintf
, "fprintf "},
188 {pred_fstype
, "fstype "},
190 {pred_group
, "group "},
191 {pred_ilname
, "ilname "},
192 {pred_iname
, "iname "},
193 {pred_inum
, "inum "},
194 {pred_ipath
, "ipath "},
195 {pred_links
, "links "},
196 {pred_lname
, "lname "},
198 {pred_mmin
, "mmin "},
199 {pred_mtime
, "mtime "},
200 {pred_name
, "name "},
201 {pred_negate
, "not "},
202 {pred_newer
, "newer "},
203 {pred_nogroup
, "nogroup "},
204 {pred_nouser
, "nouser "},
206 {pred_okdir
, "okdir "},
209 {pred_path
, "path "},
210 {pred_perm
, "perm "},
211 {pred_print
, "print "},
212 {pred_print0
, "print0 "},
213 {pred_prune
, "prune "},
214 {pred_quit
, "quit "},
215 {pred_readable
, "readable "},
216 {pred_regex
, "regex "},
217 {pred_samefile
,"samefile "},
218 {pred_size
, "size "},
219 {pred_true
, "true "},
220 {pred_type
, "type "},
222 {pred_used
, "used "},
223 {pred_user
, "user "},
224 {pred_writable
, "writable "},
225 {pred_xtype
, "xtype "},
230 /* Returns ts1 - ts2 */
231 static double ts_difference(struct timespec ts1
,
234 double d
= difftime(ts1
.tv_sec
, ts2
.tv_sec
)
235 + (1.0e-9 * (ts1
.tv_nsec
- ts2
.tv_nsec
));
241 compare_ts(struct timespec ts1
,
244 if ((ts1
.tv_sec
== ts2
.tv_sec
) &&
245 (ts1
.tv_nsec
== ts2
.tv_nsec
))
251 double diff
= ts_difference(ts1
, ts2
);
252 return diff
< 0.0 ? -1 : +1;
256 /* Predicate processing routines.
258 PATHNAME is the full pathname of the file being checked.
259 *STAT_BUF contains information about PATHNAME.
260 *PRED_PTR contains information for applying the predicate.
262 Return true if the file passes this predicate, false if not. */
267 * Returns true if THE_TIME is
268 * COMP_GT: after the specified time
269 * COMP_LT: before the specified time
270 * COMP_EQ: less than WINDOW seconds after the specified time.
273 pred_timewindow(struct timespec ts
, struct predicate
const *pred_ptr
, int window
)
277 switch (pred_ptr
->args
.reftime
.kind
)
280 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
283 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) < 0;
286 delta
= ts_difference(ts
, pred_ptr
->args
.reftime
.ts
);
287 return (delta
>= 0.0 && delta
< window
);
293 pred_amin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
296 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, 60);
300 pred_and (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
302 if (pred_ptr
->pred_left
== NULL
303 || (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
304 pred_ptr
->pred_left
))
306 /* Check whether we need a stat here. */
307 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
309 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
310 pred_ptr
->pred_right
));
317 pred_anewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
320 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
321 return compare_ts(get_stat_atime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
325 pred_atime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
328 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, DAYSECS
);
332 pred_close (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
342 pred_cmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
345 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, 60);
349 pred_cnewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
353 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
354 return compare_ts(get_stat_ctime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
358 pred_comma (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
360 if (pred_ptr
->pred_left
!= NULL
)
361 (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
362 pred_ptr
->pred_left
);
363 /* Check whether we need a stat here. */
364 /* TODO: what about need_type? */
365 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
367 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
368 pred_ptr
->pred_right
));
372 pred_ctime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
375 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, DAYSECS
);
379 pred_delete (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
383 if (strcmp (state
.rel_pathname
, "."))
385 if (0 != remove (state
.rel_pathname
))
387 error (0, errno
, "cannot delete %s", pathname
);
401 pred_empty (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
406 if (S_ISDIR (stat_buf
->st_mode
))
410 boolean empty
= true;
413 d
= opendir (state
.rel_pathname
);
416 error (0, errno
, "%s", pathname
);
417 state
.exit_status
= 1;
420 for (dp
= readdir (d
); dp
; dp
= readdir (d
))
422 if (dp
->d_name
[0] != '.'
423 || (dp
->d_name
[1] != '\0'
424 && (dp
->d_name
[1] != '.' || dp
->d_name
[2] != '\0')))
432 error (0, errno
, "%s", pathname
);
433 state
.exit_status
= 1;
438 else if (S_ISREG (stat_buf
->st_mode
))
439 return (stat_buf
->st_size
== 0);
445 new_impl_pred_exec (const char *pathname
, struct stat
*stat_buf
,
446 struct predicate
*pred_ptr
,
447 const char *prefix
, size_t pfxlen
)
449 struct exec_val
*execp
= &pred_ptr
->args
.exec_vec
;
450 size_t len
= strlen(pathname
);
456 /* Push the argument onto the current list.
457 * The command may or may not be run at this point,
458 * depending on the command line length limits.
460 bc_push_arg(&execp
->ctl
,
466 /* POSIX: If the primary expression is punctuated by a plus
467 * sign, the primary shall always evaluate as true
475 for (i
=0; i
<execp
->num_args
; ++i
)
477 bc_do_insert(&execp
->ctl
,
479 execp
->replace_vec
[i
],
480 strlen(execp
->replace_vec
[i
]),
486 /* Actually invoke the command. */
487 return execp
->ctl
.exec_callback(&execp
->ctl
,
494 pred_exec (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
496 return new_impl_pred_exec(pathname
, stat_buf
, pred_ptr
, NULL
, 0);
500 pred_execdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
502 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
504 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
505 prefix
, (prefix
? 2 : 0));
509 pred_false (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
520 pred_fls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
522 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
523 options
.output_block_size
,
524 pred_ptr
->literal_control_chars
, pred_ptr
->args
.stream
);
529 pred_fprint (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
534 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
535 pred_ptr
->args
.printf_vec
.quote_opts
,
536 pred_ptr
->args
.printf_vec
.dest_is_tty
,
543 pred_fprint0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
548 fputs (pathname
, pred_ptr
->args
.stream
);
549 putc (0, pred_ptr
->args
.stream
);
556 mode_to_filetype(mode_t m
)
559 m
== S_IFSOCK
? "s" :
566 m
== S_IFDOOR
? "D" :
568 m
== S_IFIFO
? "p" : "U";
572 file_sparseness(const struct stat
*p
)
576 if (0 == p
->st_blocks
)
579 return p
->st_blocks
< 0 ? -HUGE_VAL
: HUGE_VAL
;
583 double blklen
= file_blocksize(p
) * (double)p
->st_blocks
;
584 return blklen
/ p
->st_size
;
592 struct segment
*segment
,
594 const struct stat
*stat_buf
,
596 const struct quoting_options
*qopts
)
598 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
601 switch (segment
->segkind
)
603 case KIND_PLAIN
: /* Plain text string (no % conversion). */
605 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
608 case KIND_STOP
: /* Terminate argument and flush output. */
610 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
615 switch (segment
->format_char
[0])
617 case 'a': /* atime in `ctime' format. */
618 /* UNTRUSTED, probably unexploitable */
619 fprintf (fp
, segment
->text
, ctime_format (get_stat_atime(stat_buf
)));
621 case 'b': /* size in 512-byte blocks */
622 /* UNTRUSTED, probably unexploitable */
623 fprintf (fp
, segment
->text
,
624 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
626 ST_NBLOCKSIZE
, 512));
628 case 'c': /* ctime in `ctime' format */
629 /* UNTRUSTED, probably unexploitable */
630 fprintf (fp
, segment
->text
, ctime_format (get_stat_ctime(stat_buf
)));
632 case 'd': /* depth in search tree */
633 /* UNTRUSTED, probably unexploitable */
634 fprintf (fp
, segment
->text
, state
.curdepth
);
636 case 'D': /* Device on which file exists (stat.st_dev) */
638 fprintf (fp
, segment
->text
,
639 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
640 human_ceiling
, 1, 1));
642 case 'f': /* base name of path */
644 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, base_name (pathname
));
646 case 'F': /* filesystem type */
648 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, filesystem_type (stat_buf
, pathname
));
650 case 'g': /* group name */
652 /* (well, the actual group is selected by the user but
653 * its name was selected by the system administrator)
658 g
= getgrgid (stat_buf
->st_gid
);
661 segment
->text
[segment
->text_len
] = 's';
662 fprintf (fp
, segment
->text
, g
->gr_name
);
671 case 'G': /* GID number */
672 /* UNTRUSTED, probably unexploitable */
673 fprintf (fp
, segment
->text
,
674 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
675 human_ceiling
, 1, 1));
677 case 'h': /* leading directories part of path */
682 cp
= strrchr (pathname
, '/');
683 if (cp
== NULL
) /* No leading directories. */
685 /* If there is no slash in the pathname, we still
686 * print the string because it contains characters
687 * other than just '%s'. The %h expands to ".".
689 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, ".");
695 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, pathname
);
700 case 'H': /* ARGV element file was found under */
703 char cc
= pathname
[state
.starting_path_length
];
705 pathname
[state
.starting_path_length
] = '\0';
706 fprintf (fp
, segment
->text
, pathname
);
707 pathname
[state
.starting_path_length
] = cc
;
710 case 'i': /* inode number */
711 /* UNTRUSTED, but not exploitable I think */
712 fprintf (fp
, segment
->text
,
713 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
717 case 'k': /* size in 1K blocks */
718 /* UNTRUSTED, but not exploitable I think */
719 fprintf (fp
, segment
->text
,
720 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
722 ST_NBLOCKSIZE
, 1024));
724 case 'l': /* object of symlink */
730 if (S_ISLNK (stat_buf
->st_mode
))
732 linkname
= get_link_name (pathname
, state
.rel_pathname
);
734 state
.exit_status
= 1;
738 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, linkname
);
742 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, "");
747 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
748 /* UNTRUSTED, probably unexploitable */
750 char modestring
[16] ;
751 filemodestring (stat_buf
, modestring
);
752 modestring
[10] = '\0';
753 fprintf (fp
, segment
->text
, modestring
);
757 case 'm': /* mode as octal number (perms only) */
758 /* UNTRUSTED, probably unexploitable */
760 /* Output the mode portably using the traditional numbers,
761 even if the host unwisely uses some other numbering
762 scheme. But help the compiler in the common case where
763 the host uses the traditional numbering scheme. */
764 mode_t m
= stat_buf
->st_mode
;
765 boolean traditional_numbering_scheme
=
766 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
767 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
768 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
769 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
770 fprintf (fp
, segment
->text
,
771 (traditional_numbering_scheme
773 : ((m
& S_ISUID
? 04000 : 0)
774 | (m
& S_ISGID
? 02000 : 0)
775 | (m
& S_ISVTX
? 01000 : 0)
776 | (m
& S_IRUSR
? 00400 : 0)
777 | (m
& S_IWUSR
? 00200 : 0)
778 | (m
& S_IXUSR
? 00100 : 0)
779 | (m
& S_IRGRP
? 00040 : 0)
780 | (m
& S_IWGRP
? 00020 : 0)
781 | (m
& S_IXGRP
? 00010 : 0)
782 | (m
& S_IROTH
? 00004 : 0)
783 | (m
& S_IWOTH
? 00002 : 0)
784 | (m
& S_IXOTH
? 00001 : 0))));
788 case 'n': /* number of links */
789 /* UNTRUSTED, probably unexploitable */
790 fprintf (fp
, segment
->text
,
791 human_readable ((uintmax_t) stat_buf
->st_nlink
,
796 case 'p': /* pathname */
798 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, pathname
);
800 case 'P': /* pathname with ARGV element stripped */
802 if (state
.curdepth
> 0)
804 cp
= pathname
+ state
.starting_path_length
;
806 /* Move past the slash between the ARGV element
807 and the rest of the pathname. But if the ARGV element
808 ends in a slash, we didn't add another, so we've
809 already skipped past it. */
814 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, cp
);
816 case 's': /* size in bytes */
817 /* UNTRUSTED, probably unexploitable */
818 fprintf (fp
, segment
->text
,
819 human_readable ((uintmax_t) stat_buf
->st_size
,
820 hbuf
, human_ceiling
, 1, 1));
823 case 'S': /* sparseness */
824 /* UNTRUSTED, probably unexploitable */
825 fprintf (fp
, segment
->text
, file_sparseness(stat_buf
));;
828 case 't': /* mtime in `ctime' format */
829 /* UNTRUSTED, probably unexploitable */
830 fprintf (fp
, segment
->text
, ctime_format (get_stat_mtime(stat_buf
)));
833 case 'u': /* user name */
835 /* (well, the actual user is selected by the user on systems
836 * where chown is not restricted, but the user name was
837 * selected by the system administrator)
842 p
= getpwuid (stat_buf
->st_uid
);
845 segment
->text
[segment
->text_len
] = 's';
846 fprintf (fp
, segment
->text
, p
->pw_name
);
852 case 'U': /* UID number */
853 /* UNTRUSTED, probably unexploitable */
854 fprintf (fp
, segment
->text
,
855 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
856 human_ceiling
, 1, 1));
859 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
860 case 'Y': /* in case of symlink */
864 if (S_ISLNK (stat_buf
->st_mode
))
867 /* If we would normally follow links, do not do so.
868 * If we would normally not follow links, do so.
870 if ((following_links() ? lstat
: stat
)
871 (state
.rel_pathname
, &sbuf
) != 0)
873 if ( errno
== ENOENT
) {
874 fprintf (fp
, segment
->text
, "N");
877 if ( errno
== ELOOP
) {
878 fprintf (fp
, segment
->text
, "L");
881 error (0, errno
, "%s", pathname
);
885 fprintf (fp
, segment
->text
,
886 mode_to_filetype(sbuf
.st_mode
& S_IFMT
));
891 fprintf (fp
, segment
->text
,
892 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
900 fprintf (fp
, segment
->text
,
901 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
907 #warning this function needs a return statement. See Savannah bug#19146.
911 pred_fprintf (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
913 FILE *fp
= pred_ptr
->args
.printf_vec
.stream
;
914 struct segment
*segment
;
915 boolean ttyflag
= pred_ptr
->args
.printf_vec
.dest_is_tty
;
916 const struct quoting_options
*qopts
= pred_ptr
->args
.printf_vec
.quote_opts
;
918 for (segment
= pred_ptr
->args
.printf_vec
.segment
; segment
;
919 segment
= segment
->next
)
921 if ( (KIND_FORMAT
== segment
->segkind
) && segment
->format_char
[1]) /* Component of date. */
925 switch (segment
->format_char
[0])
928 ts
= get_stat_atime(stat_buf
);
931 ts
= get_stat_ctime(stat_buf
);
934 ts
= get_stat_mtime(stat_buf
);
940 /* We trust the output of format_date not to contain
941 * nasty characters, though the value of the date
942 * is itself untrusted data.
945 fprintf (fp
, segment
->text
,
946 format_date (ts
, segment
->format_char
[1]));
950 do_fprintf(fp
, segment
, pathname
, stat_buf
, ttyflag
, qopts
);
957 pred_fstype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
961 if (strcmp (filesystem_type (stat_buf
, pathname
), pred_ptr
->args
.str
) == 0)
968 pred_gid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
972 switch (pred_ptr
->args
.numinfo
.kind
)
975 if (stat_buf
->st_gid
> pred_ptr
->args
.numinfo
.l_val
)
979 if (stat_buf
->st_gid
< pred_ptr
->args
.numinfo
.l_val
)
983 if (stat_buf
->st_gid
== pred_ptr
->args
.numinfo
.l_val
)
991 pred_group (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
995 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
1002 pred_ilname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1004 return match_lname (pathname
, stat_buf
, pred_ptr
, true);
1008 pred_iname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1014 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1015 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1017 base
= base_name (pathname
);
1018 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
1024 pred_inum (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1028 switch (pred_ptr
->args
.numinfo
.kind
)
1031 if (stat_buf
->st_ino
> pred_ptr
->args
.numinfo
.l_val
)
1035 if (stat_buf
->st_ino
< pred_ptr
->args
.numinfo
.l_val
)
1039 if (stat_buf
->st_ino
== pred_ptr
->args
.numinfo
.l_val
)
1047 pred_ipath (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1051 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
1057 pred_links (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1061 switch (pred_ptr
->args
.numinfo
.kind
)
1064 if (stat_buf
->st_nlink
> pred_ptr
->args
.numinfo
.l_val
)
1068 if (stat_buf
->st_nlink
< pred_ptr
->args
.numinfo
.l_val
)
1072 if (stat_buf
->st_nlink
== pred_ptr
->args
.numinfo
.l_val
)
1080 pred_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1082 return match_lname (pathname
, stat_buf
, pred_ptr
, false);
1086 match_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
1088 boolean ret
= false;
1090 if (S_ISLNK (stat_buf
->st_mode
))
1092 char *linkname
= get_link_name (pathname
, state
.rel_pathname
);
1095 if (fnmatch (pred_ptr
->args
.str
, linkname
,
1096 ignore_case
? FNM_CASEFOLD
: 0) == 0)
1101 #endif /* S_ISLNK */
1106 pred_ls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1108 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
,
1109 options
.output_block_size
,
1110 pred_ptr
->literal_control_chars
,
1116 pred_mmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1119 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, 60);
1123 pred_mtime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1126 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, DAYSECS
);
1130 pred_name (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1135 base
= base_name (pathname
);
1137 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1138 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1140 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1146 pred_negate (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1148 /* Check whether we need a stat here. */
1149 /* TODO: what about need_type? */
1150 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1152 return (!(*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1153 pred_ptr
->pred_right
));
1157 pred_newer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1161 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1162 return compare_ts(get_stat_mtime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
1166 pred_nogroup (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1172 extern char *gid_unused
;
1174 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1176 return getgrgid (stat_buf
->st_gid
) == NULL
;
1181 pred_nouser (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1184 extern char *uid_unused
;
1191 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1193 return getpwuid (stat_buf
->st_uid
) == NULL
;
1199 is_ok(const char *program
, const char *arg
)
1202 /* The draft open standard requires that, in the POSIX locale,
1203 the last non-blank character of this prompt be '?'.
1204 The exact format is not specified.
1205 This standard does not have requirements for locales other than POSIX
1207 /* XXX: printing UNTRUSTED data here. */
1208 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1214 pred_ok (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1216 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1217 return new_impl_pred_exec (pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1223 pred_okdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1225 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
1226 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1227 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
1228 prefix
, (prefix
? 2 : 0));
1234 pred_open (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1243 pred_or (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1245 if (pred_ptr
->pred_left
== NULL
1246 || !(*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
1247 pred_ptr
->pred_left
))
1249 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1251 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1252 pred_ptr
->pred_right
));
1259 pred_path (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1262 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1268 pred_perm (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1270 mode_t mode
= stat_buf
->st_mode
;
1271 mode_t perm_val
= pred_ptr
->args
.perm
.val
[S_ISDIR (mode
) != 0];
1273 switch (pred_ptr
->args
.perm
.kind
)
1276 return (mode
& perm_val
) == perm_val
;
1280 /* True if any of the bits set in the mask are also set in the file's mode.
1283 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1284 * evaluate as true if at least all of the bits specified in
1285 * onum that are also set in the octal mask 07777 are set.
1287 * Eric Blake's interpretation is that the mode argument is zero,
1291 return true; /* Savannah bug 14748; we used to return false */
1293 return (mode
& perm_val
) != 0;
1297 return (mode
& MODE_ALL
) == perm_val
;
1308 pred_executable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1314 return 0 == access(state
.rel_pathname
, X_OK
);
1318 pred_readable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1324 return 0 == access(state
.rel_pathname
, R_OK
);
1328 pred_writable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1334 return 0 == access(state
.rel_pathname
, W_OK
);
1338 pred_print (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1342 /* puts (pathname); */
1343 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
1344 pred_ptr
->args
.printf_vec
.quote_opts
,
1345 pred_ptr
->args
.printf_vec
.dest_is_tty
,
1351 pred_print0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1355 fputs (pathname
, stdout
);
1361 pred_prune (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1366 if (options
.do_dir_first
== true &&
1368 S_ISDIR(stat_buf
->st_mode
))
1369 state
.stop_at_current_level
= true;
1371 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1375 pred_quit (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1381 /* Run any cleanups. This includes executing any command lines
1382 * we have partly built but not executed.
1386 /* Since -exec and friends don't leave child processes running in the
1387 * background, there is no need to wait for them here.
1389 exit(state
.exit_status
); /* 0 for success, etc. */
1393 pred_regex (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1395 int len
= strlen (pathname
);
1397 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1398 (struct re_registers
*) NULL
) == len
)
1404 pred_size (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1409 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1410 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1411 switch (pred_ptr
->args
.size
.kind
)
1414 if (f_val
> pred_ptr
->args
.size
.size
)
1418 if (f_val
< pred_ptr
->args
.size
.size
)
1422 if (f_val
== pred_ptr
->args
.size
.size
)
1430 pred_samefile (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1432 /* Potential optimisation: because of the loop protection, we always
1433 * know the device of the current directory, hence the device number
1434 * of the file we're currently considering. If -L is not in effect,
1435 * and the device number of the file we're looking for is not the
1436 * same as the device number of the current directory, this
1437 * predicate cannot return true. Hence there would be no need to
1438 * stat the file we're looking at.
1442 return stat_buf
->st_ino
== pred_ptr
->args
.fileid
.ino
1443 && stat_buf
->st_dev
== pred_ptr
->args
.fileid
.dev
;
1447 pred_true (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1456 pred_type (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1459 mode_t type
= pred_ptr
->args
.type
;
1461 assert(state
.have_type
);
1462 assert(state
.type
!= 0);
1466 if (state
.have_stat
)
1467 mode
= stat_buf
->st_mode
;
1472 /* POSIX system; check `mode' the slow way. */
1473 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1474 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1475 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1476 || (S_ISREG (mode
) && type
== S_IFREG
)
1478 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1481 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1484 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1487 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1491 /* Unix system; check `mode' the fast way. */
1492 if ((mode
& S_IFMT
) == type
)
1500 pred_uid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1503 switch (pred_ptr
->args
.numinfo
.kind
)
1506 if (stat_buf
->st_uid
> pred_ptr
->args
.numinfo
.l_val
)
1510 if (stat_buf
->st_uid
< pred_ptr
->args
.numinfo
.l_val
)
1514 if (stat_buf
->st_uid
== pred_ptr
->args
.numinfo
.l_val
)
1522 pred_used (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1524 struct timespec delta
, at
, ct
;
1528 /* TODO: this needs to be retested carefully (manually, if necessary) */
1529 at
= get_stat_atime(stat_buf
);
1530 ct
= get_stat_ctime(stat_buf
);
1531 delta
.tv_sec
= at
.tv_sec
- ct
.tv_sec
;
1532 delta
.tv_nsec
= at
.tv_nsec
- ct
.tv_nsec
;
1533 if (delta
.tv_nsec
< 0)
1535 delta
.tv_nsec
+= 1000000000;
1538 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1542 pred_user (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1545 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1552 pred_xtype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1554 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1555 int (*ystat
) (const char*, struct stat
*p
);
1557 /* If we would normally stat the link itself, stat the target instead.
1558 * If we would normally follow the link, stat the link itself instead.
1560 if (following_links())
1561 ystat
= optionp_stat
;
1563 ystat
= optionl_stat
;
1565 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1567 if (following_links() && errno
== ENOENT
)
1569 /* If we failed to follow the symlink,
1570 * fall back on looking at the symlink itself.
1572 /* Mimic behavior of ls -lL. */
1573 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1577 error (0, errno
, "%s", pathname
);
1578 state
.exit_status
= 1;
1582 /* Now that we have our stat() information, query it in the same
1583 * way that -type does.
1585 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1588 /* 1) fork to get a child; parent remembers the child pid
1589 2) child execs the command requested
1590 3) parent waits for child; checks for proper pid of child
1594 ret errno status(h) status(l)
1596 pid x signal# 0177 stopped
1597 pid x exit arg 0 term by _exit
1598 pid x 0 signal # term by signal
1599 -1 EINTR parent got signal
1600 -1 other some other kind of error
1602 Return true only if the pid matches, status(l) is
1603 zero, and the exit arg (status high) is 0.
1604 Otherwise return false, possibly printing an error message. */
1608 prep_child_for_exec (boolean close_stdin
)
1612 const char inputfile
[] = "/dev/null";
1613 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1616 if (open(inputfile
, O_RDONLY
) < 0)
1618 /* This is not entirely fatal, since
1619 * executing the child with a closed
1620 * stdin is almost as good as executing it
1621 * with its stdin attached to /dev/null.
1623 error (0, errno
, "%s", inputfile
);
1631 launch (const struct buildcmd_control
*ctl
,
1632 struct buildcmd_state
*buildstate
)
1636 static int first_time
= 1;
1637 const struct exec_val
*execp
= buildstate
->usercontext
;
1639 /* Null terminate the arg list. */
1640 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1642 /* Make sure output of command doesn't get mixed with find output. */
1646 /* Make sure to listen for the kids. */
1650 signal (SIGCHLD
, SIG_DFL
);
1653 child_pid
= fork ();
1654 if (child_pid
== -1)
1655 error (1, errno
, _("cannot fork"));
1658 /* We be the child. */
1659 prep_child_for_exec(execp
->close_stdin
);
1661 /* For -exec and -ok, change directory back to the starting directory.
1662 * for -execdir and -okdir, stay in the directory we are searching
1663 * (the latter is more secure).
1665 if (!execp
->use_current_dir
)
1667 /* Even if DebugSearch is set, don't announce our change of
1668 * directory, since we're not going to emit a subsequent
1669 * announcement of a call to stat() anyway, as we're about
1670 * to exec something.
1672 if (starting_desc
< 0
1673 ? chdir (starting_dir
) != 0
1674 : fchdir (starting_desc
) != 0)
1676 error (0, errno
, "%s", starting_dir
);
1681 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1682 error (0, errno
, "%s", buildstate
->cmd_argv
[0]);
1687 /* In parent; set up for next time. */
1688 bc_clear_args(ctl
, buildstate
);
1691 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1695 error (0, errno
, _("error waiting for %s"), buildstate
->cmd_argv
[0]);
1696 state
.exit_status
= 1;
1697 return 0; /* FAIL */
1701 if (WIFSIGNALED (wait_status
))
1703 error (0, 0, _("%s terminated by signal %d"),
1704 buildstate
->cmd_argv
[0], WTERMSIG (wait_status
));
1706 if (execp
->multiple
)
1708 /* -exec \; just returns false if the invoked command fails.
1709 * -exec {} + returns true if the invoked command fails, but
1710 * sets the program exit status.
1712 state
.exit_status
= 1;
1718 if (0 == WEXITSTATUS (wait_status
))
1724 if (execp
->multiple
)
1726 /* -exec \; just returns false if the invoked command fails.
1727 * -exec {} + returns true if the invoked command fails, but
1728 * sets the program exit status.
1730 state
.exit_status
= 1;
1732 return 0; /* FAIL */
1738 /* Return a static string formatting the time WHEN according to the
1739 * strftime format character KIND.
1741 * This function contains a number of assertions. These look like
1742 * runtime checks of the results of computations, which would be a
1743 * problem since external events should not be tested for with
1744 * "assert" (instead you should use "if"). However, they are not
1745 * really runtime checks. The assertions actually exist to verify
1746 * that the various buffers are correctly sized.
1749 format_date (struct timespec ts
, int kind
)
1751 /* Use an extra 10 characters for 9 digits of nanoseconds and 1 for
1756 DATE_LEN_PERCENT_APLUS
=21 /* length of result of %A+ (it's longer than %c)*/
1758 static char buf
[10u + MAX(DATE_LEN_PERCENT_APLUS
, MAX (LONGEST_HUMAN_READABLE
+ 2, 64))];
1759 char ns_buf
[NS_BUF_LEN
]; /* .9999999990 */
1760 int charsprinted
, need_ns_suffix
;
1764 /* human_readable() assumes we pass a buffer which is at least as
1765 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
1766 * ensure that no nasty unsigned overflow happend in our calculation
1767 * of the size of buf. Do the assertion here rather than in the
1768 * code for %@ so that we find the problem quickly if it exists. If
1769 * you want to submit a patch to move this into the if statement, go
1770 * ahead, I'll apply it. But include performance timings
1771 * demonstrating that the performance difference is actually
1774 assert(sizeof(buf
) >= LONGEST_HUMAN_READABLE
);
1776 /* Format the main part of the time. */
1779 strcpy (fmt
, "%F+%T");
1788 /* %a, %c, and %t are handled in ctime_format() */
1804 /* Format the nanoseconds part. Leave a trailing zero to discourage people from
1805 * writing scripts which extract the fractional part of the timestamp by using
1806 * column offsets. The reason for discouraging this is that in the future, the
1807 * granularity may not be nanoseconds.
1809 charsprinted
= snprintf(ns_buf
, NS_BUF_LEN
, ".%09ld0", (long int)ts
.tv_nsec
);
1810 assert(charsprinted
< NS_BUF_LEN
);
1814 && (tm
= localtime (&ts
.tv_sec
))
1815 && strftime (buf
, sizeof buf
, fmt
, tm
))
1817 /* For %AS, %CS, %TS, add the fractional part of the seconds information. */
1820 assert((sizeof buf
- strlen(buf
)) > strlen(ns_buf
));
1821 strcat(buf
, ns_buf
);
1827 uintmax_t w
= ts
.tv_sec
;
1828 size_t used
, len
, remaining
;
1830 /* XXX: note that we are negating an unsigned type which is the
1831 * widest possible unsigned type.
1833 char *p
= human_readable (ts
.tv_sec
< 0 ? -w
: w
, buf
+ 1,
1834 human_ceiling
, 1, 1);
1836 assert(p
< (buf
+ (sizeof buf
)));
1838 *--p
= '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
1840 /* Add the nanoseconds part. Because we cannot enforce a particlar implementation
1841 * of human_readable, we cannot assume any particular value for (p-buf). So we
1842 * need to be careful that there is enough space remaining in the buffer.
1845 used
= (p
-buf
) + len
; /* Offset into buf of current end */
1846 assert(sizeof buf
> used
); /* Ensure we can perform subtraction safely. */
1847 remaining
= sizeof buf
- used
- 1u; /* allow space for NUL */
1848 assert(strlen(ns_buf
) < remaining
);
1854 static const char *weekdays
[] =
1856 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1858 static char * months
[] =
1860 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1861 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1866 ctime_format (struct timespec ts
)
1868 const struct tm
* ptm
;
1869 #define TIME_BUF_LEN 1024u
1870 static char resultbuf
[TIME_BUF_LEN
];
1873 ptm
= localtime(&ts
.tv_sec
);
1876 assert(ptm
->tm_wday
>= 0);
1877 assert(ptm
->tm_wday
< 7);
1878 assert(ptm
->tm_mon
>= 0);
1879 assert(ptm
->tm_mon
< 12);
1880 assert(ptm
->tm_hour
>= 0);
1881 assert(ptm
->tm_hour
< 24);
1882 assert(ptm
->tm_min
< 60);
1883 assert(ptm
->tm_sec
<= 61); /* allows 2 leap seconds. */
1885 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
1886 nout
= snprintf(resultbuf
, TIME_BUF_LEN
,
1887 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
1888 weekdays
[ptm
->tm_wday
],
1889 months
[ptm
->tm_mon
],
1894 (long int)ts
.tv_nsec
,
1895 1900 + ptm
->tm_year
);
1897 assert(nout
< TIME_BUF_LEN
);
1902 /* The time cannot be represented as a struct tm.
1903 Output it as an integer. */
1904 return format_date (ts
, '@');
1908 /* Copy STR into BUF and trim blanks from the end of BUF.
1912 blank_rtrim (str
, buf
)
1921 i
= strlen (buf
) - 1;
1922 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
1928 /* Print out the predicate list starting at NODE. */
1930 print_list (FILE *fp
, struct predicate
*node
)
1932 struct predicate
*cur
;
1938 fprintf (fp
, "%s ", blank_rtrim (cur
->p_name
, name
));
1939 cur
= cur
->pred_next
;
1944 /* Print out the predicate list starting at NODE. */
1946 print_parenthesised(FILE *fp
, struct predicate
*node
)
1952 if ( ( (node
->pred_func
== pred_or
)
1953 || (node
->pred_func
== pred_and
) )
1954 && node
->pred_left
== NULL
)
1956 /* We print "<nothing> or X" as just "X"
1957 * We print "<nothing> and X" as just "X"
1959 print_parenthesised(fp
, node
->pred_right
);
1963 if (node
->pred_left
|| node
->pred_right
)
1967 fprintf(fp
, "%s", " ( ");
1968 print_optlist(fp
, node
);
1970 fprintf(fp
, "%s", " ) ");
1976 print_optlist (FILE *fp
, const struct predicate
*p
)
1980 print_parenthesised(fp
, p
->pred_left
);
1983 p
->need_stat
? "[call stat] " : "",
1984 p
->need_type
? "[need type] " : "");
1985 print_predicate(fp
, p
);
1986 fprintf(fp
, " [%g] ", p
->est_success_rate
);
1987 print_parenthesised(fp
, p
->pred_right
);
1992 /* If _NDEBUG is defined, the assertions will do nothing. Hence
1993 * there is no point in having a function body for pred_sanity_check()
1994 * if that preprocessor macro is defined.
1997 pred_sanity_check(const struct predicate
*predicates
)
1999 /* Do nothing, since assert() is a no-op with _NDEBUG set */
2004 pred_sanity_check(const struct predicate
*predicates
)
2006 const struct predicate
*p
;
2008 for (p
=predicates
; p
!= NULL
; p
=p
->pred_next
)
2010 /* All predicates must do something. */
2011 assert(p
->pred_func
!= NULL
);
2013 /* All predicates must have a parser table entry. */
2014 assert(p
->parser_entry
!= NULL
);
2016 /* If the parser table tells us that just one predicate function is
2017 * possible, verify that that is still the one that is in effect.
2018 * If the parser has NULL for the predicate function, that means that
2019 * the parse_xxx function fills it in, so we can't check it.
2021 if (p
->parser_entry
->pred_func
)
2023 assert(p
->parser_entry
->pred_func
== p
->pred_func
);
2026 switch (p
->parser_entry
->type
)
2028 /* Options all take effect during parsing, so there should
2029 * be no predicate entries corresponding to them. Hence we
2030 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2033 * This is a silly way of coding this test, but it prevents
2034 * a compiler warning (i.e. otherwise it would think that
2035 * there would be case statements missing).
2038 case ARG_POSITIONAL_OPTION
:
2039 assert(p
->parser_entry
->type
!= ARG_OPTION
);
2040 assert(p
->parser_entry
->type
!= ARG_POSITIONAL_OPTION
);
2044 assert(p
->side_effects
); /* actions have side effects. */
2045 if (p
->pred_func
!= pred_prune
&& p
->pred_func
!= pred_quit
)
2047 /* actions other than -prune and -quit should
2048 * inhibit the default -print
2050 assert(p
->no_default_print
);
2054 case ARG_PUNCTUATION
:
2057 /* Punctuation and tests should have no side
2058 * effects and not inhibit default print.
2060 assert(!p
->no_default_print
);
2061 assert(!p
->side_effects
);